按Enter键不会使用自动完成文本框执行命令

时间:2013-11-07 03:30:45

标签: c# wpf combobox

我有一个像这样的自动完成文本框:

public class AutoCompleteTextBox:ComboBox
{
    public AutoCompleteTextBox()
    {
        ResourceDictionary rd = new ResourceDictionary();
        rd.Source = new Uri("/"+this.GetType().Assembly.GetName().Name+";component/Styles/MainViewStyle.xaml",UriKind.Relative);
        this.Resources = rd;
        this.IsTextSearchEnabled = false;
    }

    /// <summary>
    /// Override OnApplyTemplate method 
    /// Get TextBox control out of Combobox control, and hook up TextChanged event.
    /// </summary>
    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        //get the textbox control in the ComboBox control
        TextBox textBox = this.Template.FindName("PART_EditableTextBox", this) as TextBox;
        if (textBox != null)
        {
            //disable Autoword selection of the TextBox
            textBox.AutoWordSelection = false;
            //handle TextChanged event to dynamically add Combobox items.
            textBox.TextChanged += new TextChangedEventHandler(textBox_TextChanged);                
        }
    }       


    public ObservableCollection<string> SuggestionList
    {
        get { return (ObservableCollection<string>)GetValue(SuggestionListProperty); }
        set { SetValue(SuggestionListProperty, value); }
    }



    public static readonly DependencyProperty SuggestionListProperty = DependencyProperty.Register("SuggestionList", typeof(ObservableCollection<string>), typeof(AutoCompleteTextBox), new UIPropertyMetadata());


    /// <summary>
    /// main logic to generate auto suggestion list.
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">The <see cref="System.Windows.Controls.TextChangedEventArgs"/> 
    /// instance containing the event data.</param>
    void textBox_TextChanged(object sender, TextChangedEventArgs e)
    {
        TextBox textBox = sender as TextBox;
        textBox.AutoWordSelection = false;
        // if the word in the textbox is selected, then don't change item collection
        if ((textBox.SelectionStart != 0 || textBox.Text.Length == 0))
        {
            this.Items.Clear();
            //add new filtered items according the current TextBox input
            if (!string.IsNullOrEmpty(textBox.Text))
            {
                foreach (string s in this.SuggestionList)
                {
                    if (s.StartsWith(textBox.Text, StringComparison.InvariantCultureIgnoreCase))
                    {

                        string unboldpart = s.Substring(textBox.Text.Length);
                        string boldpart = s.Substring(0, textBox.Text.Length);
                        //construct AutoCompleteEntry and add to the ComboBox
                        AutoCompleteEntry entry = new AutoCompleteEntry(s, boldpart, unboldpart);
                        this.Items.Add(entry);
                    }
                }
            }
        }
        // open or close dropdown of the ComboBox according to whether there are items in the 
        // fitlered result.
        this.IsDropDownOpen = this.HasItems;

        //avoid auto selection
        textBox.Focus();
        textBox.SelectionStart = textBox.Text.Length;

    }
}

/// <summary>
/// Extended ComboBox Item
/// </summary>
public class AutoCompleteEntry : ComboBoxItem
{
    private TextBlock tbEntry;

    //text of the item
    private string text;

    /// <summary>
    /// Contrutor of AutoCompleteEntry class
    /// </summary>
    /// <param name="text">All the Text of the item </param>
    /// <param name="bold">The already entered part of the Text</param>
    /// <param name="unbold">The remained part of the Text</param>
    public AutoCompleteEntry(string text, string bold, string unbold)
    {
        this.text = text;
        tbEntry = new TextBlock();
        //highlight the current input Text
        tbEntry.Inlines.Add(new Run
        {
            Text = bold,
            FontWeight = FontWeights.Bold,
            Foreground = new SolidColorBrush(Colors.RoyalBlue)
        });
        tbEntry.Inlines.Add(new Run { Text = unbold });
        this.Content = tbEntry;
    }

    /// <summary>
    /// Gets the text.
    /// </summary>
    public string Text
    {
        get { return this.text; }
    }
}

我的xaml看起来像这样:

<local:AutoCompleteTextBox SuggestionList="{Binding Suggestions}" 
                                           Text="{Binding Path=Keyword,UpdateSourceTrigger=PropertyChanged}"
                                           x:Name="SearchTextBox"/>

当我按下回车键时,我想执行搜索命令,但如果屏幕上有建议组合框,按回车键只关闭建议组合框,我需要再次按回车键执行命令。有没有办法关闭建议组合框并按一次按Enter键执行命令?

由于

1 个答案:

答案 0 :(得分:0)

您可以在处理DropDownClosed事件时调用搜索。

<local:AutoCompleteTextBox SuggestionList="{Binding Suggestions}" 
                                           Text="{Binding Path=Keyword,UpdateSourceTrigger=PropertyChanged}"
                                           DropDownClosed="OnDropDownClosed"
                                           x:Name="SearchTextBox"/>

OnDropDownClosed:

private void OnDropDownClosedobject sender, RoutedPropertyChangedEventArgs<bool> e)
{
    // search on Keyword
}