自定义WPF TreeSelect,Combox+TreeView

1.功能

1.1 实现功能

效果:
在这里插入图片描述

  • 1、对其中鼠标悬浮、选中的样式进行统一
  • 2、对其中滚动条样式进行全局统一配置
  • 3、对控件的Border Color 进行全局统一配置
  • 4、绑定数据时设置已选中项
  • 5、Popup 宽度根据内容自适应
  • 6、MultiTreeSelect 可设置已选中项展示样式(横向/纵向)

2 TreeSelect

2.1 控件代码
  • XAML 样式
 <ComboBox.Style>
        <Style TargetType="{x:Type ComboBox}">
            <Setter Property="Width" Value="200" />
            <Setter Property="HorizontalContentAlignment" Value="Stretch" />
            <Setter Property="VerticalContentAlignment" Value="Center" />
            <Setter Property="SnapsToDevicePixels" Value="True" />
            <Setter Property="MaxDropDownHeight" Value="200" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ComboBox}">
                        <Grid>
                            <Border SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"  Width="{TemplateBinding Width}" 
                                    Height="{TemplateBinding Height}" BorderBrush="{StaticResource DefaultBrush}" BorderThickness="1">
                                <Grid x:Name="PART_Root">
                                    <Grid x:Name="PART_InnerGrid" Margin="0">
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="*" />
                                            <ColumnDefinition Width="0.3*" MaxWidth="30" />
                                        </Grid.ColumnDefinitions>
                                        <TextBlock Margin="5 5 0 0 " Text="{Binding Path=DisplayText, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ComboBox}}"></TextBlock>
                                        <ToggleButton x:Name="PART_DropDownToggle" IsTabStop="False"  
                                         IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
                                         Grid.Column="1" Template="{StaticResource ComboBoxToggleButton}" />
                                    </Grid>
                                </Grid>
                            </Border>
                            <Popup AllowsTransparency="True"  Focusable="False" StaysOpen="False"
                               IsOpen="{Binding IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}}"
                               PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}" Placement="Bottom">
                                <Grid MinWidth="{Binding ActualWidth, RelativeSource={RelativeSource TemplatedParent}}" MinHeight="100" MaxHeight="{Binding MaxDropDownHeight, RelativeSource={RelativeSource TemplatedParent}}" >
                                    <local:TreeView x:Name="tvItems" Margin="0" SelectedItemChanged="tvItems_SelectedItemChanged" 
                                                    BorderBrush="{StaticResource DefaultBrush}"
                                                    BorderThickness="1" Padding="0 0 12 0" 
                                                    IsExpandedAll="{Binding IsExpandedAll,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}"
                                                    ItemsSource="{Binding Path=ItemsSource, Mode=TwoWay, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ComboBox}}">
                                        <TreeView.ItemTemplate>
                                            <HierarchicalDataTemplate ItemsSource="{Binding Children}">
                                                <StackPanel MinHeight="25" Orientation="Horizontal" Background="Transparent" HorizontalAlignment="Left" >
                                                    <TextBlock Text="{Binding Text}" Margin="3 0" VerticalAlignment="Center" HorizontalAlignment="Left"/>
                                                </StackPanel>
                                            </HierarchicalDataTemplate>
                                        </TreeView.ItemTemplate>
                                    </local:TreeView>
                                </Grid>
                            </Popup>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ComboBox.Style>
2.2 调用代码
  • 页面控件调用
<fcode:TreeSelect x:Name="tsTest" Width="200" MinHeight="30" IsExpandedAll="False"></fcode:TreeSelect>
  • 后台代码
tsTest.ItemsSource = new ObservableCollection<TreeSelectItem>(tree);

3 MultiTreeSelect

3.1 控件代码
  • XAML 样式
