用于显示建议的 ComboBox 的问题

发布于 2024-10-18 20:20:26 字数 2997 浏览 1 评论 0原文

我正在尝试实现像 Google 一样的建议 ComboBox:

用户输入几个符号,然后会出现一个包含建议的列表。 所以我有以下代码:

 <!--Search query textBox-->
    <ComboBox x:Name="txtMain" IsEditable="True"                                         TextBoxBase.SelectionChanged="txtMain_SelectionChanged"
    TextBoxBase.TextChanged=" txtMain_TextChanged"
    KeyDown="txtMain_PreviewKeyDown"
    SelectionChanged=" txtMain_SelectionChanged"                                              IsTextSearchEnabled="False" />

   public SearchControl()
    {
        InitializeComponent();

        _search = new SearchViewModel(doc);

        _suggestionCom = new SuggestionsCommand(
            (object s, RunWorkerCompletedEventArgs evarg) =>
            {
                List<string> results = _suggestionCom.Suggestions;

                if (results != null && results.Count() > 0)
                {
                    txtMain.ItemsSource = results;
                }
                else
                {
                    txtMain.ItemsSource = null;
                }
                txtMain.IsDropDownOpen = true;
            });
    }
   void autoTextBox_TextChanged(object sender, TextChangedEventArgs e)
    {
        try
        {
            if (_prevText.Equals(txtMain.Text))
                return;
            // Only autocomplete when there is text
            if (txtMain.Text.Length > 0)
            {
                string lastInput = txtMain.Text;
                _prevText = lastInput;
                _suggestionCom.Execute(lastInput); //it starts a new thread which download suggestions from the service
            }
            else
            {
                txtMain.ItemsSource = null;
            }
        }
        catch (Exception err)
        {
        }
    }

    void txtMain_PreviewKeyDown(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.Down)
        {
            if (txtMain.SelectedIndex < txtMain.Items.Count)
            {
                txtMain.SelectedIndex = txtMain.SelectedIndex + 1;
            }
        }
        if (e.Key == Key.Up)
        {
            if (txtMain.SelectedIndex > -1)
            {
                txtMain.SelectedIndex = txtMain.SelectedIndex - 1;
            }
        }
        if (e.Key == Key.Enter)
        {
            // Commit the selection
            //txtMain.Visibility = Visibility.Collapsed;
            e.Handled = (e.Key == Key.Enter);
            //Perform search here
        }

        if (e.Key == Key.Escape)
        {
            // Cancel the selection
            txtMain.ItemsSource = null;
            //suggestionListBox.Visibility = Visibility.Collapsed;
        }
    }

下载建议后,将调用构造函数中描述的 Lambda。 我对这段代码有以下问题。首先,我无法处理 Key.Down (按下时不会调用 txtMain_PreviewKeyDown)。因此,为了从列表中选择建议,用户需要使用鼠标。其次,当找到一些建议并且列表已被删除时,组合框中的文本被选中(蓝色),这不是我想要的(我不想在选择建议时选择文本):

I’m trying to implement suggestions ComboBox like Google’s one:

User enters several symbols and a list with suggestions appears.
So I have the following code:

 <!--Search query textBox-->
    <ComboBox x:Name="txtMain" IsEditable="True"                                         TextBoxBase.SelectionChanged="txtMain_SelectionChanged"
    TextBoxBase.TextChanged=" txtMain_TextChanged"
    KeyDown="txtMain_PreviewKeyDown"
    SelectionChanged=" txtMain_SelectionChanged"                                              IsTextSearchEnabled="False" />

   public SearchControl()
    {
        InitializeComponent();

        _search = new SearchViewModel(doc);

        _suggestionCom = new SuggestionsCommand(
            (object s, RunWorkerCompletedEventArgs evarg) =>
            {
                List<string> results = _suggestionCom.Suggestions;

                if (results != null && results.Count() > 0)
                {
                    txtMain.ItemsSource = results;
                }
                else
                {
                    txtMain.ItemsSource = null;
                }
                txtMain.IsDropDownOpen = true;
            });
    }
   void autoTextBox_TextChanged(object sender, TextChangedEventArgs e)
    {
        try
        {
            if (_prevText.Equals(txtMain.Text))
                return;
            // Only autocomplete when there is text
            if (txtMain.Text.Length > 0)
            {
                string lastInput = txtMain.Text;
                _prevText = lastInput;
                _suggestionCom.Execute(lastInput); //it starts a new thread which download suggestions from the service
            }
            else
            {
                txtMain.ItemsSource = null;
            }
        }
        catch (Exception err)
        {
        }
    }

    void txtMain_PreviewKeyDown(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.Down)
        {
            if (txtMain.SelectedIndex < txtMain.Items.Count)
            {
                txtMain.SelectedIndex = txtMain.SelectedIndex + 1;
            }
        }
        if (e.Key == Key.Up)
        {
            if (txtMain.SelectedIndex > -1)
            {
                txtMain.SelectedIndex = txtMain.SelectedIndex - 1;
            }
        }
        if (e.Key == Key.Enter)
        {
            // Commit the selection
            //txtMain.Visibility = Visibility.Collapsed;
            e.Handled = (e.Key == Key.Enter);
            //Perform search here
        }

        if (e.Key == Key.Escape)
        {
            // Cancel the selection
            txtMain.ItemsSource = null;
            //suggestionListBox.Visibility = Visibility.Collapsed;
        }
    }

Lambda described in the constructor is called when suggestions have been downloaded.
I have the following problems with this code. First, I can’t handle Key.Down (txtMain_PreviewKeyDown is not called when it is pressed). So in order to choose suggestion from a list user need to use mouse. Second, when some suggestions have been found and list has been dropped the text in ComboBox becomes selected (blue) which is not what I want(I don't want to have the text beeing selected when suggestion have been chosen):

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

比忠 2024-10-25 20:20:26

AutoCompleteBox 是更适合处理此类行为。

The AutoCompleteBox is better suited to handle this sort of behaviour.

半仙 2024-10-25 20:20:26

其一,在这种情况下,您应该在 xaml 中使用“PreviewKeyDown”而不是“KeyDown”,因为您需要隧道事件。然后,您可能必须重写“焦点”方法才能删除文本上的选择。

但就我而言,我会选择附加属性,如另一个问题的答案中所述:

这是将 AutoSuggest 构建到 WPF 组合框的最佳方式吗?

您可能还想使用 autoComplete TextBox比组合框:

http://www.codeproject.com/KB/WPF/WPFAutoCompleteTextbox.aspx

http: //www.lazarciuc.ro/ioan/2008/06/01/auto-complete-for-textboxes-in-wpf/

(我不喜欢重新发明轮子;-))

for one, you should use "PreviewKeyDown" instead of "KeyDown" in you xaml in this case, as you want a tunnelling event. then, you will probably have to override the "focus" method in order to remove the selection on the text.

but as far as I'm concerned, I'd go for an attached property, as described in this other question's answer:

Is this the best way to build AutoSuggest into a WPF ComboBox?

you might also want to go for the autoComplete TextBox rather than comboBox:

http://www.codeproject.com/KB/WPF/WPFAutoCompleteTextbox.aspx

and

http://www.lazarciuc.ro/ioan/2008/06/01/auto-complete-for-textboxes-in-wpf/

(I don't like to reinvent the wheel ;-) )

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文