• 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

    TreeViewItem添加MouseOver/Hover效果:

    当有HierarchicalDataTemplate时,下级Item的MouseOver状态Trigger设置,可以通过里面的元素直接设置。

    <Trigger SourceName="Bd" Property="IsMouseOver" Value="True">
      <Setter TargetName="Bd" Property="Background" Value="{DynamicResource Brush.Highlight}"/>
    </Trigger>

    因为TreeViewItem的MouseOver关联的是整个TreeViewItem和其下级的状态。。

  • 相关阅读:
    python的编码判断_unicode_gbk/gb2312_utf8(附函数)
    stat文件状态信息结构体
    内核配置中 ramdisk 大小修改
    mount命令详解
    dirent和DIR 结构体 表示文件夹中目录内容信息
    nandwrite 参数
    mke2fs 制作ext2文件系统image
    ext2文件系统错误
    照度/感光度(Lux)
    摄像机的几个重要的技术指标
  • 原文地址:https://www.cnblogs.com/kybs0/p/5837928.html
Copyright © 2020-2023  润新知