WPF:如何将通用数据绑定到TreeView?

时间:2015-04-23 10:26:54

标签: c# wpf binding treeview

我有一个TreeView,我想将一些数据绑定到它;我想为每种类型的数据显示不同的TreeViewItem布局,并查看this example我想出了如何做到这一点。

到目前为止,我有以下几个类:

public class Category
{
    public string Name { get; set; }
    public List<Product> Products { get; set; }
}
public class Product
{
    public string Name { get; set; }
}

现在我需要使用这样的包装器来处理数据:

public class DataWrapper<T> where T : class
{

    public T Data { get; set; }
}

我想在TreeView中为ItemSource设置一个如下所示的列表:

IList<DataWrapper<Category>> list = new List<DataWrapper<Category>>();

Category c = new Category() { Name = "C1", Products = new List<Product>() { new Product() { Name = "P1" }, new Product() { Name = "P2" } } };
list.Add(new DataWrapper<Category>() { Data = c });

c = new Category() { Name = "C2", Products = new List<Product>() { new Product() { Name = "P3" }, new Product() { Name = "P4" } } };
list.Add(new DataWrapper<Category>() { Data = c });

c = new Category() { Name = "C3", Products = new List<Product>() { new Product() { Name = "P5" }, new Product() { Name = "P6" } } };
list.Add(new DataWrapper<Category>() { Data = c });

所以我所做的就是将DataContext设置为treeView:

myTreeView.DataContext =list;

这是xaml:

<TreeView x:Name="myTreeView">
        <TreeView.Resources>
            <HierarchicalDataTemplate DataType="{x:Type src:Category}" ItemsSource="{Binding Path=Data}">
                <StackPanel>
                    <TextBlock Text="Category:" />
                    <TextBlock Text="{Binding Path=Name}" />
                </StackPanel>
            </HierarchicalDataTemplate>
            <HierarchicalDataTemplate DataType="{x:Type src:Product}">
                <StackPanel>
                    <TextBlock Text="Product:" />
                    <TextBlock Text="{Binding Path=Name}" />
                </StackPanel>
            </HierarchicalDataTemplate>
        </TreeView.Resources>
    </TreeView>

但当然它不起作用:) 任何人都可以告诉我如何正确绑定这样的对象列表吗?

谢谢

1 个答案:

答案 0 :(得分:2)

它不起作用的原因是您将ItemsSource绑定到Data DataContext上名为List<DataWrapper<Category>>的属性,该属性类型为Category且没有此属性属性。

我不确定你需要什么包装器。最简单的方法是摆脱包装器,使列表成为项目类型ItemsSource的列表,并将此列表用作IList<Category> list = new List<Category>(); Category c = new Category() { Name = "C1", Products = new List<Product>() { new Product() { Name = "P1" }, new Product() { Name = "P2" } } }; list.Add(c); ... // Set this list as ItemsSource myTreeView.ItemsSource=list;

public class CategoryWrapper
{
    public Category Data { get; set; }
}

这样就可以正确应用数据模板的类型绑定。

或者,如果您需要包装器,只需使包装器非通用:

<HierarchicalDataTemplate DataType="{x:Type src:CategoryWrapper}" ItemsSource="{Binding Path=Data.Products}">
    <StackPanel>
        <TextBlock Text="Category:" />
        <TextBlock Text="{Binding Path=Data.Name}" />
    </StackPanel>
</HierarchicalDataTemplate>

并修改类别模板:

DataType

使其成为非泛型的原因是,将泛型类型指定为模板的<!-- Doesn't work! --> DataType="{x:Type src:DataWrapper<Category>}" 并不容易:

array sortBy {case (k,v) => (-v,k)}

希望这有帮助!让我知道如果这个解决方案在你的情况下不起作用,我会再次看一下......