WPF将List绑定到TreeView并进行分组

时间:2014-11-27 12:51:20

标签: wpf treeview

我的 ViewModel 中有列表。我想根据属性对此列表对象进行分组,并在Treeview中显示它。

class ProductsViewModel
{
    public List<Product> ProductList;
}

class Product
{
    public string Name;
    public string Category;
    public double Price;
}

在我的WPF窗口中,我需要根据产品类别在 TreeView 中的 ProductList 中显示产品。请指导我。

Category 1
    P1
    P2
Category 2
    P3
    P4
    P5

2 个答案:

答案 0 :(得分:0)

我设法通过使用CollectionViewSource来完成此操作。创建CollectionViewSource并设置组描述。

    <CollectionViewSource Source="{Binding ProductList}"
                          x:Key="Items">
        <CollectionViewSource.GroupDescriptions>
            <PropertyGroupDescription PropertyName="Category" />
        </CollectionViewSource.GroupDescriptions>
    </CollectionViewSource>

我在ListBox上使用GroupStyle来实现分组。但由于您需要树视图UI,我们需要自定义GroupItem的ContainerStyle。将TreeViewItem模板放入容器样式。我实际上从here复制了TreeViewItem的默认模板。

        <ListBox ItemsSource="{Binding Source={StaticResource Items}}"
                  DisplayMemberPath="Name">
        <ItemsControl.GroupStyle>
            <GroupStyle>
                <GroupStyle.HeaderTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Name}" />
                    </DataTemplate>
                </GroupStyle.HeaderTemplate>
                <GroupStyle.ContainerStyle>
                    <Style TargetType="GroupItem">
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate TargetType="GroupItem">
                                    <Grid>
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition MinWidth="19"
                                                              Width="Auto" />
                                            <ColumnDefinition Width="Auto" />
                                            <ColumnDefinition Width="*" />
                                        </Grid.ColumnDefinitions>
                                        <Grid.RowDefinitions>
                                            <RowDefinition Height="Auto" />
                                            <RowDefinition />
                                        </Grid.RowDefinitions>
                                        <ToggleButton x:Name="Expander"
                                                      Style="{StaticResource ExpandCollapseToggleStyle}"
                                                      ClickMode="Press"/>
                                        <Border x:Name="Bd"
                                                Grid.Column="1"
                                                Background="{TemplateBinding Background}"
                                                BorderBrush="{TemplateBinding BorderBrush}"
                                                BorderThickness="{TemplateBinding BorderThickness}"
                                                Padding="{TemplateBinding Padding}">
                                            <TextBlock Text="{Binding Name}"/>
                                        </Border>
                                        <ItemsPresenter x:Name="ItemsHost"
                                                        Grid.Row="1"
                                                        Grid.Column="1"
                                                        Margin="10 0 0 0"
                                                        Grid.ColumnSpan="2"
                                                        Visibility="Collapsed" />
                                    </Grid>
                                    <ControlTemplate.Triggers>
                                        <Trigger Property="IsChecked"
                                                 SourceName="Expander"
                                                 Value="True">
                                            <Setter Property="Visibility"
                                                    TargetName="ItemsHost"
                                                    Value="Visible" />
                                        </Trigger>
                                    </ControlTemplate.Triggers>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </GroupStyle.ContainerStyle>
            </GroupStyle>
        </ItemsControl.GroupStyle>
    </ListBox>

答案 1 :(得分:0)

更改产品&amp; ProductViewModel类带有:

class ProductsViewModel
{
    private List<Product> productList;

    public List<Product> ProductList
    {
        get 
        { return productList; }
        set 
        { productList = value; }
    }
}

class Product
{
    private string name;

    public string Name
    {
        get { return name; }
        set { name = value; }
    }

    private string category;

    public string Category
    {
        get { return category; }
        set { category = value; }
    }

    private double price;

    public double Price
    {
        get { return price; }
        set { price = value; }
    }
}

MainWindow.xaml

<Window x:Class="WpfApplication11.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <TreeView x:Name="treeView" HorizontalAlignment="Left" Height="178" Margin="85,24,0,0" VerticalAlignment="Top" Width="279"/>

    </Grid>
</Window>

MainWindow构造函数:

    public MainWindow()
    {
        ProductsViewModel viewModel = new ProductsViewModel();
        viewModel.ProductList = new List<Product>();
        viewModel.ProductList.Add(new Product() { Name = "ABC", Category ="1", Price = 100 });
        viewModel.ProductList.Add(new Product() { Name = "PQR", Category = "2", Price = 100 });
        viewModel.ProductList.Add(new Product() { Name = "ABC", Category = "3", Price = 100 });
        viewModel.ProductList.Add(new Product() { Name = "XYZ", Category = "2", Price = 100 });

        InitializeComponent();

        var GetCategories = viewModel.ProductList.Select(p => p.Category).Distinct();
        foreach (var item in GetCategories)
        {
            TreeViewItem node = new TreeViewItem() { Header = item };
            treeView.Items.Add(node);
            var products = viewModel.ProductList.Where(p => p.Category == item).Select(p => p.Name).Distinct();
            foreach (var product in products)
            {
                node.Items.Add(product);
            }
        }
    }