为什么此递归搜索返回不相关的结果?

时间:2018-08-07 18:52:50

标签: c# wpf recursion search

我有一个WPF TreeView,其中装有许多子控件。他们所有有孩子的人都是TreeViewItems,所有没有孩子的人都是Checkboxes。目前,它有大约1,600个Checkbox儿童和亚儿童。我还有一个Textbox,它用于通过匹配checkboxes Tags中的数据来搜索树。

当在TreeView中键入键时,以下代码过滤Textbox。如果Textbox为空时触发了此事件,则运行另一种算法,该算法将显示所有子代并将TreeViewItems的子代折叠起来。

我的问题包括两个部分,为什么filter方法不能正常工作?令人不满意的是搜索结果。

其次,我如何优化搜索功能?它目前将我的UI线程锁定了几秒钟,而ShowAndCollapse算法似乎没有锁定。

// 'MainTree' is my TreeView being searched through

private void SearchTermTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
    TextBox textBox = (TextBox)sender;

    if (textBox.Text.Length == 0)
    {
        ShowAndCollapse(MainTree);
    }
    else
    {
        Filter(MainTree, textBox.Text);
    }
}

private void ShowAndCollapse(ItemsControl parent)
{
    foreach (Control control in parent.Items)
    {
        control.Visibility = Visibility.Visible;

        if (control is TreeViewItem treeViewItem)
        {
            ShowAndCollapse(treeViewItem);

            treeViewItem.IsExpanded = false;
        }
    }
}

private void Filter(ItemsControl parent, string searchTerm)
{
    foreach (Control child in parent.Items)
    {
        if (child is TreeViewItem treeViewItem)
        {
            Filter(treeViewItem, searchTerm);

            if (IsEmpty(treeViewItem))
            {
                treeViewItem.IsExpanded = false;
                treeViewItem.Visibility = Visibility.Collapsed;
            }
            else
            {
                treeViewItem.IsExpanded = true;
                treeViewItem.Visibility = Visibility.Visible;
            }
        }
        else if (child is CheckBox checkBox)
        {
            foreach (string term in searchTerm.ToLower().Split(' '))
            {
                if (!checkBox.Tag.ToString().ToLower().Contains(term))
                {
                    checkBox.Visibility = Visibility.Collapsed;
                    return;
                }
            }
            checkBox.Visibility = Visibility.Visible;
        }
        else
            throw new Exception("Unexpected child type!");
    }
}

private bool IsEmpty(TreeViewItem treeViewItem)
{
    foreach (Control item in treeViewItem.Items)
    {
        if (item.Visibility == Visibility.Visible)
        {
            return false;
        }
    }
    return true;
}

谢谢!

1 个答案:

答案 0 :(得分:1)

  1. 我认为方法return中的Filter语句可能是问题,可能的解决方法是在break中使用if statement并移动{{ 1}}上方的for循环。

  2. 要优化此方法,请考虑使用checkbox.Visibility = Visibility.Visible-async或按照Abion47的建议进行操作,然后对基础数据源进行过滤和排序。