<ComboBox.Style>
        <Style TargetType="{x:Type ComboBox}">
            <Setter Property="Width" Value="200" />
            <Setter Property="HorizontalContentAlignment" Value="Stretch" />
            <Setter Property="VerticalContentAlignment" Value="Center" />
            <Setter Property="SnapsToDevicePixels" Value="True" />
            <Setter Property="MaxDropDownHeight" Value="200" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ComboBox}">
                        <Grid>
                            <Border x:Name="Bg" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"  Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" BorderBrush="{StaticResource DefaultBrush}" BorderThickness="1"  >
                                <Grid x:Name="PART_Root">
                                    <Grid x:Name="PART_InnerGrid" Margin="0">
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="*" />
                                            <ColumnDefinition Width="0.3*" MaxWidth="30" />
                                        </Grid.ColumnDefinitions>
                                        <ListBox x:Name="lvSelected" ItemsSource="{Binding Path=SelectedArray, Mode=TwoWay, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ComboBox}}" SelectionMode="Multiple" BorderThickness="0" ScrollViewer.VerticalScrollBarVisibility="Disabled">
                                            <ListBox.ItemsPanel>
                                                <ItemsPanelTemplate>
                                                    <VirtualizingStackPanel Orientation="{Binding Path=SelectedOrientation, Mode=TwoWay, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ComboBox}}" VirtualizingStackPanel.IsVirtualizing="True" />
                                                </ItemsPanelTemplate>
                                            </ListBox.ItemsPanel>
                                            <ListBox.ItemContainerStyle>
                                                <Style TargetType="ListBoxItem">
                                                    <Setter Property="BorderThickness" Value="0"/>
                                                    <Setter Property="IsSelected" Value="True"/>
                                                    <Setter Property="Template">
                                                        <Setter.Value>
                                                            <ControlTemplate TargetType="ListBoxItem">
                                                                <TextBlock Padding="0 5 0 0">
                                                                    <CheckBox BorderThickness="0" Click="chbRemove_Click" VerticalAlignment="Center" HorizontalAlignment="Center" 
                                                                              IsChecked="{Binding IsChecked}" Content="{Binding Text}" >
                                                                    </CheckBox>
                                                                </TextBlock>
                                                            </ControlTemplate>
                                                        </Setter.Value>
                                                    </Setter>
                                                </Style>
                                            </ListBox.ItemContainerStyle>
                                        </ListBox>

                                        <!--下拉按钮-->
                                        <ToggleButton x:Name="PART_DropDownToggle" IsTabStop="False"  
                                         IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
                                         Grid.Column="1" Template="{StaticResource ComboBoxToggleButton}" />
                                    </Grid>
                                </Grid>
                            </Border>
                            <!--弹出多选列表-->
                            <Popup x:Name="PART_Popup" AllowsTransparency="True"  Focusable="False" StaysOpen="False"
                               IsOpen="{Binding IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}}"
                               PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}" Placement="Bottom">
                                <Grid MinWidth="{Binding ActualWidth, RelativeSource={RelativeSource TemplatedParent}}" MinHeight="100" 
                                      MaxHeight="{Binding MaxDropDownHeight, RelativeSource={RelativeSource TemplatedParent}}" >
                                    <local:TreeView x:Name="tvItems" Margin="0" BorderBrush="{StaticResource DefaultBrush}" 
                                                    BorderThickness="1" IsMultiChecked="True" Padding="0 0 12 0"
                                                    IsExpandedAll="{Binding IsExpandedAll,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}"
                                                    ItemsSource="{Binding Path=ItemsSource, Mode=TwoWay, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ComboBox}}">
                                        <TreeView.ItemTemplate>
                                            <HierarchicalDataTemplate ItemsSource="{Binding Children}">
                                                <StackPanel MinHeight="25" Orientation="Horizontal" Background="Transparent" HorizontalAlignment="Left" >
                                                    <CheckBox Margin="3 0" VerticalAlignment="Center" HorizontalAlignment="Left"
                                                              IsChecked="{Binding IsChecked,Mode=TwoWay}" 
                                                              IsEnabled="{Binding IsEnabled}"
                                                              Content="{Binding Text}"
                                                              Click="CheckBox_Click">
                                                    </CheckBox>
                                                </StackPanel>
                                            </HierarchicalDataTemplate>
                                        </TreeView.ItemTemplate>
                                    </local:TreeView>
                                </Grid>
                            </Popup>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ComboBox.Style>
3.2 调用代码
  • 页面控件调用
<fcode:MultiTreeSelect x:Name="mtsTest" Width="200" IsExpandedAll="True"  MinHeight="30"></fcode:MultiTreeSelect>
  • 后台代码
mtsTest.SetSource(new ObservableCollection<TreeSelectItem>(tree));

本文代码资源已上传:
https://download.csdn.net/download/johnson55925/10900504

项目开源地址:
https://gitee.com/fcode_me/FCODE_DEMO

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
WPF(Windows Presentation Foundation)是微软的一种用户界面技术,可用于创建各种Windows应用程序。TreeViewWPF中的一种控件,用于显示层次结构的数据。 当我们需要自定义TreeView时,可以使用WPF提供的各种功能和特性来实现。下面是一些实现自定义TreeView的方法: 1. 自定义树节点的外观:可以使用WPF的样式和模板来修改树节点的外观,例如更改节点的背景颜色、字体样式等。可以使用TreeView控件的ItemTemplate属性来为每个节点定义一个数据模板。 2. 添加功能按钮:可以为TreeView控件添加自己需要的功能按钮,比如展开/折叠按钮、添加/删除节点按钮等。可以使用WPF中的Button控件实现这些按钮,并与TreeView的事件关联。 3. 添加交互行为:可以通过使用WPF提供的命令功能,为TreeView控件添加交互行为。例如,可以为每个节点添加一个命令,当用户双击节点时执行该命令。 4. 实现节点的拖拽和放置:可以通过使用WPF的拖放功能,实现节点的拖拽和放置。可以为每个节点添加一个DragStarted事件,当用户拖动节点时触发该事件,并将节点的数据作为数据对象传递给拖动操作。同时,可以使用TreeViewDropTarget控件作为拖放目标,通过处理Drop事件实现节点的放置。 总的来说,WPF提供了丰富的功能和特性,使我们能够很容易地自定义TreeView控件。通过使用WPF的样式、模板、命令和拖放功能,我们可以实现一个完全符合我们需求的TreeView控件,并为用户提供更好的用户体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值