基于WPF实现筛选下拉多选控件

 更新时间:2023年04月19日 08:46:44   作者:WPF开发者  
这篇文章主要为大家详细介绍了如何基于WPF实现简单的筛选下拉多选控件,文中的示例代码讲解详细,对我们学习或工作有一定帮助,感兴趣的小伙伴可以了解一下
(福利推荐:【腾讯云】服务器最新限时优惠活动,云服务器1核2G仅99元/年、2核4G仅768元/3年,立即抢购>>>:9i0i.cn/qcloud

(福利推荐:你还在原价购买阿里云服务器?现在阿里云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#实现一阶卡尔曼滤波算法的示例代码

    C#实现一阶卡尔曼滤波算法的示例代码

    这篇文章主要介绍了C#实现一阶卡尔曼滤波算法的示例代码,帮助大家更好的理解和学习使用c#,感兴趣的朋友可以了解下
    2021-04-04
  • Unity Shader实现2D水流效果

    Unity Shader实现2D水流效果

    这篇文章主要为大家详细介绍了Unity Shader实现2D水流效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-05-05
  • C#用委托BeginInvoke做异步线程

    C#用委托BeginInvoke做异步线程

    今天小编就为大家分享一篇关于C#用委托BeginInvoke做异步线程,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01
  • C#实现将像素转换为页面单位的方法

    C#实现将像素转换为页面单位的方法

    这篇文章主要介绍了C#实现将像素转换为页面单位的方法,涉及C#像素转换在图形绘制中的技巧,需要的朋友可以参考下
    2015-06-06
  • C#中sqlDataRead 的三种方式遍历读取各个字段数值的方法

    C#中sqlDataRead 的三种方式遍历读取各个字段数值的方法

    这篇文章主要介绍了C#中 sqlDataRead 的三种方式遍历读取各个字段数值的方法,每种方法给大家介绍的都非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2018-09-09
  • c# WPF实现Windows资源管理器(附源码)

    c# WPF实现Windows资源管理器(附源码)

    这篇文章主要介绍了c# WPF实现Windows资源管理器的示例(附源码),帮助大家更好的理解和学习使用c#,感兴趣的朋友可以了解下
    2021-03-03
  • C#数据库操作类AccessHelper实例

    C#数据库操作类AccessHelper实例

    这篇文章主要介绍了C#数据库操作类AccessHelper实例,可实现针对access数据库的各种常见操作,非常具有实用价值,需要的朋友可以参考下
    2014-10-10
  • C#权限管理和设计浅谈

    C#权限管理和设计浅谈

    权限管理是很多软件中相当重要的一个模块——它的设计的好坏直接影响到软件的安全性、权限管理的可扩展性和易操作性 以及代码中权限判断的复杂程度和效率等方面
    2012-02-02
  • C#实现表格数据转实体的示例代码

    C#实现表格数据转实体的示例代码

    在实际开发过程中,特别是接口对接之类的,对于这种需求是屡见不鲜,现在很多在线平台也都提供了像json转实体、sql转实体等。本文将用C#实现这一功能,需要的可以参考一下
    2022-09-09
  • DataGridView冻结列或行、列顺序调整、操作行头列头标题的方法

    DataGridView冻结列或行、列顺序调整、操作行头列头标题的方法

    这篇文章介绍了DataGridView冻结列或行、列顺序调整、操作行头列头标题的方法,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-02-02

最新评论

?


http://www.vxiaotou.com