基于WPF实现筛选下拉多选控件
(福利推荐:你还在原价购买阿里云服务器?现在阿里云0.8折限时抢购活动来啦!4核8G企业云服务器仅2998元/3年,立即抢购>>>:9i0i.cn/aliyun)
WPF 实现筛选下拉多选控件
- 框架使用
.NET4 至 .NET6
; Visual Studio 2022
;
创建 MultiSelectionSearchComboBox
继承 Control
.
模板中创建两个 ListBox
PART_Selector
用来显示所有Item
PART_SearchSelector
用于记录筛选到的Item
Item
继承 ListBoxItem
并将样式模板修改为 CheckBox
解决 Popup
中 IME
不跟随 TextBox
问题
private static extern IntPtr SetFocus(IntPtr hWnd);
当 TextBox
中 Text
发生改变时通过循环 Item
中的 GetProperty
获取特定 DisplayMemberPath
属性,判断是否包含输入的 SearchText
值,如果包含则添加PART_SearchSelector
中,当 SelectionChanged
事件更改时将修改 PART_Selector
中的内容。
实现代码
1)创建 MultiSelectionSearchComboBox.cs
代码如下:
using?System; using?System.Collections; using?System.Collections.Generic; using?System.Linq; using?System.Runtime.InteropServices; using?System.Windows; using?System.Windows.Controls; using?System.Windows.Controls.Primitives; using?System.Windows.Interop; namespace?WPFDevelopers.Controls { ????[TemplatePart(Name?=?"PART_TextBox",?Type?=?typeof(TextBox))] ????[TemplatePart(Name?=?"PART_Popup",?Type?=?typeof(Popup))] ????[TemplatePart(Name?=?"PART_Selector",?Type?=?typeof(ListBox))] ????[TemplatePart(Name?=?"PART_SelectAll",?Type?=?typeof(CheckBox))] ????[TemplatePart(Name?=?"PART_SearchSelector",?Type?=?typeof(ListBox))] ????public?class?MultiSelectionSearchComboBox?:?Control ????{ ????????private?const?string?TextBoxTemplateName?=?"PART_TextBox"; ????????private?const?string?PopupTemplateName?=?"PART_Popup"; ????????private?const?string?ListBoxTemplateName?=?"PART_Selector"; ????????private?const?string?CheckBoxTemplateName?=?"PART_SelectAll"; ????????private?const?string?ListBoxTemplateNameSearch?=?"PART_SearchSelector"; ????????public?static?readonly?RoutedEvent?ClosedEvent?= ????????????EventManager.RegisterRoutedEvent("Closed", ????????????????RoutingStrategy.Bubble, ????????????????typeof(RoutedEventHandler), ????????????????typeof(MultiSelectionSearchComboBox)); ????????public?static?readonly?DependencyProperty?DisplayMemberPathProperty?= ???????????DependencyProperty.Register("DisplayMemberPath", ???????????????typeof(string), ???????????????typeof(MultiSelectionSearchComboBox), ???????????????new?PropertyMetadata(string.Empty)); ????????public?static?readonly?DependencyProperty?SelectedValuePathProperty?= ???????????DependencyProperty.Register("SelectedValuePath", ???????????????typeof(string), ???????????????typeof(MultiSelectionSearchComboBox), ???????????????new?PropertyMetadata(string.Empty)); ????????public?static?readonly?DependencyProperty?TextProperty?= ????????????DependencyProperty.Register("Text", ????????????????typeof(string), ????????????????typeof(MultiSelectionSearchComboBox), ????????????????new?PropertyMetadata(string.Empty)); ????????public?static?readonly?DependencyProperty?ItemsSourceProperty?= ????????????DependencyProperty.Register("ItemsSource",?typeof(IEnumerable),?typeof(MultiSelectionSearchComboBox), ????????????????new?PropertyMetadata()); ????????public?static?readonly?DependencyProperty?ItemsSourceSearchProperty?= ????????????DependencyProperty.Register("ItemsSourceSearch",?typeof(IEnumerable),?typeof(MultiSelectionSearchComboBox), ????????????????new?PropertyMetadata()); ????????public?static?readonly?DependencyProperty?SelectAllContentProperty?= ????????????DependencyProperty.Register("SelectAllContent",?typeof(object),?typeof(MultiSelectionSearchComboBox), ????????????????new?PropertyMetadata("全选")); ????????public?static?readonly?DependencyProperty?IsSelectAllActiveProperty?= ????????????DependencyProperty.Register("IsSelectAllActive",?typeof(bool),?typeof(MultiSelectionSearchComboBox), ????????????????new?PropertyMetadata(false)); ????????public?static?readonly?DependencyProperty?DelimiterProperty?= ????????????DependencyProperty.Register("Delimiter",?typeof(string),?typeof(MultiSelectionSearchComboBox), ????????????????new?PropertyMetadata(";")); ????????public?static?readonly?DependencyProperty?IsDropDownOpenProperty?= ????????????DependencyProperty.Register("IsDropDownOpen",?typeof(bool),?typeof(MultiSelectionSearchComboBox), ????????????????new?PropertyMetadata(false,?OnIsDropDownOpenChanged)); ????????public?static?readonly?DependencyProperty?MaxDropDownHeightProperty?= ????????????DependencyProperty.Register("MaxDropDownHeight",?typeof(double),?typeof(MultiSelectionSearchComboBox), ????????????????new?UIPropertyMetadata(SystemParameters.PrimaryScreenHeight?/?3.0,?OnMaxDropDownHeightChanged)); ????????public?static?readonly?DependencyProperty?SelectedItemsProperty?= ????????????DependencyProperty.Register("SelectedItems",?typeof(IList),?typeof(MultiSelectionSearchComboBox), ????????????????new?FrameworkPropertyMetadata(null, ????????????????????FrameworkPropertyMetadataOptions.BindsTwoWayByDefault?|?FrameworkPropertyMetadataOptions.Journal, ????????????????????OnSelectedItemsChanged)); ????????public?static?readonly?DependencyProperty?SearchWatermarkProperty?= ???????????DependencyProperty.Register("SearchWatermark", ???????????????typeof(string), ???????????????typeof(MultiSelectionSearchComboBox), ???????????????new?PropertyMetadata(string.Empty)); ????????private?CheckBox?_checkBox; ????????private?ListBox?_listBox; ????????private?ListBox?_listBoxSearch; ????????private?Popup?_popup; ????????private?TextBox?_textBox; ????????private?List<object>?selectedItems; ????????private?List<object>?selectedList; ????????private?List<object>?selectedSearchList; ????????private?string?theLastText; ????????static?MultiSelectionSearchComboBox() ????????{ ????????????DefaultStyleKeyProperty.OverrideMetadata(typeof(MultiSelectionSearchComboBox), ????????????????new?FrameworkPropertyMetadata(typeof(MultiSelectionSearchComboBox))); ????????} ????????public?string?Delimiter ????????{ ????????????get?=>?(string)GetValue(DelimiterProperty); ????????????set?=>?SetValue(DelimiterProperty,?value); ????????} ????????public?string?SelectedValuePath ????????{ ????????????get?=>?(string)GetValue(SelectedValuePathProperty); ????????????set?=>?SetValue(SelectedValuePathProperty,?value); ????????} ????????public?string?DisplayMemberPath ????????{ ????????????get?=>?(string)GetValue(DisplayMemberPathProperty); ????????????set?=>?SetValue(DisplayMemberPathProperty,?value); ????????} ????????public?string?Text ????????{ ????????????get?=>?(string)?GetValue(TextProperty); ????????????set?=>?SetValue(TextProperty,?value); ????????} ????????public?IEnumerable?ItemsSource ????????{ ????????????get?=>?(IEnumerable)GetValue(ItemsSourceProperty); ????????????set?=>?SetValue(ItemsSourceProperty,?value); ????????} ????????public?IEnumerable?ItemsSourceSearch ????????{ ????????????get?=>?(IEnumerable)?GetValue(ItemsSourceSearchProperty); ????????????set?=>?SetValue(ItemsSourceSearchProperty,?value); ????????} ????????public?object?SelectAllContent ????????{ ????????????get?=>?GetValue(SelectAllContentProperty); ????????????set?=>?SetValue(SelectAllContentProperty,?value); ????????} ????????public?bool?IsSelectAllActive ????????{ ????????????get?=>?(bool)?GetValue(IsSelectAllActiveProperty); ????????????set?=>?SetValue(IsSelectAllActiveProperty,?value); ????????} ????????public?bool?IsDropDownOpen ????????{ ????????????get?=>?(bool)?GetValue(IsDropDownOpenProperty); ????????????set?=>?SetValue(IsDropDownOpenProperty,?value); ????????} ????????public?double?MaxDropDownHeight ????????{ ????????????get?=>?(double)?GetValue(MaxDropDownHeightProperty); ????????????set?=>?SetValue(MaxDropDownHeightProperty,?value); ????????} ????????public?IList?SelectedItems ????????{ ????????????get?=>?(IList)?GetValue(SelectedItemsProperty); ????????????set?=>?SetValue(SelectedItemsProperty,?value); ????????} ????????public?string?SearchWatermark ????????{ ????????????get?=>?(string)GetValue(SearchWatermarkProperty); ????????????set?=>?SetValue(SearchWatermarkProperty,?value); ????????} ????????[DllImport("User32.dll")] ????????private?static?extern?IntPtr?SetFocus(IntPtr?hWnd); ????????public?event?RoutedEventHandler?Closed ????????{ ????????????add?=>?AddHandler(ClosedEvent,?value); ????????????remove?=>?RemoveHandler(ClosedEvent,?value); ????????} ????????public?override?void?OnApplyTemplate() ????????{ ????????????base.OnApplyTemplate(); ????????????selectedList?=?new?List<object>(); ????????????selectedSearchList?=?new?List<object>(); ????????????selectedItems?=?new?List<object>(); ????????????_textBox?=?GetTemplateChild(TextBoxTemplateName)?as?TextBox; ????????????_popup?=?GetTemplateChild(PopupTemplateName)?as?Popup; ????????????if?(_popup?!=?null) ????????????????_popup.GotFocus?+=?_popup_GotFocus; ????????????_listBox?=?GetTemplateChild(ListBoxTemplateName)?as?ListBox; ????????????_checkBox?=?GetTemplateChild(CheckBoxTemplateName)?as?CheckBox; ????????????_listBoxSearch?=?GetTemplateChild(ListBoxTemplateNameSearch)?as?ListBox; ????????????if?(_textBox?!=?null) ????????????{ ????????????????_textBox.TextChanged?-=?_textbox_TextChanged; ????????????????_textBox.TextChanged?+=?_textbox_TextChanged; ????????????} ????????????if?(_checkBox?!=?null) ????????????{ ????????????????_checkBox.Checked?-=?_checkBox_Checked; ????????????????_checkBox.Unchecked?-=?_checkBox_Unchecked; ????????????????_checkBox.Checked?+=?_checkBox_Checked; ????????????????_checkBox.Unchecked?+=?_checkBox_Unchecked; ????????????} ????????????if?(_listBox?!=?null) ????????????{ ????????????????_listBox.IsVisibleChanged?-=?_listBox_IsVisibleChanged; ????????????????_listBox.IsVisibleChanged?+=?_listBox_IsVisibleChanged; ????????????????_listBox.SelectionChanged?-=?_listBox_SelectionChanged; ????????????????_listBox.SelectionChanged?+=?_listBox_SelectionChanged; ????????????} ????????????if?(_listBoxSearch?!=?null) ????????????{ ????????????????_listBoxSearch.IsVisibleChanged?-=?_listBoxSearch_IsVisibleChanged; ????????????????_listBoxSearch.IsVisibleChanged?+=?_listBoxSearch_IsVisibleChanged; ????????????????_listBoxSearch.SelectionChanged?-=?_listBoxSearch_SelectionChanged; ????????????????_listBoxSearch.SelectionChanged?+=?_listBoxSearch_SelectionChanged; ????????????} ????????} ????????private?void?_listBoxSearch_IsVisibleChanged(object?sender,?DependencyPropertyChangedEventArgs?e) ????????{ ????????????if?((bool)?e.NewValue) ????????????????UpdateIsChecked(_listBoxSearch); ????????} ????????private?void?_listBox_IsVisibleChanged(object?sender,?DependencyPropertyChangedEventArgs?e) ????????{ ????????????if?((bool)?e.NewValue) ????????????{ ????????????????foreach?(var?item?in?selectedSearchList) ????????????????????if?(!_listBox.SelectedItems.Contains(item)) ????????????????????????_listBox.SelectedItems.Add(item); ????????????????UpdateIsChecked(_listBox); ????????????} ????????} ????????private?void?UpdateIsChecked(ListBox?listBox) ????????{ ????????????_checkBox.Checked?-=?_checkBox_Checked; ????????????if?(listBox.Items.Count?>?0?&&?listBox.Items.Count?==?listBox.SelectedItems.Count) ????????????{ ????????????????if?(_checkBox.IsChecked?!=?true) ????????????????????_checkBox.IsChecked?=?true; ????????????} ????????????else ????????????{ ????????????????if?(listBox.SelectedItems.Count?==?0) ????????????????????_checkBox.IsChecked?=?false; ????????????????else ????????????????????_checkBox.IsChecked?=?null; ????????????} ????????????_checkBox.Checked?+=?_checkBox_Checked; ????????} ????????private?void?_popup_GotFocus(object?sender,?RoutedEventArgs?e) ????????{ ????????????var?source?=?(HwndSource)?PresentationSource.FromVisual(_popup.Child); ????????????if?(source?!=?null) ????????????{ ????????????????SetFocus(source.Handle); ????????????????_textBox.Focus(); ????????????} ????????} ????????private?void?_checkBox_Unchecked(object?sender,?RoutedEventArgs?e) ????????{ ????????????if?(_listBoxSearch.Visibility?==?Visibility.Visible) ????????????????_listBoxSearch.UnselectAll(); ????????????else ????????????????_listBox.UnselectAll(); ????????} ????????private?void?_checkBox_Checked(object?sender,?RoutedEventArgs?e) ????????{ ????????????if?(_listBoxSearch.Visibility?==?Visibility.Visible) ????????????????_listBoxSearch.SelectAll(); ????????????else ????????????????_listBox.SelectAll(); ????????} ????????private?void?Combination() ????????{ ????????????var?seletedName?=?new?List<string>(); ????????????foreach?(var?item?in?_listBox.SelectedItems) ????????????{ ????????????????var?name?=?GetDisplayText(item); ????????????????seletedName.Add(name); ????????????} ????????????foreach?(var?item?in?_listBoxSearch.SelectedItems) ????????????{ ????????????????if?(_listBox.SelectedItems.Contains(item)) ????????????????????continue; ????????????????var?name?=?GetDisplayText(item); ????????????????seletedName.Add(name); ????????????} ????????????Text?=?string.Join(Delimiter,?seletedName.ToArray()); ????????} ????????private?void?_listBox_SelectionChanged(object?sender,?SelectionChangedEventArgs?e) ????????{ ????????????if?(e.RemovedItems.Count?>?0) ????????????????foreach?(var?item?in?e.RemovedItems) ????????????????????if?(_checkBox.IsChecked?==?true) ????????????????????{ ????????????????????????_checkBox.Unchecked?-=?_checkBox_Unchecked; ????????????????????????if?(_listBox.Items.Count?==?1) ????????????????????????????_checkBox.IsChecked?=?false; ????????????????????????else ????????????????????????????_checkBox.IsChecked?=?null; ????????????????????????_checkBox.Unchecked?+=?_checkBox_Unchecked; ????????????????????} ????????????if?(e.AddedItems.Count?>?0) ????????????????SelectionChecked(_listBox); ????????????Combination(); ????????????SelectedItems?=?_listBox.SelectedItems; ????????} ????????private?void?_listBoxSearch_SelectionChanged(object?sender,?SelectionChangedEventArgs?e) ????????{ ????????????if?(!_listBoxSearch.IsVisible)?return; ????????????if?(e.RemovedItems.Count?>?0) ????????????{ ????????????????foreach?(var?item?in?e.RemovedItems) ????????????????????if?(selectedSearchList.Contains(item)) ????????????????????????selectedSearchList.Remove(item); ????????????????Combination(); ????????????????SelectionChecked(_listBoxSearch); ????????????} ????????????if?(e.AddedItems.Count?>?0) ????????????{ ????????????????foreach?(var?item?in?e.AddedItems) ????????????????????if?(!selectedSearchList.Contains(item)) ????????????????????????selectedSearchList.Add(item); ????????????????Combination(); ????????????????SelectionChecked(_listBoxSearch); ????????????} ????????} ????????private?void?SelectionChecked(ListBox?listbox) ????????{ ????????????if?(listbox.SelectedItems.Count?>?0 ????????????????&& ????????????????listbox.Items.Count?==?listbox.SelectedItems.Count) ????????????{ ????????????????_checkBox.Checked?-=?_checkBox_Checked; ????????????????_checkBox.IsChecked?=?true; ????????????????_checkBox.Checked?+=?_checkBox_Checked; ????????????} ????????????else ????????????{ ????????????????_checkBox.Checked?-=?_checkBox_Checked; ????????????????if?(listbox.SelectedItems.Count?>?0 ????????????????????&&? ????????????????????listbox.Items.Count?==?listbox.SelectedItems.Count) ????????????????{ ????????????????????if?(_checkBox.IsChecked?!=?true) ????????????????????????_checkBox.IsChecked?=?true; ????????????????} ????????????????else ????????????????{ ????????????????????if?(listbox.SelectedItems.Count?==?0) ????????????????????????_checkBox.IsChecked?=?false; ????????????????????else ????????????????????????_checkBox.IsChecked?=?null; ????????????????} ????????????????_checkBox.Checked?+=?_checkBox_Checked; ????????????} ????????} ????????private?string?GetDisplayText(object?dataItem,?string?path?=?null) ????????{ ????????????if?(dataItem?==?null)?return?string.Empty; ????????????return?GetPropertyValue(dataItem); ????????} ????????private?void?_textbox_TextChanged(object?sender,?TextChangedEventArgs?e) ????????{ ????????????if?(string.IsNullOrWhiteSpace(theLastText))?theLastText?=?_textBox.Text; ????????????SearchText(_textBox.Text); ????????} ????????private?void?SearchText(string?_text) ????????{ ????????????var?text?=?_text; ????????????if?(string.IsNullOrWhiteSpace(text)) ????????????{ ????????????????if?(_listBoxSearch.Visibility?!=?Visibility.Collapsed) ????????????????????_listBoxSearch.Visibility?=?Visibility.Collapsed; ????????????????if?(_listBox.Visibility?!=?Visibility.Visible) ????????????????????_listBox.Visibility?=?Visibility.Visible; ????????????} ????????????else ????????????{ ????????????????if(_listBoxSearch.Visibility?!=?Visibility.Visible) ????????????????????_listBoxSearch.Visibility?=?Visibility.Visible; ????????????????if(_listBox.Visibility?!=?Visibility.Collapsed) ????????????????????_listBox.Visibility?=?Visibility.Collapsed; ????????????????var?listSearch?=?new?List<object>(); ????????????????foreach?(var?item?in?_listBox.Items) ????????????????{ ????????????????????var?str?=?GetPropertyValue(item); ????????????????????if?(!string.IsNullOrWhiteSpace(str)) ????????????????????????if?(str.Contains(text.ToUpperInvariant())) ????????????????????????????listSearch.Add(item); ????????????????} ????????????????foreach?(var?item?in?selectedList) ????????????????????if?(!listSearch.Contains(item)) ????????????????????????listSearch.Add(item); ????????????????var?lastItem?=?ItemsSourceSearch; ????????????????ItemsSourceSearch?=?listSearch; ????????????????SelectionChecked(_listBoxSearch); ????????????????selectedItems.Clear(); ????????????????foreach?(var?item?in?_listBoxSearch.Items) ????????????????????if?(_listBox.SelectedItems.Contains(item)) ????????????????????????if?(!_listBoxSearch.SelectedItems.Contains(item)) ????????????????????????????_listBoxSearch.SelectedItems.Add(item); ????????????} ????????} ????????private?string?GetPropertyValue(object?item) ????????{ ????????????var?result?=?string.Empty; ????????????var?nameParts?=?DisplayMemberPath.Split('.'); ????????????if?(nameParts.Length?==?1) ????????????{ ????????????????var?property?=?item.GetType().GetProperty(DisplayMemberPath); ????????????????if?(property?!=?null) ????????????????????return?(property.GetValue(item,?null)????string.Empty).ToString(); ????????????} ????????????return?result.ToUpperInvariant(); ????????} ????????private?static?void?OnIsDropDownOpenChanged(DependencyObject?o,?DependencyPropertyChangedEventArgs?e) ????????{ ????????????var?multiSelectionSearchComboBox?=?o?as?MultiSelectionSearchComboBox; ????????????if?(multiSelectionSearchComboBox?!=?null) ????????????????multiSelectionSearchComboBox.OnIsOpenChanged((bool)?e.OldValue,?(bool)?e.NewValue); ????????} ????????protected?virtual?void?OnIsOpenChanged(bool?oldValue,?bool?newValue) ????????{ ????????????if?(!newValue) ????????????????RaiseRoutedEvent(ClosedEvent); ????????} ????????private?void?RaiseRoutedEvent(RoutedEvent?routedEvent) ????????{ ????????????var?args?=?new?RoutedEventArgs(routedEvent,?this); ????????????RaiseEvent(args); ????????} ????????private?static?void?OnMaxDropDownHeightChanged(DependencyObject?o,?DependencyPropertyChangedEventArgs?e) ????????{ ????????????var?comboBox?=?o?as?MultiSelectionSearchComboBox; ????????????if?(comboBox?!=?null) ????????????????comboBox.OnMaxDropDownHeightChanged((double)?e.OldValue,?(double)?e.NewValue); ????????} ????????protected?virtual?void?OnMaxDropDownHeightChanged(double?oldValue,?double?newValue) ????????{ ????????} ????????private?static?void?OnSelectedItemsChanged(DependencyObject?d,?DependencyPropertyChangedEventArgs?e) ????????{ ????????????var?mltiSelectionSearchComboBox?=?d?as?MultiSelectionSearchComboBox; ????????????if?(e.NewValue?!=?null) ????????????{ ????????????????var?collection?=?e.NewValue?as?IList; ????????????????if?(collection.Count?<=?0)?return; ????????????????if?(e.OldValue?!=?null?&&?mltiSelectionSearchComboBox._listBox?!=?null) ????????????????{ ????????????????????mltiSelectionSearchComboBox._listBox.SelectionChanged?-= ????????????????????????mltiSelectionSearchComboBox._listBox_SelectionChanged; ????????????????????mltiSelectionSearchComboBox._listBox.SelectedItems.Clear(); ????????????????} ????????????????foreach?(var?item?in?collection) ????????????????{ ????????????????????var?name?=?mltiSelectionSearchComboBox.GetPropertyValue(item); ????????????????????var?model?=?mltiSelectionSearchComboBox._listBox.ItemsSource.OfType<object>().FirstOrDefault(h?=> ????????????????????????mltiSelectionSearchComboBox.GetPropertyValue(h).ToUpperInvariant() ????????????????????????????.Equals(name)); ????????????????????if?(model?!=?null?&&?!mltiSelectionSearchComboBox._listBox.SelectedItems.Contains(item)) ????????????????????????mltiSelectionSearchComboBox._listBox.SelectedItems.Add(model); ????????????????????if?(e.OldValue?!=?null?&&?mltiSelectionSearchComboBox._listBox?!=?null) ????????????????????????mltiSelectionSearchComboBox._listBox.SelectionChanged?+= ????????????????????????????mltiSelectionSearchComboBox._listBox_SelectionChanged; ????????????????????mltiSelectionSearchComboBox.Combination(); ????????????????} ????????????} ????????} ????} }
2)创建 MultiSelectionListBox.xaml
代码如下:
using?System.Windows; using?System.Windows.Controls; namespace?WPFDevelopers.Controls { ????public?class?MultiSelectionListBox:ListBox ????{ ????????protected?override?bool?IsItemItsOwnContainerOverride(object?item) ????????{ ????????????return?item?is?MultiSelectComboBoxItem; ????????} ????????protected?override?DependencyObject?GetContainerForItemOverride() ????????{ ????????????return?new?MultiSelectComboBoxItem(); ????????} ????} }
3)创建 MultiSelectionSearchComboBox.xaml
代码如下:
<ResourceDictionary?xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" ????????????????????xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" ????????????????????xmlns:controls="clr-namespace:WPFDevelopers.Controls" ????????????????????xmlns:helpers="clr-namespace:WPFDevelopers.Helpers"> ???? ????<ResourceDictionary.MergedDictionaries> ????????<ResourceDictionary?Source="Basic/ControlBasic.xaml"/> ????????<ResourceDictionary?Source="MultiSelectionComboBox.xaml"/> ????</ResourceDictionary.MergedDictionaries> ???? ????<Style?TargetType="{x:Type?controls:MultiSelectionSearchComboBox}"> ??<Setter?Property="ScrollViewer.HorizontalScrollBarVisibility"?Value="Auto"?/> ??<Setter?Property="ScrollViewer.VerticalScrollBarVisibility"?Value="Auto"?/> ??<Setter?Property="ScrollViewer.CanContentScroll"?Value="True"?/> ??<Setter?Property="MinWidth"?Value="120"?/> ??<Setter?Property="MinHeight"?Value="{StaticResource?MinHeight}"?/> ????????<Setter?Property="Height"?Value="{StaticResource?MinHeight}"?/> ??<Setter?Property="HorizontalContentAlignment"?Value="Left"?/> ??<Setter?Property="VerticalContentAlignment"?Value="Center"?/> ????????<Setter?Property="BorderBrush"?Value="{DynamicResource?BaseSolidColorBrush}"/> ????????<Setter?Property="BorderThickness"?Value="1"/> ??<Setter?Property="Background"?Value="{DynamicResource?BackgroundSolidColorBrush}"/> ??<Setter?Property="Padding"?Value="14.5,3,30,3"/> ????????<Setter?Property="Template"> ???<Setter.Value> ????????????????<ControlTemplate?TargetType="{x:Type?controls:MultiSelectionSearchComboBox}"> ?????<ControlTemplate.Resources> ??????<Storyboard?x:Key="OpenStoryboard"> ???????<DoubleAnimation?Storyboard.TargetName="PART_DropDown" ?????????????Storyboard.TargetProperty="(Grid.RenderTransform).(ScaleTransform.ScaleY)" ?????????????To="1"?Duration="00:00:.2" ?????????????EasingFunction="{StaticResource?ExponentialEaseOut}"/> ??????</Storyboard> ??????<Storyboard?x:Key="CloseStoryboard"> ???????<DoubleAnimation?Storyboard.TargetName="PART_DropDown" ?????????????Storyboard.TargetProperty="(Grid.RenderTransform).(ScaleTransform.ScaleY)" ?????????????To="0"?Duration="00:00:.2" ?????????????EasingFunction="{StaticResource?ExponentialEaseOut}"/> ??????</Storyboard> ?????</ControlTemplate.Resources> ????????????????????<controls:SmallPanel?SnapsToDevicePixels="True"> ??????<Border?Name="PART_Border" ????????Background="{TemplateBinding?Background}" ????????BorderBrush="{TemplateBinding?BorderBrush}" ????????BorderThickness="{TemplateBinding?BorderThickness}" ????????SnapsToDevicePixels="True" ????????CornerRadius="{Binding?Path=(helpers:ElementHelper.CornerRadius),?RelativeSource={RelativeSource?TemplatedParent}}"?/> ??????<ToggleButton?x:Name="PART_ToggleButton" ???????????Template="{StaticResource?ComboBoxToggleButton}" ???????????Style="{x:Null}" ???????????Focusable="False" ???????????ClickMode="Release" ???????????IsChecked="{Binding?IsDropDownOpen,?Mode=TwoWay,?RelativeSource={RelativeSource?TemplatedParent}}"/> ??????<TextBox?Name="PART_EditableTextBox" ?????????Template="{StaticResource?ComboBoxTextBox}" ?????????HorizontalAlignment="{TemplateBinding?HorizontalContentAlignment}" ?????????VerticalAlignment="{TemplateBinding?VerticalContentAlignment}" ?????????Margin="{TemplateBinding?Padding}" ?????????Focusable="True" ?????????????????????????????????Foreground="{DynamicResource?PrimaryTextSolidColorBrush}" ?????????Text="{Binding?Text,RelativeSource={RelativeSource?TemplatedParent},Mode=TwoWay}" ?????????Background="{TemplateBinding?Background}" ?????????SelectionBrush="{DynamicResource?WindowBorderBrushSolidColorBrush}" ?????????IsReadOnly="True"?Style="{x:Null}"?/> ????????????????????????<TextBlock?x:Name="PART_Watermark" ???????????????????????????????????Text="{Binding?Path=(helpers:ElementHelper.Watermark),RelativeSource={RelativeSource?TemplatedParent}}" ???????????????????????????????????Foreground="{DynamicResource?RegularTextSolidColorBrush}" ???????????????????????????????????HorizontalAlignment="{TemplateBinding?HorizontalContentAlignment}" ???????????????????????????????????VerticalAlignment="{TemplateBinding?VerticalContentAlignment}" ???????????????????????????????????FontSize="{StaticResource?NormalFontSize}" ???????????????????????????????????Margin="{TemplateBinding?Padding}"? ???????????????????????????????????Background="Transparent" ???????????????????????????????????TextTrimming="CharacterEllipsis" ???????????????????????????????????IsHitTestVisible="False" ???????????????????????????????????Padding="1,0"? ???????????????????????????????????Visibility="Collapsed"/> ????????????????????????<Popup?x:Name="PART_Popup" ????????AllowsTransparency="True" ????????PlacementTarget="{Binding?ElementName=PART_ToggleButton}" ????????IsOpen="{Binding?IsDropDownOpen,RelativeSource={RelativeSource?TemplatedParent},Mode=TwoWay}" ????????Placement="Bottom"?StaysOpen="False"> ????????????????????????????<controls:SmallPanel?x:Name="PART_DropDown" ??????????MinWidth="{TemplateBinding?FrameworkElement.ActualWidth}" ????????Margin="24,2,24,24" ????????MaxHeight="{TemplateBinding?MaxDropDownHeight}" ????????RenderTransformOrigin=".5,0" ????????SnapsToDevicePixels="True"> ????????????????????????????????<controls:SmallPanel.RenderTransform> ?????????<ScaleTransform?ScaleY="0"/> ????????</controls:SmallPanel.RenderTransform> ????????<Border ?????????Name="PART_DropDownBorder" ?????????Background="{TemplateBinding?Background}" ?????????BorderBrush="{TemplateBinding?BorderBrush}" ?????????BorderThickness="{TemplateBinding?BorderThickness}" ?????????SnapsToDevicePixels="True" ?????????????????????????????????CornerRadius="{Binding?Path=(helpers:ElementHelper.CornerRadius),RelativeSource={RelativeSource?TemplatedParent}}" ?????????UseLayoutRounding="True" ?????????Effect="{StaticResource?PopupShadowDepth}"/> ????????<Grid?ClipToBounds="False" ???????????Margin="0,8"?> ?????????<Grid.RowDefinitions> ??????????<RowDefinition?Height="Auto"/> ????????????????????????????????????????<RowDefinition?Height="Auto"/> ??????????<RowDefinition/> ?????????</Grid.RowDefinitions> ????????????????????????????????????<TextBox?x:Name="PART_TextBox" ?????????????????????????????????????????????Margin="6,0" ?????????????????????????????????????????????helpers:ElementHelper.Watermark="{Binding?SearchWatermark,RelativeSource={RelativeSource?TemplatedParent}}"/> ????????????????????????????????????<CheckBox?x:Name="PART_SelectAll" ??????????????????????????????????????????????Grid.Row="1" ??????????????????????????????????????????????Margin="5,4" ??????????????????????????????????????????????Visibility="{TemplateBinding?IsSelectAllActive,Converter={StaticResource?bool2VisibilityConverter}}" ??????????????????????????????????????????????Content="{TemplateBinding?SelectAllContent}"/> ????????????????????????????????????<controls:MultiSelectListBox?x:Name="PART_Selector" ?????????????????????????????????????????????Grid.Row="2" ?????????????????????????????????????????????BorderThickness="1,0,1,0" ?????????????????????????????????????????????DisplayMemberPath="{TemplateBinding?DisplayMemberPath}" ?????????????????????????????????????????????SelectedValuePath="{TemplateBinding?SelectedValuePath}" ?????????????????????????????????????????????MinHeight="{TemplateBinding?MinHeight}" ????????????ItemsSource="{TemplateBinding?ItemsSource}" ?????????????????????????????????????????????SelectionMode="Multiple" ?????????????????????????????????????????????VerticalContentAlignment="{TemplateBinding?VerticalContentAlignment}" ?????????????????????????????????????????????HorizontalContentAlignment="{TemplateBinding?HorizontalContentAlignment}" ?????????????????????????????????????????????ItemContainerStyle="{StaticResource?DefaultMultiSelectComboBoxItem}" ?????????????????????????????????????????????ScrollViewer.HorizontalScrollBarVisibility="{Binding?ScrollViewer.HorizontalScrollBarVisibility,?RelativeSource={RelativeSource?TemplatedParent}}" ?????????????????????????????????????????????ScrollViewer.CanContentScroll="{Binding?ScrollViewer.CanContentScroll,?RelativeSource={RelativeSource?TemplatedParent}}" ?????????????????????????????????????????????BorderBrush="{TemplateBinding?BorderBrush}"> ????????????????????????????????????</controls:MultiSelectListBox> ????????????????????????????????????<controls:MultiSelectListBox?x:Name="PART_SearchSelector" ?????????????????????????????????????????????Grid.Row="2" ?????????????????????????????????????????????BorderThickness="1,0,1,0" ?????????????????????????????????????????????BorderBrush="{TemplateBinding?BorderBrush}" ?????????????????????????????????????????????DisplayMemberPath="{TemplateBinding?DisplayMemberPath}" ?????????????????????????????????????????????SelectedValuePath="{TemplateBinding?SelectedValuePath}" ?????????????????????????????????????????????MinHeight="{TemplateBinding?MinHeight}" ????????????ItemsSource="{TemplateBinding?ItemsSourceSearch}" ?????????????????????????????????????????????SelectionMode="Multiple" ?????????????????????????????????????????????VerticalContentAlignment="{TemplateBinding?VerticalContentAlignment}" ?????????????????????????????????????????????HorizontalContentAlignment="{TemplateBinding?HorizontalContentAlignment}" ?????????????????????????????????????????????ItemContainerStyle="{StaticResource?DefaultMultiSelectComboBoxItem}" ?????????????????????????????????????????????ScrollViewer.HorizontalScrollBarVisibility="{Binding?ScrollViewer.HorizontalScrollBarVisibility,?RelativeSource={RelativeSource?TemplatedParent}}" ?????????????????????????????????????????????ScrollViewer.CanContentScroll="{Binding?ScrollViewer.CanContentScroll,?RelativeSource={RelativeSource?TemplatedParent}}" ?????????????????????????????????????????????Visibility="Collapsed"> ????????????????????????????????????</controls:MultiSelectListBox> ????????????????????????????????</Grid> ???????</controls:SmallPanel> ??????</Popup> ?????</controls:SmallPanel> ?????<ControlTemplate.Triggers> ??????<Trigger?SourceName="PART_ToggleButton"?Property="IsChecked"?Value="True"> ???????<Trigger.EnterActions> ????????<BeginStoryboard?x:Name="BeginStoryboardOpenStoryboard"?Storyboard="{StaticResource?OpenStoryboard}"?/> ???????</Trigger.EnterActions> ???????<Trigger.ExitActions> ????????<StopStoryboard?BeginStoryboardName="BeginStoryboardOpenStoryboard"?/> ???????</Trigger.ExitActions> ??????</Trigger> ??????<Trigger?SourceName="PART_ToggleButton"?Property="IsChecked"?Value="False"> ???????<Trigger.EnterActions> ????????<BeginStoryboard?x:Name="BeginStoryboardCloseStoryboard"?Storyboard="{StaticResource?CloseStoryboard}"?/> ???????</Trigger.EnterActions> ???????<Trigger.ExitActions> ????????<StopStoryboard?BeginStoryboardName="BeginStoryboardCloseStoryboard"?/> ???????</Trigger.ExitActions> ??????</Trigger> ??????<Trigger?Property="IsMouseOver"?Value="True"> ????????????????????????????<Setter?Property="BorderBrush"?TargetName="PART_Border"?Value="{DynamicResource?PrimaryNormalSolidColorBrush}"/> ??????</Trigger> ??????<Trigger?SourceName="PART_Popup"?Property="AllowsTransparency"?Value="True"> ???????<Setter?TargetName="PART_DropDownBorder"??Property="Margin"?Value="0,2,0,0"?/> ??????</Trigger> ????????????????????????<Trigger?Property="Text"?Value=""> ????????????????????????????<Setter?Property="Visibility"?TargetName="PART_Watermark"?Value="Visible"/> ????????????????????????</Trigger> ????????????????????????<Trigger?Property="Text"?Value="{x:Null}"> ????????????????????????????<Setter?Property="Visibility"?TargetName="PART_Watermark"?Value="Visible"/> ????????????????????????</Trigger> ?????</ControlTemplate.Triggers> ????</ControlTemplate> ???</Setter.Value> ??</Setter> ?</Style> </ResourceDictionary>
4)创建 MultiSelectSearchComboBoxExample.xaml
代码如下:
?<Grid> ????????????<Grid.RowDefinitions> ????????????????<RowDefinition?Height="Auto"/> ????????????????<RowDefinition/> ????????????</Grid.RowDefinitions> ????????????<Button?Content="获取选中"? ????????????????????VerticalAlignment="Bottom" ????????????????????HorizontalAlignment="Center" ????????????????????Click="Button_Click" ????????????????????Margin="0,20,0,0" ????????????????????Style="{StaticResource?SuccessPrimaryButton}"/> ????????????<UniformGrid?Columns="2"?Rows="2"?Grid.Row="1"> ????????????????<wd:MultiSelectionSearchComboBox ????????????????VerticalContentAlignment="Center"? ????????????????HorizontalAlignment="Center" ????????????????????ItemsSource="{Binding?Drawings}"? ????????????????DisplayMemberPath="Number" ????????????????SelectedValuePath="Index" ????????????????Width="200"?Delimiter="," ????????????????IsSelectAllActive="True"> ????????????????????<wd:MultiSelectionSearchComboBox.DataContext> ????????????????????????<vm:DrawingExampleVM/> ????????????????????</wd:MultiSelectionSearchComboBox.DataContext> ????????????????</wd:MultiSelectionSearchComboBox> ????????????????<wd:MultiSelectionSearchComboBox ????????????????????Name="MyMultiSelectionSearchComboBox2" ????????????????VerticalContentAlignment="Center"? ????????????????HorizontalAlignment="Center" ????????????????ItemsSource="{Binding?Drawings}"? ????????????????DisplayMemberPath="Number" ????????????????SelectedValuePath="Index" ????????????????Width="200"?Delimiter="^" ????????????????IsSelectAllActive="True" ????????????????wd:ElementHelper.Watermark="MultiSelectionSearchComboBox" ????????????????SearchWatermark="请输入搜索内容"> ????????????????????<wd:MultiSelectionSearchComboBox.DataContext> ????????????????????????<vm:DrawingExampleVM/> ????????????????????</wd:MultiSelectionSearchComboBox.DataContext> ????????????????</wd:MultiSelectionSearchComboBox> ????????????</UniformGrid> ????????</Grid>
5)创建 MultiSelectSearchComboBoxExample.xaml.cs
代码如下:
using?System.Windows; using?System.Windows.Controls; namespace?WPFDevelopers.Samples.ExampleViews { ????///?<summary> ????///?MultiSelectComboBoxExample.xaml?的交互逻辑 ????///?</summary> ????public?partial?class?MultiSelectSearchComboBoxExample?:?UserControl ????{ ????????public?MultiSelectSearchComboBoxExample() ????????{ ????????????InitializeComponent(); ????????} ????????private?void?Button_Click(object?sender,?System.Windows.RoutedEventArgs?e) ????????{ ????????????WPFDevelopers.Controls.MessageBox.Show($"{MyMultiSelectionSearchComboBox2.Text}?\r\n总共选中:{MyMultiSelectionSearchComboBox2.SelectedItems.Count}?条","选中内容",MessageBoxButton.OK,MessageBoxImage.Information);?????? ????????} ????} }
效果图
以上就是基于WPF实现筛选下拉多选控件的详细内容,更多关于WPF筛选下拉多选控件的资料请关注程序员之家其它相关文章!
相关文章
C#中sqlDataRead 的三种方式遍历读取各个字段数值的方法
这篇文章主要介绍了C#中 sqlDataRead 的三种方式遍历读取各个字段数值的方法,每种方法给大家介绍的都非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下2018-09-09DataGridView冻结列或行、列顺序调整、操作行头列头标题的方法
这篇文章介绍了DataGridView冻结列或行、列顺序调整、操作行头列头标题的方法,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2022-02-02
最新评论