【问题标题】:How to visually show multiselect on TreeView in WPF如何在 WPF 中的 TreeView 上直观地显示多选
【发布时间】:2017-07-26 09:38:09
【问题描述】:

我正在尝试启用 TreeView 控件以支持多选。

非常基本的流程有效,如果您在按住 ctrl 或 shift 的同时选择 TreeView 中的多个项目,那么它将成功地将这些项目添加到我在视图模型中的列表中。

问题在于,当实际点击TreeView 项目时,它只会在视觉上选择一项,即只有一项被标记为选中。如何使它突出显示/标记多个项目?我不明白这是在哪里控制的。

TreeViewxaml:

<TreeView x:Name="availableColumnsTreeView" 
              AutomationProperties.AutomationId="availableColumnsTreeView"
              x:Uid="availableColumnsTreeView"           
              SelectedItemChanged="availableColumnsTreeView_SelectedItemChanged"
              ItemsSource="{Binding Path=TreeFieldData, Mode=OneWay, Converter={StaticResource SortingConverter}, ConverterParameter='DisplayName.Text'}"
              ScrollViewer.HorizontalScrollBarVisibility="Auto" 
              ScrollViewer.VerticalScrollBarVisibility="Auto"
              Grid.Row="0">

    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate x:Uid="HierarchicalDataTemplate_1" ItemsSource="{Binding Path=Children, Mode=OneWay, Converter={StaticResource SortingConverter}, ConverterParameter='DisplayName.Text'}">
            <TextBlock x:Uid="TextBlock_1" Text="{Binding DisplayName.Text, Mode=OneWay}" />
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>

所以“availableColumnsTreeView_SelectedItemChanged”调用得很好,但我需要它来实际突出显示选定的项目。

编辑:请在将其标记为重复之前阅读我的问题。我试图尽可能具体地说明我的问题是什么。我不是在寻找隐藏在某个驱动器文档中的多选的完整解决方案。

【问题讨论】:

  • @Fruchtzwerg 我看了一下,然后以另一种方式去做。但现在卡在我的问题中描述的问题
  • “将这些项目添加到列表中” - 您可以使用项目本身的额外属性来存储选择并简单地同步它(您添加的地方),而不是额外的列表/删除项目到这个选择列表)。作为奖励,您可以在数据模板中使用属性来执行某些操作(运行触发器、更改背景等)。
  • @Sinatr 我不确定我是否 100% 关注你。可以举个小例子吗?

标签: c# wpf xaml treeview


【解决方案1】:

如何使它突出显示/标记多个项目?我不明白这是在哪里控制的。

您使用TreeViewItem 样式定义TreeViewItem 容器的外观。如果您向数据对象添加“IsSelected”属性来跟踪当前是否选择了该项目,则可以使用绑定到该项目并提供突出显示的DataTrigger,例如:

<TreeView>
    <TreeView.Resources>
        <Style TargetType="TreeViewItem">
            <Style.Triggers>
                <DataTrigger Binding="{Binding IsSelected}" Value="True">
                    <Setter Property="Background" Value="Yellow" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </TreeView.Resources>
    ...
</TreeView>

确保定义了“IsSelected”属性的数据类实现了INotifyPropertyChanged 接口,并且您在事件处理程序或命令中设置了此属性。

【讨论】:

    【解决方案2】:

    我不确定我是否 100% 关注你。可以举个小例子吗?

    当然。

    这里是 xaml:

    <TreeView ItemsSource="{Binding Items}">
        <TreeView.ItemTemplate>
            <HierarchicalDataTemplate ItemsSource="{Binding Path=Children, Mode=OneWay}">
                <CheckBox Content="{Binding Text, Mode=OneWay}" IsChecked="{Binding IsSelected}">
                    <CheckBox.Style>
                        <Style TargetType="CheckBox">
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding IsSelected}" Value="True">
                                    <DataTrigger.Setters>
                                        <Setter Property="Foreground" Value="Red" />
                                    </DataTrigger.Setters>
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </CheckBox.Style>
                </CheckBox>
            </HierarchicalDataTemplate>
        </TreeView.ItemTemplate>
    </TreeView>
    

    这里是cs:

    public class Item : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
    
        public string Text { get; set; }
        public List<Item> Children { get; set; }
    
        bool _isSelected;
        public bool IsSelected
        {
            get { return _isSelected; }
            set
            {
                _isSelected = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsSelected)));
            }
        }
    
        public Item(string text)
        {
            Text = text;
        }
    }
    
    public partial class MainWindow : Window
    {
        public List<Item> Items { get; set; } = new List<Item>
        {
            new Item("1") { Children = new List<Item>
            {
                new Item("11"),
                new Item("12"),
                new Item("13"),
            }},
            new Item("2") { Children = new List<Item>
            {
                new Item("11"),
                new Item("12"),
                new Item("13"),
            }},
            new Item("3"),
        };
    
        public MainWindow()
        {
            InitializeComponent();
            DataContext = this;
        }
    }
    

    我正在使用CheckBox 来选择项目(不知道你是怎么做的)。如果项目被选中,它的前景会通过数据触发器变为红色。

    如您所见,选择(不管您如何实现它,实际上,我使用的是单选TreeView)作为IsSelected 值存储在项目中。可以遍历分层集合来获取选中项的列表(这叫做flattering)。

    注意:IPropertyChanged,如果您打算从代码隐藏中设置IsSelected,则需要它(例如,按下按钮时选择所有项目)。

    应该很容易适应你的情况。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-02
      • 1970-01-01
      • 2016-05-29
      • 2015-04-23
      • 2012-05-13
      • 1970-01-01
      相关资源
      最近更新 更多