Это лучший способ встроить AutoSuggest в ComboBox WPF? - PullRequest
0 голосов
/ 05 октября 2009

У меня есть поле со списком национальностей, подобное приведенному ниже, и я хочу сделать так, чтобы пользователь мог набирать буквы для узких в вариантах. Я мог бы решить эту проблему так, как я начал ниже, добавив logic в методе NationalityComboBox_KeyDown.

Это лучший способ встроить AutoSuggest в ComboBox или есть встроенный способ сделать то же самое?

XAML:

<ComboBox x:Class="TestComboSuggest343.NationalityComboBox"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Height="300" Width="300">
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Value}"/>
        </DataTemplate>        
    </ComboBox.ItemTemplate>
</ComboBox>

Code-Behind:

public partial class NationalityComboBox : ComboBox
{
    public NationalityComboBox()
    {
        InitializeComponent();

        Items.Add(new KeyValuePair<string, string>(null, "Please choose..."));
        Items.Add(new KeyValuePair<string, string>(null, "American"));
        Items.Add(new KeyValuePair<string, string>(null, "Australian"));
        Items.Add(new KeyValuePair<string, string>(null, "Belgian"));
        Items.Add(new KeyValuePair<string, string>(null, "French"));
        Items.Add(new KeyValuePair<string, string>(null, "German"));
        Items.Add(new KeyValuePair<string, string>(null, "Georgian"));
        SelectedIndex = 0;

        KeyDown += new KeyEventHandler(NationalityComboBox_KeyDown);

    }

    void NationalityComboBox_KeyDown(object sender, KeyEventArgs e)
    {
        SelectedIndex = 4; // can create logic here to handle key presses, e.g. "G", "E", "O"....
    }
}

Ответы [ 2 ]

1 голос
/ 05 октября 2009

Я написал прикрепленное свойство, чтобы сделать это:

public class ComboBoxAutoFilter
{
    public static bool GetEnabled(DependencyObject obj)
    {
        return (bool)obj.GetValue(EnabledProperty);
    }

    public static void SetEnabled(DependencyObject obj, bool value)
    {
        obj.SetValue(EnabledProperty, value);
    }

    // Using a DependencyProperty as the backing store for Enabled.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty EnabledProperty =
        DependencyProperty.RegisterAttached(
            "Enabled",
            typeof(bool),
            typeof(ComboBoxAutoFilter),
            new UIPropertyMetadata(false, Enabled_Changed)
        );

    private static void Enabled_Changed(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
        ComboBox combo = sender as ComboBox;
        if (combo != null)
        {
            if (combo.Template != null)
                SetTextChangedHandler(combo);
            else
                combo.Loaded += new RoutedEventHandler(combo_Loaded);
        }
    }

    static void combo_Loaded(object sender, RoutedEventArgs e)
    {
        ComboBox combo = sender as ComboBox;
        combo.Loaded -= combo_Loaded;
        if (combo.Template != null)
            SetTextChangedHandler(combo);
    }

    private static void SetTextChangedHandler(ComboBox combo)
    {
        TextBox textBox = combo.Template.FindName("PART_EditableTextBox", combo) as TextBox;
        if (textBox != null)
        {
            bool enabled = GetEnabled(combo);
            if (enabled)
                textBox.TextChanged += textBox_TextChanged;
            else
                textBox.TextChanged -= textBox_TextChanged;
        }
    }

    private static void textBox_TextChanged(object sender, RoutedEventArgs e)
    {
        TextBox textBox = sender as TextBox;
        ComboBox combo = textBox.TemplatedParent as ComboBox;
        combo.IsDropDownOpen = true;
        string text = textBox.Text.Substring(0, textBox.SelectionStart);
        combo.Items.Filter = value => value.ToString().StartsWith(text);
    }

}

Вы можете использовать это так:

    <ComboBox IsEditable="True"
              local:ComboBoxAutoFilter.Enabled="True">
        <sys:String>American</sys:String>
        <sys:String>Australian</sys:String>
        <sys:String>Belgian</sys:String>
        <sys:String>French</sys:String>
        <sys:String>German</sys:String>
        <sys:String>Georgian</sys:String>
        ...
    </ComboBox>
0 голосов
/ 05 октября 2009

Проверьте автоматическое заполнение текстовых полей, предусмотренных в Silverlight Toolkit . Я считаю, что они также доступны для WPF.

Вы можете увидеть это в действии в этой демонстрации XBAP . Ищите AutoCompleteBox.

...