I have a Nationality ComboBox like the one below and want to make it so that the user can type letters to narrow in on the choices. I could solve this the way I started below by adding logic in the NationalityComboBox_KeyDown method.
Is this the best way to build AutoSuggest into a ComboBox or is there a built-in way to do the same thing?
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.Ad开发者_JAVA技巧d(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"....
}
}
I wrote an attached property to do that :
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);
}
}
You can use it like that :
<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>
Check out the auto complete text boxes provided in the Silverlight Toolkit. I believe they're available for WPF too.
You can see it in action in this XBAP demo. Look for AutoCompleteBox
.
精彩评论