using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace XHandler.Controls { /// /// 按照步骤 1a 或 1b 操作,然后执行步骤 2 以在 XAML 文件中使用此自定义控件。 /// /// 步骤 1a) 在当前项目中存在的 XAML 文件中使用该自定义控件。 /// 将此 XmlNamespace 特性添加到要使用该特性的标记文件的根 /// 元素中: /// /// xmlns:MyNamespace="clr-namespace:XHandler.Controls" /// /// /// 步骤 1b) 在其他项目中存在的 XAML 文件中使用该自定义控件。 /// 将此 XmlNamespace 特性添加到要使用该特性的标记文件的根 /// 元素中: /// /// xmlns:MyNamespace="clr-namespace:XHandler.Controls;assembly=XHandler.Controls" /// /// 您还需要添加一个从 XAML 文件所在的项目到此项目的项目引用, /// 并重新生成以避免编译错误: /// /// 在解决方案资源管理器中右击目标项目,然后依次单击 /// “添加引用”->“项目”->[浏览查找并选择此项目] /// /// /// 步骤 2) /// 继续操作并在 XAML 文件中使用控件。 /// /// /// /// public class MultiComboBox : ComboBox { static MultiComboBox() { DefaultStyleKeyProperty.OverrideMetadata(typeof(MultiComboBox), new FrameworkPropertyMetadata(typeof(MultiComboBox))); } private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { d.SetValue(e.Property, e.NewValue); } private ObservableCollection _ChekedItems = new ObservableCollection(); /// /// 选中项列表 /// public ObservableCollection ChekedItems { get { return _ChekedItems; } set { SetValue(ChekedItemsProperty, value); } } public static readonly DependencyProperty ChekedItemsProperty = DependencyProperty.Register("ChekedItems", typeof(ObservableCollection), typeof(MultiComboBox), new PropertyMetadata(new ObservableCollection(), OnPropertyChanged)); /// /// ListBox竖向列表 /// private ListBox _ListBoxV; /// /// ListBox横向列表 /// private ListBox _ListBoxH; public override void OnApplyTemplate() { base.OnApplyTemplate(); _ListBoxV = Template.FindName("PART_ListBox", this) as ListBox; _ListBoxH = Template.FindName("PART_ListBoxChk", this) as ListBox; if (_ListBoxV != null && _ListBoxH != null) { _ListBoxH.ItemsSource = ChekedItems; _ListBoxV.SelectionChanged += _ListBoxV_SelectionChanged; _ListBoxH.SelectionChanged += _ListBoxH_SelectionChanged; if (ItemsSource != null) { foreach (var item in ItemsSource) { MultiCbxBaseData bdc = item as MultiCbxBaseData; if (bdc.IsCheck) { _ListBoxV.SelectedItems.Add(bdc); } } } } } private void _ListBoxH_SelectionChanged(object sender, SelectionChangedEventArgs e) { foreach (var item in e.AddedItems) { MultiCbxBaseData datachk = item as MultiCbxBaseData; } foreach (var item in e.RemovedItems) { MultiCbxBaseData datachk = item as MultiCbxBaseData; for (int i = 0; i < _ListBoxV.SelectedItems.Count; i++) { MultiCbxBaseData datachklist = _ListBoxV.SelectedItems[i] as MultiCbxBaseData; if (datachklist.ID == datachk.ID) { _ListBoxV.SelectedItems.Remove(_ListBoxV.SelectedItems[i]); } } } } void _ListBoxV_SelectionChanged(object sender, SelectionChangedEventArgs e) { foreach (var item in e.AddedItems) { MultiCbxBaseData datachk = item as MultiCbxBaseData; datachk.IsCheck = true; if (_ChekedItems.IndexOf(datachk) < 0) { _ChekedItems.Add(datachk); } } foreach (var item in e.RemovedItems) { MultiCbxBaseData datachk = item as MultiCbxBaseData; datachk.IsCheck = false; _ChekedItems.Remove(datachk); } } public void SetSelecteItems(ObservableCollection items) { foreach(var item in items) { _ListBoxV.SelectedItems.Add(item); } } public void AddSelectedItem(MultiCbxBaseData item) { _ListBoxV.SelectedItems.Add(item); } public class MultiCbxBaseData { private string _id; /// /// 关联主键 /// public string ID { get { return _id; } set { _id = value; } } private string _viewName; /// /// 显示名称 /// public string ViewName { get { return _viewName; } set { _viewName = value; } } private bool _isCheck; /// /// 是否选中 /// public bool IsCheck { get { return _isCheck; } set { _isCheck = value; } } } } }