首页 > 代码库 > WPF 自定义列表筛选 自定义TreeView模板 自定义ListBox模板

WPF 自定义列表筛选 自定义TreeView模板 自定义ListBox模板

有很多项目,都有数据筛选的操作。下面提供一个案例,给大家做参考。

技术分享

左侧是数据源,搜索框加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>
View Code

2、后台:

技术分享
public partial class SelectControl : UserControl    {        private List<TreeViewModel> ItemSoure { get; set; }        public SelectControl()        {            InitializeComponent();            ItemSoure = new List<TreeViewModel>() { new TreeViewModel()                {                    Name = "前端设计",                    TreeViewItems = new List<TreeViewModel>()                    {                        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<TreeViewModel>()                    {                        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<TreeViewModel>()                    {                        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<TreeViewModel>();        }        /// <summary>        /// 选择        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        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<TreeViewModel>;                selectList.Add(viewModel);                RightListBox.ItemsSource = null;                RightListBox.ItemsSource = selectList;            }        }        /// <summary>        /// 移除        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        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<TreeViewModel>;            selectList.Remove(viewModel);            RightListBox.ItemsSource = null;            RightListBox.ItemsSource = selectList;        }        /// <summary>        /// 搜索        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        private void BtnSearch_OnOnSearch(object sender, SearchEventArgs e)        {            string serachText=e.SearchText;            var items=new List<TreeViewModel>();            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<TreeViewModel> 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));        }    }
View Code

 

GitHub下载此案例Demo:https://github.com/Kybs0/DataSelectControlDemo

此案例中图标,推荐个图标下载网站:http://www.easyicon.net/

 

WPF 自定义列表筛选 自定义TreeView模板 自定义ListBox模板