有很多项目,都有数据筛选的操作。下面提供一个案例,给大家做参考。
左侧是数据源,搜索框加TreeView控件,右侧是ListBox控件。在左侧数据列点击添加数据,然后点击确定,得到所筛选的数据。
下面直接看代码吧,比较好理解~
筛选控件做成用户控件,当然也可以直接放在主界面,如果不复用的话。数据源都是固定的,实际用的话,新建个ViewModel将数据源绑定就行了。
1、筛选控件界面:
<UserControl x:Class="WpfApplication17.SelectControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:wpfApplication17="clr-namespace:WpfApplication17" mc:Ignorable="d" d:DesignHeight="400" d:DesignWidth="412" Background="LightSkyBlue"> <UserControl.Resources> <ImageBrush x:Key="ImageBrushAddBlue" ImageSource="AddGreen.png">ImageBrush> <ImageBrush x:Key="ImageBrushAddGray" ImageSource="AddGray.png">ImageBrush> <Style x:Key="ScrollBarPageButton" TargetType="{x:Type RepeatButton}"> <Setter Property="SnapsToDevicePixels" Value="True" /> <Setter Property="OverridesDefaultStyle" Value="true" /> <Setter Property="IsTabStop" Value="false" /> <Setter Property="Focusable" Value="false" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type RepeatButton}"> <Border Background="Transparent" /> ControlTemplate> Setter.Value> Setter> Style> <Style x:Key="ScrollBarThumb" TargetType="{x:Type Thumb}"> <Setter Property="SnapsToDevicePixels" Value="True" /> <Setter Property="OverridesDefaultStyle" Value="true" /> <Setter Property="IsTabStop" Value="false" /> <Setter Property="Focusable" Value="false" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type Thumb}"> <Border CornerRadius="2" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1" /> ControlTemplate> Setter.Value> Setter> Style> <ControlTemplate x:Key="VerticalScrollBar" TargetType="{x:Type ScrollBar}"> <Grid> <Border CornerRadius="2" Width="0.5" Background="#FF046BFF" /> <Track x:Name="PART_Track" IsDirectionReversed="true"> <Track.DecreaseRepeatButton> <RepeatButton Style="{StaticResource ScrollBarPageButton}" Command="ScrollBar.PageUpCommand" /> Track.DecreaseRepeatButton> <Track.Thumb> <Thumb Style="{StaticResource ScrollBarThumb}" Margin="4,0,4,0" Background="DodgerBlue">Thumb> Track.Thumb> <Track.IncreaseRepeatButton> <RepeatButton Style="{StaticResource ScrollBarPageButton}" Command="ScrollBar.PageDownCommand" /> Track.IncreaseRepeatButton> Track> Grid> ControlTemplate> <ControlTemplate x:Key="ScrollViewerControlTemplate1" TargetType="{x:Type ScrollViewer}"> <Grid x:Name="Grid" Background="{TemplateBinding Background}"> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> <ColumnDefinition Width="Auto"/> Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="*"/> <RowDefinition Height="Auto"/> Grid.RowDefinitions> <Rectangle x:Name="Corner" Grid.Column="1" Fill="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" Grid.Row="1"/> <ScrollContentPresenter x:Name="PART_ScrollContentPresenter" CanContentScroll="{TemplateBinding CanContentScroll}" CanHorizontallyScroll="False" CanVerticallyScroll="False" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Grid.Column="0" Margin="{TemplateBinding Padding}" Grid.Row="0"/> <ScrollBar x:Name="PART_VerticalScrollBar" AutomationProperties.AutomationId="VerticalScrollBar" Cursor="Arrow" Grid.Column="1" Maximum="{TemplateBinding ScrollableHeight}" Minimum="0" Grid.Row="0" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportHeight}" Template="{StaticResource VerticalScrollBar}"/> <ScrollBar x:Name="PART_HorizontalScrollBar" AutomationProperties.AutomationId="HorizontalScrollBar" Cursor="Arrow" Grid.Column="0" Maximum="{TemplateBinding ScrollableWidth}" Minimum="0" Orientation="Horizontal" Grid.Row="1" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" Value="{Binding HorizontalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportWidth}"/> Grid> ControlTemplate> <DataTemplate x:Key="TreeItemTemplate" DataType="TreeViewItem"> <Grid Margin="50,0,0,0" Height="28"> <Grid.ColumnDefinitions> <ColumnDefinition Width="*">ColumnDefinition> <ColumnDefinition Width="30">ColumnDefinition> Grid.ColumnDefinitions> <TextBlock Text="{Binding Name}" Foreground="White" FontSize="15" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="10,0"/> <Button x:Name="BtnAdd" Grid.Column="1" Background="Transparent" VerticalAlignment="Center" HorizontalAlignment="Center" Click="BtnAdd_OnClick"> <Button.Template> <ControlTemplate TargetType="Button"> <Grid> <Rectangle x:Name="BtnRetangle" Height="20" Width="20" Stroke="Transparent" StrokeThickness="1" VerticalAlignment="Center" HorizontalAlignment="Center"> Rectangle> <ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center" Content="{TemplateBinding Content}">ContentPresenter> Grid> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter TargetName="BtnRetangle" Property="Height" Value="22">Setter> <Setter TargetName="BtnRetangle" Property="Width" Value="22">Setter> Trigger> <DataTrigger Binding="{Binding IsChecked}" Value="true"> <Setter TargetName="BtnRetangle" Property="Fill" Value="{StaticResource ImageBrushAddGray}">Setter> <Setter Property="ToolTip" Value="已添加">Setter> DataTrigger> <DataTrigger Binding="{Binding IsChecked}" Value="false"> <Setter TargetName="BtnRetangle" Property="Fill" Value="{StaticResource ImageBrushAddBlue}">Setter> <Setter Property="ToolTip" Value="添加">Setter> DataTrigger> ControlTemplate.Triggers> ControlTemplate> Button.Template> Button> Grid> DataTemplate> <Style TargetType="TreeViewItem"> <Setter Property="Background" Value="Transparent" /> <Setter Property="IsExpanded" Value="True">Setter> <Setter Property="HeaderTemplate"> <Setter.Value> <HierarchicalDataTemplate ItemsSource="{Binding TreeViewItems,Mode=TwoWay}" ItemTemplate="{StaticResource TreeItemTemplate}"> <StackPanel Orientation="Horizontal" Height="28" VerticalAlignment="Center" HorizontalAlignment="Left"> <Image Source="folder.png" VerticalAlignment="Center" Height="17" Margin="10,0"/> <TextBlock Text="{Binding Name}" Margin="5,0,0,0" FontSize="15" VerticalAlignment="Center" Foreground="White"/> StackPanel> HierarchicalDataTemplate> Setter.Value> Setter> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type TreeViewItem}"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="*" /> Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition /> Grid.RowDefinitions> <VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="SelectionStates"> <VisualState x:Name="Selected"> <Storyboard> <ColorAnimationUsingKeyFrames Storyboard.TargetName="Bd" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" > <EasingColorKeyFrame KeyTime="0" Value="Transparent" /> ColorAnimationUsingKeyFrames> Storyboard> VisualState> <VisualState x:Name="Unselected" /> <VisualState x:Name="SelectedInactive"> <Storyboard> <ColorAnimationUsingKeyFrames Storyboard.TargetName="Bd" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)"> <EasingColorKeyFrame KeyTime="0" Value="Transparent" /> ColorAnimationUsingKeyFrames> Storyboard> VisualState> VisualStateGroup> <VisualStateGroup x:Name="ExpansionStates"> <VisualState x:Name="Expanded"> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="ItemsHost"> <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}" /> ObjectAnimationUsingKeyFrames> Storyboard> VisualState> <VisualState x:Name="Collapsed" /> VisualStateGroup> VisualStateManager.VisualStateGroups> <Border x:Name="Bd" Grid.Column="0" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}"> <ContentPresenter x:Name="PART_Header" ContentSource="Header" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"/> Border> <ItemsPresenter x:Name="ItemsHost" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Visibility="Collapsed" /> Grid> <ControlTemplate.Triggers> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="HasHeader" Value="false" /> <Condition Property="Width" Value="Auto" /> MultiTrigger.Conditions> <Setter TargetName="PART_Header" Property="MinWidth" Value="75" /> MultiTrigger> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="HasHeader" Value="false" /> <Condition Property="Height" Value="Auto" /> MultiTrigger.Conditions> <Setter TargetName="PART_Header" Property="MinHeight" Value="19" /> MultiTrigger> ControlTemplate.Triggers> ControlTemplate> Setter.Value> Setter> Style> <Style x:Key="ItemContainer" TargetType="{x:Type ListBoxItem}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ListBoxItem}"> <Border x:Name="IconBorder" Background="Transparent" CornerRadius="4" BorderThickness="0"> <ContentPresenter /> Border> <ControlTemplate.Triggers> <Trigger Property="IsSelected" Value="true"> <Setter TargetName="IconBorder" Property="BitmapEffect"> <Setter.Value> <OuterGlowBitmapEffect GlowColor="Transparent" GlowSize="5" /> Setter.Value> Setter> Trigger> ControlTemplate.Triggers> ControlTemplate> Setter.Value> Setter> Style> UserControl.Resources> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition>ColumnDefinition> <ColumnDefinition>ColumnDefinition> Grid.ColumnDefinitions> <Grid> <Grid.RowDefinitions> <RowDefinition Height="40">RowDefinition> <RowDefinition >RowDefinition> Grid.RowDefinitions> <wpfApplication17:SearchControl x:Name="BtnSearch" Margin="30,0,10,0" VerticalAlignment="Center" HorizontalAlignment="Left" OnSearch="BtnSearch_OnOnSearch">wpfApplication17:SearchControl> <ScrollViewer Grid.Row="1" Margin="20,0,0,0" Template="{StaticResource ScrollViewerControlTemplate1}" CanContentScroll="True"> <TreeView x:Name="MyTreeView" ScrollViewer.VerticalScrollBarVisibility="Disabled" HorizontalAlignment="Stretch" Background="Transparent" BorderBrush="Transparent">TreeView> ScrollViewer> Grid> <Grid Grid.Column="1"> <Grid.RowDefinitions> <RowDefinition Height="40">RowDefinition> <RowDefinition Height="*">RowDefinition> Grid.RowDefinitions> <TextBlock Text="已选择列表" Foreground="White" FontSize="15" VerticalAlignment="Center" Margin="10">TextBlock> <ListBox x:Name="RightListBox" Grid.Row="1" HorizontalAlignment="Right" Margin="50,0" Background="Transparent" ItemContainerStyle="{StaticResource ItemContainer}" FocusVisualStyle="{x:Null}"> <ListBox.Template> <ControlTemplate> <StackPanel Background="Transparent" IsItemsHost="True">StackPanel> ControlTemplate> ListBox.Template> <ListBox.ItemTemplate> <DataTemplate> <Grid Height="28"> <Grid.ColumnDefinitions> <ColumnDefinition Width="*">ColumnDefinition> <ColumnDefinition Width="40">ColumnDefinition> Grid.ColumnDefinitions> <TextBlock Text="{Binding Name}" Foreground="White" FontSize="15" VerticalAlignment="Center" HorizontalAlignment="Center"/> <Button x:Name="BtnDelete" Grid.Column="1" Background="Transparent" ToolTip="移除" VerticalAlignment="Center" HorizontalAlignment="Center" Click="BtnRemove_OnClick"> <Button.Template> <ControlTemplate TargetType="Button"> <Grid> <Rectangle x:Name="BtnRetangle" Height="17" Width="17" Stroke="Transparent" StrokeThickness="1" VerticalAlignment="Center" HorizontalAlignment="Center"> <Rectangle.Fill> <ImageBrush ImageSource="Delete.png">ImageBrush> Rectangle.Fill> Rectangle> <ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center" Content="{TemplateBinding Content}">ContentPresenter> Grid> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter TargetName="BtnRetangle" Property="Height" Value="19">Setter> <Setter TargetName="BtnRetangle" Property="Width" Value="19">Setter> Trigger> ControlTemplate.Triggers> ControlTemplate> Button.Template> Button> Grid> DataTemplate> ListBox.ItemTemplate> ListBox> Grid> Grid> UserControl>
2、后台:
public partial class SelectControl : UserControl { private ListItemSoure { get; set; } public SelectControl() { InitializeComponent(); ItemSoure = new List () { new TreeViewModel() { Name = "前端设计", TreeViewItems = new List () { new TreeViewModel(){Name = "Html/Css/Js"}, new TreeViewModel(){Name = "WPF"}, new TreeViewModel(){Name = "Winform"}, new TreeViewModel(){Name = "Webform"}, new TreeViewModel(){Name = "U3D"}, } }, new TreeViewModel() { Name = "后台语言", TreeViewItems = new List () { new TreeViewModel(){Name = "C#"}, new TreeViewModel(){Name = "VB.Net"}, new TreeViewModel(){Name = "Java"}, new TreeViewModel(){Name = "PHP"}, new TreeViewModel(){Name = "C"}, new TreeViewModel(){Name = "Python"}, new TreeViewModel(){Name = "C++"}, new TreeViewModel(){Name = "Ruby"}, } },new TreeViewModel() { Name = "数据库", TreeViewItems = new List () { new TreeViewModel(){Name = "SqlServer"}, new TreeViewModel(){Name = "MySql"}, new TreeViewModel(){Name = "Oracle"}, new TreeViewModel(){Name = "SqlLite"}, new TreeViewModel(){Name = "MongoDB"}, new TreeViewModel(){Name = "PLSql"}, } } }; MyTreeView.ItemsSource = ItemSoure; RightListBox.ItemsSource = null; RightListBox.ItemsSource = new List (); } /// /// 选择 /// /// /// private void BtnAdd_OnClick(object sender, RoutedEventArgs e) { Button button = sender as Button; var viewModel = button.DataContext as TreeViewModel; if (!viewModel.IsChecked) { viewModel.IsChecked = true; var selectList = RightListBox.ItemsSource as List ; selectList.Add(viewModel); RightListBox.ItemsSource = null; RightListBox.ItemsSource = selectList; } } /// /// 移除 /// /// /// private void BtnRemove_OnClick(object sender, RoutedEventArgs e) { Button button = sender as Button; var viewModel = button.DataContext as TreeViewModel; viewModel.IsChecked = false; var selectList = RightListBox.ItemsSource as List ; selectList.Remove(viewModel); RightListBox.ItemsSource = null; RightListBox.ItemsSource = selectList; } /// /// 搜索 /// /// /// private void BtnSearch_OnOnSearch(object sender, SearchEventArgs e) { string serachText=e.SearchText; var items=new List (); if (string.IsNullOrWhiteSpace(serachText)) { MyTreeView.ItemsSource = ItemSoure; return; } foreach (var item in ItemSoure) { var childrenItems=item.TreeViewItems.Where(o => o.Name.Contains(serachText)).ToList(); if (childrenItems.Count>0) { var parentItem=new TreeViewModel(){Name = item.Name}; parentItem.TreeViewItems = childrenItems; items.Add(parentItem); } } MyTreeView.ItemsSource = items; } } public class TreeViewModel : INotifyPropertyChanged { public string Name { get; set; } private bool _isChecked = false; public bool IsChecked { get { return _isChecked; } set { _isChecked = value; if (this.PropertyChanged != null) { this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs("IsChecked")); } } } public List TreeViewItems { get; set; } public event PropertyChangedEventHandler PropertyChanged; [NotifyPropertyChangedInvocator] protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChangedEventHandler handler = PropertyChanged; if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); } }
GitHub下载此案例Demo:https://github.com/Kybs0/DataSelectControlDemo
TreeViewItem添加MouseOver/Hover效果:
当有HierarchicalDataTemplate时,下级Item的MouseOver状态Trigger设置,可以通过里面的元素直接设置。
因为TreeViewItem的MouseOver关联的是整个TreeViewItem和其下级的状态。。