将对象列表绑定到 WPF listviewitem

Binding a list of object to a WPF listviewitem

我在 WPF 项目中有以下 类

public class part
{
    public string number { get; set; }
    public string name { get; set; }
    public List<department> departments { get; set; }
}
public class department
{
    public string name { get; set; }
    public double hours { get; set; }
}

每个部分都包含不同部门的工作时间列表。我想要实现的是在 WPF 列表视图中查看它。我的问题是我没有找到一个很好的例子来说明如何将对象列表绑定到 listviewitem。我在 windows 表单应用程序中有一个类似的案例。我在那里遍历了列表中的对象并通过代码创建了子项。虽然这也可以通过在代码中创建 gridviewcolumns 来实现,但我相信它也应该通过绑定来实现,或者我错了吗?

示例:

public void Test()
    {
       List<part> list_parts = new List<part>();
       List<department> list_departments = new List<department>();

        department d = new department();
        d.name = "Sawing";
        d.hours = 0.3;
        list_departments.Add(d);

        d = new department();
        d.name = "Miling";
        d.hours = 12.3;
        list_departments.Add(d);

        part Test = new part();
        Test.name = "Block";
        Test.number = "123";
        Test.departments = list_departments;
        list_parts.Add(Test);

        d = new department();
        d.name = "Sawing";
        d.hours = 1.2;
        list_departments.Add(d);

        d = new department();
        d.name = "Turning";
        d.hours = 5.8;
        list_departments.Add(d);

        d = new department();
        d.name = "Finishing";
        d.hours = 5.6;
        list_departments.Add(d);

        d = new department();
        d.name = "QA";
        d.hours = 0.5;
        list_departments.Add(d);

        Test = new part();
        Test.name = "Cylinder";
        Test.number = "234";
        list_parts.Add(Test);

        lv_parts.ItemsSource = list_parts;
    }
}

我的 XAML 没有绑定子列表的列表视图

   <ListView x:Name="lv_parts" ItemsSource="{Binding list_parts}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*"/>
                        </Grid.ColumnDefinitions>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="50px"/>
                            <RowDefinition Height="50px"/>
                        </Grid.RowDefinitions>
                        <Label Grid.Row="0" Content="{Binding number}"/>
                        <Label Grid.Row="1 " Content="{Binding name}"/>
                    </Grid>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>

预期结果如下所示:

没有任何视觉样式,例如背景和前景色,您的 ListView 应如下所示。它使用带有水平 StackPanel 的 ItemsControl 来显示 Departments 集合。

<ListView ItemsSource="{Binding Parts}">
    <ListView.View>
        <GridView>
            <GridViewColumn>
                <GridViewColumn.Header>
                    <TextBlock>
                        <Run Text="Part Number"/>
                        <LineBreak/>
                        <Run Text="Part Name"/>
                    </TextBlock>
                </GridViewColumn.Header>
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock>
                            <Run Text="{Binding Number}"/>
                            <LineBreak/>
                            <Run Text="{Binding Name}"/>
                        </TextBlock>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
            <GridViewColumn>
                <GridViewColumn.Header>
                    <TextBlock>
                        <Run Text="Departement Name"/>
                        <LineBreak/>
                        <Run Text="Hours"/>
                    </TextBlock>
                </GridViewColumn.Header>
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <ItemsControl ItemsSource="{Binding Departments}">
                            <ItemsControl.ItemsPanel>
                                <ItemsPanelTemplate>
                                    <StackPanel Orientation="Horizontal"/>
                                </ItemsPanelTemplate>
                            </ItemsControl.ItemsPanel>
                            <ItemsControl.ItemTemplate>
                                <DataTemplate>
                                    <TextBlock>
                                        <Run Text="{Binding Name}"/>
                                        <LineBreak/>
                                        <Run Text="{Binding Hours}"/>
                                    </TextBlock>
                                </DataTemplate>
                            </ItemsControl.ItemTemplate>
                        </ItemsControl>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
        </GridView>
    </ListView.View>
</ListView>

请注意,上面的 XAML 使用如下所示的视图模型,并使用 class 和 属性 名称的适当大小写。

public class Part
{
    public string Number { get; set; }
    public string Name { get; set; }
    public List<Department> Departments { get; set; }
}

public class Department
{
    public string Name { get; set; }
    public double Hours { get; set; }
}

public class ViewModel
{
    public ObservableCollection<Part> Parts { get; }
        = new ObservableCollection<Part>();
}

视图模型的实例将分配给视图的 DataContext:

public MainWindow()
{
    InitializeComponent();

    var vm = new ViewModel();
    DataContext = vm;

    vm.Parts.Add(new Part
    {
        Name = "Block",
        Number = "123",
        Departments = new List<Department>
        {
            new Department { Name = "Sawing" , Hours = 0.3 },
            new Department { Name = "Milling" , Hours = 12.3 },
        }
    });

    vm.Parts.Add(new Part
    {
        Name = "Cylinder",
        Number = "456",
        Departments = new List<Department>
        {
            new Department { Name = "Sawing" , Hours = 1.2 },
            new Department { Name = "Turning" , Hours = 5.8 },
            new Department { Name = "Finishing" , Hours = 5.6 },
            new Department { Name = "QA" , Hours = 0.5 },
        }
    });
}

我更改了您的 xaml 代码。您可以将堆栈面板更改为网格并根据您的要求添加样式

<Grid IsSharedSizeScope="True">
        <ListView x:Name="lv_parts" ItemsSource="{Binding list_parts}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*" SharedSizeGroup="Parts"/>
                            <ColumnDefinition Width="*"/>
                        </Grid.ColumnDefinitions>
                        <StackPanel Orientation="Vertical" Grid.Column="0" Background="CornflowerBlue">
                            <Label Content="{Binding number}" Foreground="AliceBlue"/>
                            <Label Content="{Binding name}" Foreground="AliceBlue"/>
                        </StackPanel>
                        
                        <ListView Grid.Row="0" Grid.Column="1" Margin="0"  ItemsSource="{Binding departments}" >
                            <ListView.ItemsPanel>
                                <ItemsPanelTemplate>
                                    <StackPanel Orientation="Horizontal"/>
                                </ItemsPanelTemplate>
                            </ListView.ItemsPanel>
                            <ListView.ItemTemplate>
                                <DataTemplate>
                                    <StackPanel Orientation="Vertical" Background="Coral">
                                        <Label Content="{Binding name}" Foreground="AliceBlue"/>
                                        <Label Content="{Binding hours}" Foreground="AliceBlue"/>
                                    </StackPanel>
                                </DataTemplate>
                            </ListView.ItemTemplate>
                        </ListView>
                    </Grid>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </Grid>

您提供的数据输出如下: