Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.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# 使用MVVM中的自定义ItemTemplate将对象列表绑定到ItemsControl 当前设置_C#_Wpf_Data Binding_Grouping_Itemscontrol - Fatal编程技术网

C# 使用MVVM中的自定义ItemTemplate将对象列表绑定到ItemsControl 当前设置

C# 使用MVVM中的自定义ItemTemplate将对象列表绑定到ItemsControl 当前设置,c#,wpf,data-binding,grouping,itemscontrol,C#,Wpf,Data Binding,Grouping,Itemscontrol,我有一个自定义类,表示安装程序文件和该文件的一些属性,符合以下接口 public interface IInstallerObject { string FileName { get; set; } string FileExtension { get; set; } string Path { get; set; } int Build { get; set; } ProductType ProductType { get; set; } Arc

我有一个自定义类,表示安装程序文件和该文件的一些属性,符合以下接口

public interface IInstallerObject
{
    string FileName { get; set; }
    string FileExtension { get; set; }
    string Path { get; set; }
    int Build { get; set; }
    ProductType ProductType { get; set; }
    Architecture ArchType { get; set; }
    bool Configurable { get; set; }
    int AverageInstallTime { get; set; }
    bool IsSelected { get; set; }
}
我的
ViewModel
有一个名为
AvailableInstallerObjects
ReadOnlyObservableCollection
属性

我的
视图
有一个
GroupBox
,其中包含绑定到上述属性的
ItemsControl

    <GroupBox Header="Products">
        <ItemsControl ItemsSource="{Binding Path=AvailableInstallerObjects}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <CheckBox IsChecked="{Binding Path=IsSelected}"
                                  VerticalAlignment="Center" Margin="5"/>
                        <TextBlock Text="{Binding Path=FileName}" Margin="5" />
                    </StackPanel>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </GroupBox>
基本上,我希望能够通过
ProductType
属性进行分组,显示可用产品的列表,使用
ComboBox
表示
ProductType
IInstallerObject
的可用
Build
属性值

我可以在
ViewModel
中使用
LINQ
提取分组,但我不知道如何绑定到提取的分组

我的研究还发现了使用
CollectionViewSource
的可能性,但我不确定如何将其应用到当前设置中


我提前感谢你的帮助。我愿意学习,所以如果我忽略了一些明显的东西,请告诉我这些信息,我会很乐意自学。

如果构建应该是集合类型

因此,您的类应该以这样的结构为例

Public Class Customer
 Public Property FirstName as string
Public Property LastName as string
Public Property CustomerOrders as observableCollection(OF Orders)
End Class
这会给你预期的结果。主项目演示者中的每个项目都将显示绑定到客户订单的名字、姓氏和组合框。
我知道这很简单,但这应该可以做到。

您所要做的就是在视图中声明一个
CollectionViewSource
,并将其绑定到
ObservableCollection
。在这个对象中,您可以声明一个或多个
GroupDescriptions
,这将把源代码分成几个组

将此源绑定到列表框,为组描述创建模板,就完成了


可以在此处找到一个示例:。有关CollectionViewSource的更多信息,请参见此处:

对您的问题的描述使我相信您正在寻找某种协作/扩展/分组/树状视图之类的东西

树视图的XAML

<Window x:Class="WPFLab12.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:loc="clr-namespace:WPFLab12"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
      <GroupBox Header="Products">
        <TreeView ItemsSource="{Binding Path=ProductTypes}">
            <TreeView.Resources>
                <HierarchicalDataTemplate 
                    DataType="{x:Type loc:ProductType}"
                    ItemsSource="{Binding AvailableInstallerObjects}">
                    <TextBlock Text="{Binding Description}" />
                </HierarchicalDataTemplate>
                <HierarchicalDataTemplate DataType="{x:Type loc:InstallerObject}">
                    <StackPanel Orientation="Horizontal">
                        <CheckBox IsChecked="{Binding Path=IsSelected}" 
                                  VerticalAlignment="Center" Margin="5"/>
                        <TextBlock Text="{Binding Path=FileName}" Margin="5" />
                    </StackPanel>
                </HierarchicalDataTemplate>
            </TreeView.Resources>
        </TreeView>
      </GroupBox>
    </Grid>
