多選Combobox的實現(適合MVVM模式)
MVVM沒有.cs後臺邏輯,一般依靠command驅動邏輯及通過binding(vm層的屬性)來顯示前端
我的資料類Student有三個屬性int StuId ,string StuName ,bool isChecked。
首先第一步建立一個UserControl,裡面放一個ComboBox
<ComboBox x:Name="cb" Width="150" Height="25" ItemsSource="{Binding StudentList}">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox Click="CheckBox_Click" IsChecked="{Binding IsChecked,Mode=TwoWay}"/>
<TextBlock Text="{Binding StuName}"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
ComboBox 的樣式改造如前篇非MvvM模式下的改造一樣,只要將template中ContentPresenter的Content="{TemplateBinding SelectionBoxItem}"改成Content="{TemplateBinding Tag}"即可。
然後在UserControl.cs里加一個依賴屬性
public List<Student> SelectedItems1
{
get { return (List<Student>)GetValue(SelectedItems1Property); }
set { SetValue(SelectedItems1Property, value); }
}
public static readonly DependencyProperty SelectedItems1Property =
DependencyProperty.Register("SelectedItems1", typeof(List<Student>), typeof(ComboboxEx),new PropertyMetadata(null,new PropertyChangedCallback(OnSelectedChangeCallBack)));
private static void OnSelectedChangeCallBack(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
MessageBox.Show("Success");
}
這裡在回撥函式中做了個彈出框的處理,用來判斷屬性繫結是否成功。
勾選框的邏輯處理:
private void CheckBox_Click(object sender, RoutedEventArgs e)
{
var items = this.cb.ItemsSource ;
if (items != null )
{
SelectedStr=string.Empty;
foreach (Student item in items)
{
if (item.IsChecked == true)
{
SelectedStr = string.Format("{0}{1};", SelectedStr, item.StuName);
}
}
this.cb.Tag = SelectedStr;
}
}
第二步,建立ViewModel層
裡面建立兩個屬性,一個用來建立資料來源集合,一個用來存放勾選的集合
public ObservableCollection<Student> StudentList{get;set;}
private List<Student> _SelectedItems;
public List<Student> SelectedItems
{
get { return _SelectedItems; }
set
{
if (PropertyChanged != null)
{
_SelectedItems = value;
this.PropertyChanged(this, new PropertyChangedEventArgs("SelectedItems"));
}
}
}
建立一個command及一個遍歷方法
public ICommand CheckItemsChangedCommand { get; set; }
public void UpdataSelecteditems()
{
List<Student> slist = new List<Student>();
foreach (var item in StudentList)
{
if (item.IsChecked == true)
{
slist.Add(item);
}
}
SelectedItems = slist;
}
在ViewModel建構函式中繫結資料集合,例項化Command;
public ComboboxViewModel()
{
SelectedItems = new List<Student>();
StudentList = new ObservableCollection<Student>()
{
new Student(){StuId=1,StuName="aaa"},
new Student(){StuId=2,StuName="bbb"},
new Student(){StuId=3,StuName="ccc"},
new Student(){StuId=3,StuName="ddd"},
new Student(){StuId=3,StuName="eee"}
};
CheckItemsChangedCommand = new ActionCommand(this.UpdataSelecteditems);
}
最後一步完成部件的組裝
<StackPanel>
<UserControls:ComboboxEx x:Name="cb" SelectedItems1="{Binding SelectedItems}"></UserControls:ComboboxEx>
<Button HorizontalAlignment="Center" Content="Click" Command="{Binding CheckItemsChangedCommand}"/>
</StackPanel>
後臺加 this.DataContext = new ComboboxViewModel();
(PS:當在Selecte ComboboxItem而非Check的時候,combobox head會顯示checkbox。這裡要重現ComboboxItem的onMouseLeftUp事件,裡面改成e.handle =true即可)