Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/258.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# HierarchycalDataTemplate不同的叶子_C#_Wpf_Hierarchicaldatatemplate - Fatal编程技术网

C# HierarchycalDataTemplate不同的叶子

C# HierarchycalDataTemplate不同的叶子,c#,wpf,hierarchicaldatatemplate,C#,Wpf,Hierarchicaldatatemplate,我有一组结构如下的数据: ItemA.GroupA ItemB.GroupA ItemC.GroupB ItemD.GroupC 我需要在WPF树视图中显示数据,如下所示: ItemA.GroupA ItemB.GroupA ItemC.GroupB ItemD.GroupC GroupA ---项目a ---项目B B组 ---项目C C组 ---项目 我可以使用什么XAML按不同的值对叶子进行分组?例如,集合中可能有多个项目是GroupA.ItemA,但是,我只想显示一次

我有一组结构如下的数据:

 ItemA.GroupA
 ItemB.GroupA
 ItemC.GroupB
 ItemD.GroupC
我需要在WPF树视图中显示数据,如下所示:

 ItemA.GroupA
 ItemB.GroupA
 ItemC.GroupB
 ItemD.GroupC
GroupA

---项目a

---项目B

B组

---项目C

C组

---项目


我可以使用什么XAML按不同的值对叶子进行分组?例如,集合中可能有多个项目是GroupA.ItemA,但是,我只想显示一次节点和叶。

您不能在XAML中这样做,至少不能以任何自然方式。更好的方法是引入一个视图模型——一个以视图友好的方式表示数据的类,这样可以使XAML保持简单和自然

因此,在您的情况下,您将拥有一个类来包装您的ItemX集合,并公开组及其不同的成员:

public class MyItemsViewModel
{
  public IList<MyGroupViewModel> Groups { get; }
}

public class MyGroupViewModel
{
  public string GroupName { get; }
  public IList<MyItem> DistinctItems { get; }
}
公共类MyItemsViewModel
{
公共IList组{get;}
}
公共类MyGroupViewModel
{
公共字符串组名{get;}
公共IList区分项{get;}
}

然后,您的HierarchycalDataTemplate将几乎自动脱落。另一个好处是,因为视图模型类只是数据对象,所以可以对它们进行自动测试,而复杂的XAML需要手动测试。

我不同意itowlson的观点。这不是一个棘手的问题,
hierarchycaldatatemplate
就是为这种事情而设计的。在你随意潜入模式和查看模型和其他不必要的混淆之前,请考虑你的问题可以用两个类来解决,一个是“强> LINQ<代码> GROPbB/<代码>语句。

以下是您的课程:

public class GroupItem
{
    public string Name
    {
        get;
        private set;
    }

    public string Group
    {
        get;
        private set;
    }

    public GroupItem(string name, string group)
    {
        Name = name;
        Group = group;
    }
}

public class Group
{
    public IEnumerable<GroupItem> Children
    {
        get;
        set;
    }

    public string Name
    {
        get;
        private set;
    }

    public Group(string name)
    {
        Name = name;
    }
}
再一次,这是所有的样板,除了分组行。该声明值得进一步调查。这将根据项目集合的
group
属性对其进行分组。项目分组后,您将创建
组的新实例。传入组的name属性(这是键),并将子项设置为组本身,然后ta da

最后,这里是
窗口
的XAML,它使用
层次数据模板

<Window x:Class="TestWpfApplication.DistinctLeaves"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="DistinctLeaves" Height="300" Width="300"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Grid>
    <TreeView ItemsSource="{Binding Groups}">
        <TreeView.ItemTemplate>
            <HierarchicalDataTemplate ItemsSource="{Binding Children}">
                <TextBlock Text="{Binding Name}"/>
            </HierarchicalDataTemplate>
        </TreeView.ItemTemplate>
    </TreeView>
</Grid>

结果如下:


虽然这在技术上并没有错——他确实应该已经为这类事情定义了一个视图模型类——但我认为这没有抓住问题的关键。他不是问他应该如何将代码修改为MVVM正确,而是问他如何组织现有数据来表示不同的组。查理:我实际上认为我们基本上是一致的——也许我的回答措词不当,但我们都认为HierarchycalDataTemplate是正确的解决方案,只要数据结构正确,使用起来就非常简单。我用“视图模型”这个术语来表示视图友好的数据结构,您考虑混淆,但是我们提出的数据结构是相同的,并且我同意您对该结构的实现。区别在于术语,而不是实践:如果我使用的术语“视图模型”看起来很重或很吓人,我很抱歉。使用
ItemsSource=“{Binding Children}”
不会在运行时抛出绑定异常,因为叶视图模型不具有这样的属性吗?可能是的,但正是由于这个原因,绑定失败了。性能影响可以忽略不计,因为此绑定解析在每个组中只发生一次。如果这是不可接受的,则可以将Children属性添加到叶视图模型并创建空列表。