</Window>
不过,这完全是欺骗——通常,
MainWindow.cs
不会用作DataContext并包含所有这些内容。但是对于这个例子,我只是让它列出
ProductType
s,并用
InstallerObject
实例填充每个
ProductType

我使用的类,注意我做了一些假设并修改了您的类以更好地适应此视图模型:

public class InstallerObject
{
    public string FileName { get; set; }
    public string FileExtension { get; set; }
    public string Path { get; set; }
    public int Build { get; set; }
    public bool Configurable { get; set; }
    public int AverageInstallTime { get; set; }
    public bool IsSelected { get; set; }
}

public class ProductType
{
    public string Description { get; set; }
    public ReadOnlyObservableCollection<InstallerObject> AvailableInstallerObjects
    {
        get;
        set; 
    }
    public override string ToString()
    {
        return this.Description;
    }
}
公共类InstallerObject
{
公共字符串文件名{get;set;}
公共字符串文件扩展名{get;set;}
公共字符串路径{get;set;}
公共int生成{get;set;}
公共bool可配置{get;set;}
public int average安装时间{get;set;}
公共布尔值被选为{get;set;}
}
公共类ProductType
{
公共字符串说明{get;set;}
公共ReadOnlyObservableCollection可用安装对象
{
得到;
设置
}
公共重写字符串ToString()
{
返回此。说明;
}
}
因此,在MVVM中,在我看来,您当前的
InstallerObject
类更像是一种模型层。您可能会考虑将视图模型中的集合转换为更易于在视图中管理的集合类。ViewModel中的思想是对事物建模,类似于它们将如何被查看和交互。将安装对象的平面列表转换为新的分层数据集合,以便更轻松地绑定到视图

有关使用和自定义TreeView的各种方法的更多信息:

public partial class MainWindow : Window
{
    public ReadOnlyObservableCollection<ProductType> ProductTypes
    {
        get { return (ReadOnlyObservableCollection<ProductType>)GetValue(ProductTypesProperty); }
        set { SetValue(ProductTypesProperty, value); }
    }

    // Using a DependencyProperty as the backing store for ProductTypes.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty ProductTypesProperty =
        DependencyProperty.Register("ProductTypes", typeof(ReadOnlyObservableCollection<ProductType>), typeof(MainWindow), new UIPropertyMetadata(null));

    public MainWindow()
    {
        this.InitializeComponent();

        this.ProductTypes = new ReadOnlyObservableCollection<ProductType>(
            new ObservableCollection<ProductType>()
            {
                new ProductType() 
                { 
                    Description = "Type A",
                    AvailableInstallerObjects = new ReadOnlyObservableCollection<InstallerObject>(
                        new ObservableCollection<InstallerObject>()
                        {
                            new InstallerObject() { FileName = "A" },
                            new InstallerObject() { FileName = "B" },
                            new InstallerObject() { FileName = "C" },
                        })
                },

                new ProductType() 
                { 
                    Description = "Type B",
                    AvailableInstallerObjects = new ReadOnlyObservableCollection<InstallerObject>(
                        new ObservableCollection<InstallerObject>()
                        {
                            new InstallerObject() { FileName = "A" },
                            new InstallerObject() { FileName = "D" },
                        })
                }
            });

        this.DataContext = this;
    }
}
public class InstallerObject
{
    public string FileName { get; set; }
    public string FileExtension { get; set; }
    public string Path { get; set; }
    public int Build { get; set; }
    public bool Configurable { get; set; }
    public int AverageInstallTime { get; set; }
    public bool IsSelected { get; set; }
}

public class ProductType
{
    public string Description { get; set; }
    public ReadOnlyObservableCollection<InstallerObject> AvailableInstallerObjects
    {
        get;
        set; 
    }
    public override string ToString()
    {
        return this.Description;
    }
}