0

我遇到了一个问题,我在 ViewModel 中有两个单独的 ObservableCollection。一个列表包含以下对象:

public class TypeCategory {
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
}

另一个列表是:

public class Type {
    public string Name { get; set; }
    public string Description { get; set; }
    public int CategoryId { get; set; }
}

ViewModel 是这样的:

public class TheViewModel {
    public ObservableCollection<TypeCategory > TypeCategories { get; private set; }
    public ObservableCollection<Type> Types { get; private set; }
}

Type是 的子节点,TypeCategory其中与父节点的连接是CategoryId。是否可以通过使用例如多重绑定和转换器来连接两个列表来生成 TreeView ?或者是扩展父类以包含它的子类的唯一解决方案?

4

1 回答 1

1

你可以这样尝试:

使用Dictionary<string,List<string>>which hold's TypeCategory Nameas Key& List<string>which contains Type Namesunder this Category

public class TheViewModel
{
    public ObservableCollection<TypeCategory> TypeCategories { get; set; }
    public ObservableCollection<Type> Types { get; set; }
    public Dictionary<string,List<string>> TreeViewItemSource { get; set; }

    public TheViewModel()
    {
        TypeCategories = new ObservableCollection<TypeCategory>();
        Types = new ObservableCollection<Type>();
        TreeViewItemSource = new Dictionary<string, List<string>>();

        for (int i = 0; i < 10; i++)
        {
            TypeCategories.Add(new TypeCategory() { Id = i, Name = "TypeCategory "+ i, Description = string.Empty });
        }

        for (int i = 0; i < 50; i++)
        {
            Types.Add(new Type() { CategoryId = i / 5, Name = "Type " + i, Description = string.Empty });
        }

        foreach (TypeCategory item in TypeCategories)
        {
            List<string> list = Types.Where(p => p.CategoryId == item.Id).Select(p=>p.Name).ToList<string>();
            TreeViewItemSource.Add(item.Name, list);
        }
    }
}

XAML

<TreeView Name="treeView1" ItemsSource="{Binding TreeViewItemSource}" >
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding Path=Value}">
            <TextBlock FontWeight="Bold" Text="{Binding Path=Key}" />
            <HierarchicalDataTemplate.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding }"/>
                </DataTemplate>
            </HierarchicalDataTemplate.ItemTemplate>
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>

希望这会帮助你。

UPDATE

如果您不想创建字典,则需要MultiBindingHierarchicalDataTemplate's ItemSource.

xmlns:local="clr-namespace:assembly_Name" 
.....
<TreeView Name="treeView1" ItemsSource="{Binding TypeCategories}" Tag="{Binding Types}">
    <TreeView.Resources>
        <local:CategoryItemsConverter x:Key="CategoryItemsConverter"/>
    </TreeView.Resources>
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate >
            <HierarchicalDataTemplate.ItemsSource>
                <MultiBinding Converter="{StaticResource CategoryItemsConverter}">
                    <Binding Path="Tag" ElementName="treeView1"/>
                    <Binding Path="ItemsSource" ElementName="treeView1"/>
                    <Binding Path="Name"/>
                </MultiBinding>
            </HierarchicalDataTemplate.ItemsSource>
            <TextBlock FontWeight="Bold" Text="{Binding Name}" />
            <HierarchicalDataTemplate.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Name}"/>
                </DataTemplate>
            </HierarchicalDataTemplate.ItemTemplate>
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>

类别项目转换器:

public class CategoryItemsConverter : IMultiValueConverter
{
    public object Convert(object[] values, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        ObservableCollection<Type> typesList = values[0] as ObservableCollection<Type>;
        ObservableCollection<TypeCategory> categoryList = values[1] as ObservableCollection<TypeCategory>;
        string currentCategory = values[2] as string;
        if (typesList != null && categoryList != null && !string.IsNullOrEmpty(currentCategory))
        {
            int? categoryId = categoryList.Where(p => p.Name == currentCategory).Select(p=>p.Id).FirstOrDefault();
            if (categoryId.HasValue)
            {
                var a = typesList.Where(p => p.CategoryId == categoryId).ToList<Type>();
                if (a.Any())
                {
                    return a;
                }
            }
        }
        return null;
    }

    public object[] ConvertBack(object value, System.Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
于 2015-01-16T12:19:23.077 回答