【问题标题】:wpf TreeView binding having multiple TreeViewItemStylewpf TreeView 绑定具有多个 TreeViewItemStyle
【发布时间】:2021-12-08 01:36:08
【问题描述】:

我可以在 Window1.cs 初始化中使用此代码在 TreeViewItem 内创建 RadioButtions 和 CheckBoxes:

        TreeViewItem parent = createTextInTree("Выпечка", tree);
        createCheckBoxChildren("торт Птичье молоко - 350 звезд", parent);
        createCheckBoxChildren("пироженное Тирамиссу - 25 UAH", parent);
        createCheckBoxChildren("пироженное Тирамиссу - 70 звезд", parent);
        createCheckBoxChildren("тарт Вишня - 35 звезд", parent);


        parent = createTextInTree("Мороженное", tree);
        createRadioButtonsChildren("ванильное - 15 звезд", parent, "grp1");
        createRadioButtonsChildren("шоколадное - 15 звезд", parent, "grp1");
        createRadioButtonsChildren("клубничное - 15 звезд", parent, "grp1");

        parent = createTextInTree("Кофе", tree);
        createRadioButtonsChildren("эспрессо - 30 звезд", parent, "grp2");
        createRadioButtonsChildren("латте - 25 UAH", parent, "grp2");
        createRadioButtonsChildren("латте - 50 звезд", parent, "grp2");
        createRadioButtonsChildren("капучино - 35 звезд", parent, "grp2");

方法有:

    private TreeViewItem createTextInTree(string content, TreeView tree)
    {
        TreeViewItem item = new TreeViewItem()
        {
            Header = content
        };
        tree.Items.Add(item);
        return item;
    }

    private TreeViewItem createCheckBoxInTree(string content, TreeView tree)
    {
        TreeViewItem item = new TreeViewItem()
        {
            Header = new CheckBox()
            {
                Content = content
            }
        };
        tree.Items.Add(item);
        return item;
    }

    private void createCheckBoxChildren(string content, TreeViewItem item)
    {
        TreeViewItem child = new TreeViewItem()
        {
            Header = new CheckBox()
            {
                Content = content,
            }
        };
        item.Items.Add(child);
    }


    private void createRadioButtonsChildren(string content, TreeViewItem item, string group)
    {
        TreeViewItem childRadio = new TreeViewItem()
        {
            Header = new RadioButton()
            {
                Content = content,
                GroupName = group,
            }
        };
        item.Items.Add(childRadio);
    }

控件现在看起来像这样: Control dialog

使用示例:TreeView with Checkboxes 我成功地使用了绑定,以防我只有一个 TreeViewItem 模型,但如果我有多个模型则不行。

这是我当前的 xaml:

  <Style x:Key="TreeViewItemStyle" TargetType="TreeViewItem">
    <Setter Property="IsExpanded" Value="True" />
    <Setter Property="IsSelected" Value="{Binding IsInitiallySelected, Mode=OneTime}" >
    <Setter Property="KeyboardNavigation.AcceptsReturn" Value="True" />
    <Setter Property="dw:VirtualToggleButton.IsVirtualToggleButton" Value="True" />
    <Setter Property="dw:VirtualToggleButton.IsChecked" Value="{Binding IsChecked}" />
    <Setter Property="FontSize" Value="30"/>
  </Style>
        <Style TargetType="{x:Type TreeView}">
            <Style.Resources>
                <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="#CBE8F6" />
                <SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="Black" />
                <SolidColorBrush x:Key="{x:Static SystemColors.ControlTextBrushKey}" Color="Black" />
            </Style.Resources>
        </Style>
        <Style TargetType="{x:Type TreeViewItem}">
            <Setter Property="BorderThickness" Value="1" />
            <Style.Triggers>
                <Trigger Property="IsSelected" Value="True">
                    <Setter Property="BorderBrush" Value="#26A0DA" />
                </Trigger>
                <MultiTrigger>
                    <MultiTrigger.Conditions>
                        <Condition Property="IsSelected" Value="True" />
                        <Condition Property="IsSelectionActive" Value="False" />
                    </MultiTrigger.Conditions>
                    <Setter Property="BorderBrush" Value="#DADADA" />
                </MultiTrigger>
            </Style.Triggers>
        </Style>

      <HierarchicalDataTemplate x:Key="RadioButtonItemTemplate" DataType="{x:Type local:FooViewModel2}" ItemsSource="{Binding Children, Mode=OneTime}">
            <StackPanel Orientation="Horizontal">
                <RadioButton Focusable="False" IsChecked="{Binding IsChecked}" VerticalAlignment="Center" />
                <ContentPresenter Content="{Binding Name, Mode=OneTime}" Height="30" Margin="8,0" />
            </StackPanel>
        </HierarchicalDataTemplate>
        <HierarchicalDataTemplate x:Key="CheckBoxItemTemplate" DataType="{x:Type local:FooViewModel}" ItemsSource="{Binding Children, Mode=OneTime}" >
    <StackPanel Orientation="Horizontal">
      <!-- These elements are bound to a FooViewModel object. -->
      <CheckBox Focusable="False" IsChecked="{Binding IsChecked}" VerticalAlignment="Center" />
      <ContentPresenter Content="{Binding Name, Mode=OneTime}" Height="30" Margin="8,0" />
    </StackPanel>
  </HierarchicalDataTemplate>
