WPF 簡(jiǎn)單實(shí)現(xiàn)下拉篩選控件
?WPF 簡(jiǎn)單實(shí)現(xiàn)下拉篩選控件
控件名:CheckedSearch
作 ? 者:WPFDevelopersOrg - 驚鏵
原文鏈接[1]:https://github.com/WPFDevelopersOrg/WPFDevelopers
框架使用
.NET40
;Visual Studio 2022
;使用 ICollectionView 實(shí)現(xiàn)
篩選
功能,還支持其他如下:使集合具有當(dāng)前
記錄管理
自定義排序
篩選
和分組
功能

1)CheckedSearch.cs
代碼如下:
SearchText
用來(lái)記錄輸入的篩選內(nèi)容Text
用來(lái)記錄展示的所選內(nèi)容^
拼接ItemsSource
數(shù)據(jù)源ContainsFilter
篩選數(shù)據(jù),如果從數(shù)據(jù)源中找到則返回True
using?System.Collections.ObjectModel;
using?System.ComponentModel;
using?System.Linq;
using?System.Windows;
using?System.Windows.Controls;
using?System.Windows.Data;
using?WpfCustomControlLibrary1.Datas;
namespace?WpfCustomControlLibrary1
{
????public?class?CheckedSearch?:?Control
????{
????????private?ICollectionView?_filteredCollection;
????????public?ICollectionView?FilteredCollection?{?get?{?return?_filteredCollection;?}?}
????????private?string?_searchText?=?string.Empty;
????????public?string?SearchText
????????{
????????????get?{?return?_searchText;?}
????????????set
????????????{
????????????????if?(_searchText?!=?value)
????????????????{
????????????????????_searchText?=?value;
????????????????????_filteredCollection.Refresh();
????????????????}
????????????}
????????}
????????public?string?Text
????????{
????????????get?{?return?(string)GetValue(TextProperty);?}
????????????set?{?SetValue(TextProperty,?value);?}
????????}
????????public?static?readonly?DependencyProperty?TextProperty?=
????????????DependencyProperty.Register("Text",?typeof(string),?typeof(CheckedSearch),?new?PropertyMetadata(string.Empty));
????????public?ObservableCollection<CheckedSearchItem>?ItemsSource
????????{
????????????get?{?return?(ObservableCollection<CheckedSearchItem>)GetValue(ItemsSourceProperty);?}
????????????set?{?SetValue(ItemsSourceProperty,?value);?}
????????}
????????public?static?readonly?DependencyProperty?ItemsSourceProperty?=
????????????DependencyProperty.Register("ItemsSource",?typeof(ObservableCollection<CheckedSearchItem>),?typeof(CheckedSearch),?new?PropertyMetadata(null,?OnItemsSourceChanged));
????????private?static?void?OnItemsSourceChanged(DependencyObject?d,?DependencyPropertyChangedEventArgs?e)
????????{
????????????var?choseSearch?=?(CheckedSearch)d;
????????????if?(choseSearch?==?null)?return;
????????????if?(choseSearch._filteredCollection?==?null?&&?choseSearch.ItemsSource.Count?>?0)
????????????{
????????????????foreach?(var?item?in?choseSearch.ItemsSource)
????????????????{
????????????????????item.PropertyChanged?-=?choseSearch.Item_PropertyChanged;
????????????????????item.PropertyChanged?+=?choseSearch.Item_PropertyChanged;
????????????????}
????????????????choseSearch._filteredCollection?=?CollectionViewSource.GetDefaultView(choseSearch.ItemsSource);
????????????????choseSearch._filteredCollection.Filter?=?choseSearch.ContainsFilter;
????????????}
????????}
????????string?GetItems()
????????{
????????????var?list?=?ItemsSource.Where(x=>x.IsChecked).Select(x=>x.Name).ToList();
????????????var?visibleItems?=?string.Join("^",list);
????????????return?visibleItems;
????????}
????????static?CheckedSearch()
????????{
????????????DefaultStyleKeyProperty.OverrideMetadata(typeof(CheckedSearch),?new?FrameworkPropertyMetadata(typeof(CheckedSearch)));
????????}
????????private?void?Item_PropertyChanged(object?sender,?PropertyChangedEventArgs?e)
????????{
????????????if?(e.PropertyName?==?"IsChecked")
????????????????Text?=?GetItems();
????????????
????????}
????????private?bool?ContainsFilter(object?item)
????????{
????????????var?model?=?item?as?CheckedSearchItem;
????????????if?(model?==?null)
????????????????return?false;
????????????if?(string.IsNullOrEmpty(SearchText))
????????????????return?true;
????????????if?(model.Name.ToUpperInvariant().Contains(SearchText.ToUpperInvariant()))
????????????????return?true;
????????????return?false;
????????}
????}
}
2)CheckedSearchItem.cs
代碼如下:
IsChecked
記錄是否選中Name
展示的名稱
using?System.ComponentModel;
namespace?WpfCustomControlLibrary1.Datas
{
????public?class?CheckedSearchItem
????{
????????public?string?Name?{?get;?set;?}
????????private?bool?_isChecked;
????????public?bool?IsChecked
????????{
????????????get?{?return?_isChecked;?}
????????????set
????????????{
????????????????_isChecked?=?value;
????????????????OnPropertyChanged("IsChecked");
????????????}
????????}
????????
????????public?event?PropertyChangedEventHandler?PropertyChanged;
????????protected?void?OnPropertyChanged(string?propertyName)
????????{
????????????if?(PropertyChanged?!=?null)
????????????????PropertyChanged(this,?new?PropertyChangedEventArgs(propertyName));
????????}
????}
}
3)CheckedSearch.xaml
代碼如下:
<Style?TargetType="{x:Type?local:CheckedSearch}">
????????<Setter?Property="Height"?Value="40"/>
????????<Setter?Property="Width"?Value="200"/>
????????<Setter?Property="BorderBrush"?Value="DodgerBlue"/>
????????<Setter?Property="Background"?Value="White"/>
????????<Setter?Property="BorderThickness"?Value="1"/>
????????<Setter?Property="Template">
????????????<Setter.Value>
????????????????<ControlTemplate?TargetType="{x:Type?local:CheckedSearch}">
????????????????????<Border?Background="{TemplateBinding?Background}"
????????????????????????????BorderBrush="{TemplateBinding?BorderBrush}"
????????????????????????????BorderThickness="{TemplateBinding?BorderThickness}"
????????????????????????????x:Name="PART_Border">
????????????????????????<Grid>
????????????????????????????<Grid.ColumnDefinitions>
????????????????????????????????<ColumnDefinition/>
????????????????????????????????<ColumnDefinition?Width="Auto"/>
????????????????????????????</Grid.ColumnDefinitions>
????????????????????????????<TextBlock?Text="{Binding?Text,RelativeSource={RelativeSource?TemplatedParent},Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
???????????????????????????????????????Foreground="Black"
???????????????????????????????????????VerticalAlignment="Center"
???????????????????????????????????????Margin="2,0"/>
????????????????????????????<ToggleButton?x:Name="PART_ToggleButton"?
???????????Focusable="False"
??????????????????????????????????????Width="30"
??????????????????????????????????????Style="{x:Null}"
??????????????????????????????????????Grid.Column="1"
???????????ClickMode="Release">
????????????????????????????????<Path?Stretch="Fill"?
??????????????????????????????????????Height="6"?Width="10"??
??????????????????????????????????????HorizontalAlignment="Center"?
??????????????????????????????????????VerticalAlignment="Center"?
??????????????????Data="M998?352c0?-8?-4?-17?-10?-23l-50?-50c-6?-6?-14?-10?-23?-10c-8?0?-17?4?-23?10l-393?393l-393?-393c-6?-6?-15?-10?-23?-10s-17?4?-23?10l-50?50c-6?6?-10?15?-10?23s4?17?10?23l466?466c6?6?15?10?23?10s17?-4?23?-10l466?-466c6?-6?10?-15?10?-23z"?
??????????????????????????????????????Fill="Black">
????????????????????????????????</Path>
????????????????????????????</ToggleButton>
????????????????????????????<Popup?IsOpen="{Binding?ElementName=PART_ToggleButton,Path=IsChecked}"
???????????????????????????????????x:Name="PART_Popup"
???????????????????????????????????VerticalOffset="2"
???????????????????????????????????AllowsTransparency="True"
????????PlacementTarget="{Binding?ElementName=PART_Border}"
????????Placement="Bottom"?StaysOpen="False">
????????????????????????????????<Border?Width="{TemplateBinding?Width}"
????????????????????????????????????????Padding="2,4"
????????????????????????????????????????Background="{TemplateBinding?Background}"
????????????????????????????BorderBrush="{TemplateBinding?BorderBrush}"
????????????????????????????BorderThickness="{TemplateBinding?BorderThickness}">
????????????????????????????????????<StackPanel>
????????????????????????????????????????<TextBox?Text="{Binding?SearchText,RelativeSource={RelativeSource?TemplatedParent},Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
?????????????????????????????????????????????????Height="40"?VerticalContentAlignment="Center"
?????????????????????????????????????????????????Margin="0,0,0,2"/>
????????????????????????????????????????<ListBox?ItemsSource="{TemplateBinding?ItemsSource}">
????????????????????????????????????????????<ListBox.ItemTemplate>
????????????????????????????????????????????????<DataTemplate>
????????????????????????????????????????????????????<CheckBox?Content="{Binding?Name}"?
??????????????????????????????????????????????????????????????IsChecked="{Binding?IsChecked}"/>
????????????????????????????????????????????????</DataTemplate>
????????????????????????????????????????????</ListBox.ItemTemplate>
????????????????????????????????????????</ListBox>
????????????????????????????????????</StackPanel>
????????????????????????????????</Border>
????????????????????????????????
????????????????????????????</Popup>
????????????????????????</Grid>
????????????????????</Border>
????????????????</ControlTemplate>
????????????</Setter.Value>
????????</Setter>
????</Style>
4)CheckedSearchExample.xaml
示例代碼如下:
<wd:Window?x:Class="WpfApp1.MainWindow"
????????xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
????????xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
????????xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
????????xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
????????xmlns:wd="https://github.com/WPFDevelopersOrg/WPFDevelopers"
????????xmlns:custom="clr-namespace:WpfCustomControlLibrary1;assembly=WpfCustomControlLibrary1"
????????xmlns:local="clr-namespace:WpfApp1"
????????mc:Ignorable="d"?
????????Title="WPFDevelopers?-?搜索多選控件"?Height="450"?Width="800">
??<!--公眾號(hào):WPF開發(fā)者-->
????<Grid>
????????<custom:CheckedSearch?
????????????ItemsSource="{Binding?ItemsSource,RelativeSource={RelativeSource?AncestorType=Window}}"
????????????VerticalAlignment="Top"?Margin="0,10"/>
????</Grid>
</wd:Window>
5)CheckedSearchExample.xaml
數(shù)據(jù)源示例代碼如下:
using?System.Collections.ObjectModel;
using?System.Windows;
using?WpfCustomControlLibrary1.Datas;
namespace?WpfApp1
{
????public?partial?class?MainWindow
????{
????????public?ObservableCollection<CheckedSearchItem>?ItemsSource
????????{
????????????get?{?return?(ObservableCollection<CheckedSearchItem>)GetValue(ItemsSourceProperty);?}
????????????set?{?SetValue(ItemsSourceProperty,?value);?}
????????}
????????public?static?readonly?DependencyProperty?ItemsSourceProperty?=
????????????DependencyProperty.Register("ItemsSource",?typeof(ObservableCollection<CheckedSearchItem>),?typeof(MainWindow),?new?PropertyMetadata(null));
????????public?MainWindow()
????????{
????????????InitializeComponent();
????????????Loaded?+=?MainWindow_Loaded;
????????}
????????private?void?MainWindow_Loaded(object?sender,?RoutedEventArgs?e)
????????{
????????????ItemsSource?=?new?ObservableCollection<CheckedSearchItem>();
????????????var?items?=?new?ObservableCollection<CheckedSearchItem>();
????????????items.Add(new?CheckedSearchItem?{?Name?=?"Winform"?});
????????????items.Add(new?CheckedSearchItem?{?Name?=?"WPF"?});
????????????items.Add(new?CheckedSearchItem?{?Name?=?"WinUI?3"?});
????????????items.Add(new?CheckedSearchItem?{?Name?=?"MAUI"?});
????????????items.Add(new?CheckedSearchItem?{?Name?=?"Avalonia?UI"?});
????????????ItemsSource?=?items;
????????}
????}
}
參考資料
[1]
原文鏈接: https://github.com/WPFDevelopersOrg/WPFDevelopers