Over View
ComboBox 由一个 TextBox 一个 Button 和一个 Popup 组合而成;
Data Binding
当 data binding 到 ComboBox 时,如何显示数据,有如下选择:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
<
ComboBox
Width
="90"
Margin
="0,0,10,0"
ItemsSource =" {Binding MyList} "
DisplayMemberPath ="ID"
SelectedItem =" {Binding MySelected} "
SelectedValuePath ="ID"
/>
ItemsSource =" {Binding MyList} "
DisplayMemberPath ="ID"
SelectedItem =" {Binding MySelected} "
SelectedValuePath ="ID"
/>
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
<
ComboBox
Width
="90"
Margin
="0,0,10,0"
ItemsSource =" {Binding MyList} "
SelectedItem =" {Binding MySelected} "
SelectedValuePath ="ID"
>
< ComboBox.ItemTemplate >
< DataTemplate >
< TextBlock Text =" {Binding ID} " />
</ DataTemplate >
</ ComboBox.ItemTemplate >
</ ComboBox >
ItemsSource =" {Binding MyList} "
SelectedItem =" {Binding MySelected} "
SelectedValuePath ="ID"
>
< ComboBox.ItemTemplate >
< DataTemplate >
< TextBlock Text =" {Binding ID} " />
</ DataTemplate >
</ ComboBox.ItemTemplate >
</ ComboBox >
其中 MyList 是一个 ObservableCollection<MyItem>:
public
class
MyItem
{
public int ID { get ; set ; }
public string Name { get ; set ; }
}
{
public int ID { get ; set ; }
public string Name { get ; set ; }
}
Command Binding
绑定一个 Command 到 ComboBox 的 SelectionChanged 事件,可以有如下选择:
1,delegate 函数调用
2,从ComboBox 派生新类,实现 ICommandSource
3,使用 Attached Property
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
public
static
class
ItemSelectedBehavior
{
public static DependencyProperty ItemSelectedProperty =
DependencyProperty.RegisterAttached( " ItemSelected " ,
typeof (ICommand),
typeof (ItemSelectedBehavior),
new FrameworkPropertyMetadata( null , new PropertyChangedCallback(ItemSelectedBehavior.ItemSelectedChanged)));
public static void SetItemSelected(DependencyObject target, ICommand value)
{
target.SetValue(ItemSelectedBehavior.ItemSelectedProperty, value);
}
private static void ItemSelectedChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
{
Selector element = target as Selector;
if (element != null )
{
// If we're putting in a new command and there wasn't one already hook the event
if ((e.NewValue != null ) && (e.OldValue == null ))
{
element.SelectionChanged += element_SelectionChanged;
}
// If we're clearing the command and it wasn't already null unhook the event
else if ((e.NewValue == null ) && (e.OldValue != null ))
{
element.SelectionChanged -= element_SelectionChanged;
}
}
}
private static void element_SelectionChanged( object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
Selector element = sender as Selector;
if (element != null )
{
ICommand command = (ICommand)element.GetValue(ItemSelectedBehavior.ItemSelectedProperty);
command.Execute(element.SelectedItem);
}
}
}
{
public static DependencyProperty ItemSelectedProperty =
DependencyProperty.RegisterAttached( " ItemSelected " ,
typeof (ICommand),
typeof (ItemSelectedBehavior),
new FrameworkPropertyMetadata( null , new PropertyChangedCallback(ItemSelectedBehavior.ItemSelectedChanged)));
public static void SetItemSelected(DependencyObject target, ICommand value)
{
target.SetValue(ItemSelectedBehavior.ItemSelectedProperty, value);
}
private static void ItemSelectedChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
{
Selector element = target as Selector;
if (element != null )
{
// If we're putting in a new command and there wasn't one already hook the event
if ((e.NewValue != null ) && (e.OldValue == null ))
{
element.SelectionChanged += element_SelectionChanged;
}
// If we're clearing the command and it wasn't already null unhook the event
else if ((e.NewValue == null ) && (e.OldValue != null ))
{
element.SelectionChanged -= element_SelectionChanged;
}
}
}
private static void element_SelectionChanged( object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
Selector element = sender as Selector;
if (element != null )
{
ICommand command = (ICommand)element.GetValue(ItemSelectedBehavior.ItemSelectedProperty);
command.Execute(element.SelectedItem);
}
}
}
<
ComboBox
ItemsSource
="
{Binding MyStringList}
"
local:ItemSelectedBehavior.ItemSelected =" {Binding CmdSelectionChanged} "
/>
local:ItemSelectedBehavior.ItemSelected =" {Binding CmdSelectionChanged} "
/>
参考:http://johnllao.wordpress.com/2009/07/21/attached-property-sample/
属性 Text 和 属性 SelectedItem
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
<
ComboBox
Grid.Row
="1"
ItemsSource =" {Binding MyStringList} "
SelectedItem =" {Binding MySelectedString} "
IsEditable ="True"
StaysOpenOnEdit ="True"
Text =" {Binding EditingString} "
/>
ItemsSource =" {Binding MyStringList} "
SelectedItem =" {Binding MySelectedString} "
IsEditable ="True"
StaysOpenOnEdit ="True"
Text =" {Binding EditingString} "
/>
Text 属性 binding 改变之前,会先改变 SelectedItem 的 binding。
如何响应 TextChanged 事件
最简单的方法:
<ComboBox TextBoxBase.TextChanged="theTextBox_TextChanged"
IsEditable="True"
/>
另外的一个方法是,在 ComboBox 的 Loaded 事件里找到 TextBox,然后响应其事件。如何获得那个TextBox?