TreeView中只在子节点上显示复选框

3

我有一个这样的XML文档。

<?xml version="1.0" encoding="utf-8"?>
<Parameters>
  <Param Name="Father0_0" ID="1">
    <Param0 Name="Father0_1" ID="2">
      <Param1 Name="Father0_2" ID="3">
        <Param2 Name="Child0_0" ID_ch="1"/>
      </Param1>
      <Param1 Name="Father0_3" ID="4">
        <Param2 Name="Father0_4" ID="5">
          <Param3 Name="Child0_3" ID_ch="2"/>
        </Param2>
      </Param1>
    </Param0>
  </Param>
  <Param Name="Father1_0" ID="6">
    <Param0 Name="Child1_0" ID_ch="3" />
  </Param>
  <Param Name="Father2_0" ID="7">
    <Param1 Name="Child2_0" ID_ch="3"/>
  </Param>
 <Param Name="Child3_0" ID_ch="4"/>
</Parameters>

.CS

所以我加载我的XML文件

XmlDataProvider _xml = FindResource("xmldata") as XmlDataProvider;
var xmlDocument = new XmlDocument();
xmlDocument.Load("34.xml");
_xml.Document = xmlDocument;

如果我按照下面的XAML描述这样做,我会在树形视图中的所有项目上得到复选框?

.XAML

<Window.Resources>
 <XmlDataProvider x:Key="xmldata" XPath="Parameters"/>
<!--The same is done for the Param0,Param1,Param2,Param3 changing DataType=""-->
 <HierarchicalDataTemplate DataType="Param" ItemsSource="{Binding XPath= ./*}">
   <StackPanel Orientation="Horizontal">
    <CheckBox Margin="5,0,0,0" Content="{Binding XPath=@Name}" />
   </StackPanel>
 </HierarchicalDataTemplate>
<!-------------------------------->
</Window.Resources>
<Grid>
 <TreeView ItemsSource="{Binding Source={StaticResource xmldata}, XPath=Param}"  />
</Grid>

如何使复选框仅用于子级。
2个回答

2
你可以检查 TreeViewItem 是否没有子项,如果是,则该节点是叶节点,你可以将你的 CheckBox.Visibility 绑定为:
     <HierarchicalDataTemplate DataType="Param" ItemsSource="{Binding XPath= ./*}">
        <StackPanel Orientation="Horizontal">
            <CheckBox Margin="5,0,0,0" Content="{Binding XPath=@Name}" >
                <CheckBox.Style>
                    <Style TargetType="CheckBox">
                        <Setter Property="Visibility" Value="Collapsed"/>
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding Items.Count, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TreeViewItem}}}" Value="0">
                                <Setter Property="Visibility" Value="Visible"/>
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </CheckBox.Style>
            </CheckBox>
        </StackPanel>
    </HierarchicalDataTemplate>

功能正常,但完全隐藏了父级的名称,你需要在 stackPanel 中添加一个文本框。非常感谢。 - undefined

2
定制XML数据的更通用方法是创建自己的数据模板选择器,用于自定义TreeView。
public class ItemTemplateSelector : DataTemplateSelector
{
    public DataTemplate ParentTemplate { get; set; }

    public DataTemplate ChildTemplate { get; set; }

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        var element = item as XElement;
        if (element != null)
        {
            return element.Elements().Any() ? ParentTemplate : ChildTemplate;
        }

        return base.SelectTemplate(item, container);
    }
}

这是如何在XAML中使用它的:
<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication2"
        Title="MainWindow" Height="350" Width="525">

    <Window.Resources>
        <local:ItemTemplateSelector x:Key="ItemTemplateSelectorKey">

            <local:ItemTemplateSelector.ParentTemplate>
                <HierarchicalDataTemplate ItemsSource="{Binding Elements}">
                    <TextBlock Text="{Binding Attribute[Name].Value}"/>
                </HierarchicalDataTemplate>
            </local:ItemTemplateSelector.ParentTemplate>

            <local:ItemTemplateSelector.ChildTemplate>
                <DataTemplate>
                    <CheckBox Content="{Binding Attribute[Name].Value}"/>
                </DataTemplate>
            </local:ItemTemplateSelector.ChildTemplate>

        </local:ItemTemplateSelector>
    </Window.Resources>

    <TreeView ItemsSource="{Binding Root.Elements}"
              ItemTemplateSelector="{StaticResource ItemTemplateSelectorKey}"/>
</Window>

代码后台:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = XDocument.Parse(Properties.Resources.XmlFile);
    }
}

这是结果:

enter image description here

请注意,我使用的是XDocument API而不是XmlDocument API。 更新
ChildTemplate 稍微简化了一下以便更易读,但这会导致内容中的下划线显示有问题(例如,请参见this答案以获得解释)。

完美运行,下划线示例,告诉我当点击复选框时如何获取有关子项和父项的信息。我的意思是从XML标签“名称”,“值”,“ID”中获取。非常感谢。 - undefined
XML不是处理复杂逻辑数据上的好选择。如果你需要像“当复选框被点击时,执行某些操作”这样的代码,则考虑将你的XML转换为视图模型。 - undefined
我已经纠正了上面的XML,当我点击复选框时,需要获取子元素的id和其第一个父元素的id。 - undefined
非常感谢您的帮助,我已经完成了以下操作: 添加如下代码: <CheckBox Content="{Binding Attribute[Name].Value}" Checked="Box1_Checked"/> 并获取数据如下: CheckBox chkSelecttedItem = (CheckBox)sender; var _dc = (XElement)chkSelecttedItem.DataContext; var ID_par = _dc.Parent.Attribute("ID").Value; var ID_ch = _dc.LastAttribute.Value; - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接