</ResourceDictionary>

<DockPanel>
    <TreeView x:Name="tree" Width="450" ItemContainerStyle="{StaticResource TreeViewItemStyle}"  ItemsSource="{Binding Mode=OneTime}"  ItemTemplate="{StaticResource RadioButtonItemTemplate}" />
    <StackPanel Background="White">
        <Button Command="Undo" Content="Uncheck All" HorizontalAlignment="Stretch" Margin="0,2" Padding="8,0"/>
        <Button DockPanel.Dock="Bottom" Content="Ok" HorizontalAlignment="Stretch" Margin="0,2" Padding="8,0"/>
        <Button DockPanel.Dock="Bottom" IsCancel="True" IsDefault="True" Content="Отмена" HorizontalAlignment="Stretch" Margin="0,2" Padding="8,0"/>
        <Label Name="lblTotalBonusesTitle" Content="Всего бонусов" HorizontalAlignment="Center" FontWeight="Bold" Margin="0,2" Padding="1,0" />
        <Label Name="lblTotalBonuses" Content="750" HorizontalAlignment="Center" Margin="0,2" Padding="1,0" />
        <Label Name="lblChosenBonusesTitle" Content="Выбрано" HorizontalAlignment="Center" FontWeight="Bold" Margin="0,2" Padding="1,0" />
        <Label Name="lblChosenBonuses" Content="320" HorizontalAlignment="Center" FontWeight="DemiBold" Margin="0,2" Padding="1,0" />
        <Label Name="lblChosenStrTitle" Content="Выбраны" HorizontalAlignment="Center" FontWeight="Bold" Margin="0,2" Padding="1,0" />
        <Label Name="lblChosenStr" Content="" HorizontalAlignment="Center" FontWeight="DemiBold" Margin="0,2" Padding="1,0" />            
    </StackPanel>
</DockPanel>

【问题讨论】:

  • 这不是一个好主意。您如何手动构建包含许多项目的树?很多重复的代码。您应该将数据模型的集合绑定到 TreeView,然后使用 DataTemplates 和 HierarchicalDataTemplates 为这些项目创建视图。您可以为每种节点类型(RadioButton、CheckBox 等)使用数据模型。在 C# 中执行此操作不会扩展。您应该使用 XAML 和模板。
  • 仅使用数据模型创建树结构。然后 WPF 将根据定义的模板为您创建实际的 TreeViewItem 容器(包括所有控件)。
  • 扩展 TreeView 类也更方便,例如 MultiSelectTreeView,并让它公开一个可以绑定的 SelectedItems 属性。这消除了将每个参与的数据模型都用于 IsSelected 属性的要求。您必须遍历整个树才能收集所选项目(或添加复杂的事件逻辑),而 SelectedItems 属性将简化此过滤并提高性能。此外,SelectedItems 属性会将完整的选择逻辑从数据模型移动到 MultiSelectTreeView 控件。

标签: wpf xaml data-binding treeview


【解决方案1】:

我决定使用DataTemplateSelector。这是一个自定义类,其方法根据您需要的任何标准返回DataTemplate。然后将自定义的DataTemplateSelector 分配给元素:对于ListBox,它是ItemTemplateSelector 属性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-27
    • 2011-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多