C# 如何插入多个GroupDescription?

C# 如何插入多个GroupDescription?,c#,wpf,xaml,C#,Wpf,Xaml,我已经做了一个应用程序,可以获得比赛的实况结果。 现在,每场比赛的组织如下: Nation->League->Match list 所以我有国家,它是联盟的容器,联盟是比赛的容器。我首先做的是创建一个XAML结构,它允许我实现前面提到的容器结果: <Window x:Class="GroupBox_Header.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

我已经做了一个应用程序,可以获得比赛的实况结果。 现在,每场比赛的组织如下:

Nation->League->Match list
所以我有
国家
,它是
联盟
的容器,
联盟
比赛
的容器。我首先做的是创建一个
XAML
结构,它允许我实现前面提到的容器结果:

<Window x:Class="GroupBox_Header.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:GroupBox_Header"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">
<Grid Margin="10">
    <ListView Name="lvUsers">
        <ListView.View>
            <GridView>
                <GridViewColumn Header="Home Team" Width="50" DisplayMemberBinding="{Binding HomeTeam}" />
                <GridViewColumn Header="Away Team" Width="50" DisplayMemberBinding="{Binding AwayTeam}" />
            </GridView>
        </ListView.View>

        <ListView.GroupStyle>
            <GroupStyle>
                <GroupStyle.ContainerStyle>
                    <Style TargetType="{x:Type GroupItem}">
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate>
                                    <Expander IsExpanded="True">
                                        <Expander.Header>
                                            <StackPanel Orientation="Horizontal">
                                                <TextBlock Text="{Binding Name}" FontWeight="Bold" Foreground="Gray" FontSize="22" VerticalAlignment="Bottom" />
                                                <TextBlock Text="{Binding ItemCount}" FontSize="22" Foreground="Green" FontWeight="Bold" FontStyle="Italic" Margin="10,0,0,0" VerticalAlignment="Bottom" />
                                                <TextBlock Text=" Items" FontSize="22" Foreground="Silver" FontStyle="Italic" VerticalAlignment="Bottom" />
                                            </StackPanel>
                                        </Expander.Header>
                                        <ItemsPresenter />
                                    </Expander>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </GroupStyle.ContainerStyle>
            </GroupStyle>
            <GroupStyle>
                <GroupStyle.ContainerStyle>
                    <Style TargetType="{x:Type GroupItem}">
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate>
                                    <Expander IsExpanded="True">
                                        <Expander.Header>
                                            <StackPanel Orientation="Horizontal">
                                                <TextBlock Text="{Binding League}" FontWeight="Bold" Foreground="Gray" FontSize="22" VerticalAlignment="Bottom" />
                                            </StackPanel>
                                        </Expander.Header>
                                        <ItemsPresenter />
                                    </Expander>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </GroupStyle.ContainerStyle>
            </GroupStyle>
        </ListView.GroupStyle>
    </ListView>
</Grid>
非常简单,一个
联盟
结构用于保存所有联盟,一个
国家
结构用于国家。我以这种方式对
国家进行了估价:

List<Country> items = new List<Country>();
            items.Add(new Country() { Name = "Italy", League = { Name = "Serie A"} });
            items.Add(new Country() { Name = "Italy", League = { Name = "Serie B" } });
            items.Add(new Country() { Name = "England", League = { Name = "Premiere League" } });
            items.Add(new Country() { Name = "Spain", League = { Name = "Primeira Division" } });
            lvUsers.ItemsSource = items; 
这段代码允许我创建多个标题,结果正是我想要的。对于
联盟
,我也做了同样的操作,因为我需要将
联盟
名称作为
子标题插入
国家
容器(标题):

但实际上这是结果:

如何只显示国家标题,而
联赛
标题不显示在
国家
标题内。我做错了什么?

您可以通过将
League
设置为属性(将getter和setter-WPF绑定添加到属性,而不是字段)来“修复”它,将第二个组描述组设置为
“League.Name”
而不是
“League”
并使第二组样式
TextBlock
绑定到
Name
,而不是
League

然后你得到这个:

但我要说的是,你用了错误的方法来处理这个问题,并且用了一种非常奇怪的方式来建模你的数据。如果
列表视图
旨在列出
匹配
,则您应该绑定到
匹配
对象的集合(或它们上方的视图),并且每个
匹配
应该引用其父
联盟
,每个
联盟
应该引用其父
国家

或者,使用树而不是列表,然后有一个包含子
联盟的
国家
,每个
联盟
包含子
匹配的集合

或者两者都有-一个
联赛
,其中包含一组
比赛
,但每个比赛都有一个父
联赛
参考,并且与
国家/联赛
类似

代码中的这种方式有点奇怪

另外,我不明白为什么要对对象使用结构而不是类

对代码隐藏的更改(请注意,我并不是说这是一种很好的方法,请参见上文):

公共部分类主窗口:窗口
{
公共主窗口()
{
初始化组件();
列表项=新列表();
items.Add(newcountry(){Name=“意大利”,League=新联赛{Name=“意甲”}});//添加了“新联赛”
添加(新国家({Name=“意大利”,联赛=新联赛{Name=“意乙”});
添加(新国家(){Name=“英格兰”,联赛=新联赛{Name=“英超联赛”});
添加(新国家(){Name=“西班牙”,联盟=新联盟{Name=“Primeira分部”});
lvUsers.ItemsSource=项目;
CollectionView视图=(CollectionView)CollectionViewSource.GetDefaultView(lvUsers.ItemsSource);
PropertyGroupDescription groupNations=新的PropertyGroupDescription(“名称”);
view.GroupDescriptions.Add(groupNations);
PropertyGroupDescription GroupCompetitions=新建PropertyGroupDescription(“League.Name”);//将“League”更改为“League.Name”
view.GroupDescriptions.Add(groupcompetitions);//修复了此处的变量名
lvUsers.ItemsSource=view;//添加了,您可能已经拥有了它,但没有发布它
}
}
公共结构联盟
{
公共字符串名称{get;set;}
}
公共结构国家
{
公共字符串名称{get;set;}
公开联赛{get;set;}//增加了一个接球手和二传手
}
对XAML的更改,仅1行:

<TextBlock Text="{Binding Name}" FontWeight="Bold" Foreground="Gray" FontSize="22" VerticalAlignment="Bottom" />


{Binding Name}
是原始代码中的
{Binding League}

您如何确定它在内部而不是下方。狗仔队不确定,但也许还有另一个问题。现在我无法打印联盟的名称。因此,您还添加了一个新的XAML
GroupStyle
?你能给我看一下修改过的代码吗?我想我将来会用类替换结构。但是你为什么不建议结构呢?与类相比,结构是一种轻量级数据。结果应该是这样的:我只添加了联赛。@Dillinger我添加了代码。。。但首先,这不是一个好方法,这就是我最初没有添加它的原因。这是一个“黑客”,谢谢你,你有什么建议?我没有找到任何允许我这样做的控件,我用vb.net和windows窗体创建了这个自定义控件:但现在我不能重用它。@迪林杰:最简单的方法是只有一个类-
Match
,它有一个
string
属性
Country
和一个
string
属性
League
。然后在
匹配项的集合上创建一个视图,并按
国家
分组,然后按
联盟
分组。除非您实际需要一个更复杂的模型,其中包含
Country
League
的类。如果你这样做了,我会在回答中提到这一点。我提到的对XAML的更改是针对你的pastebin中的第53行的。另外,请看第112行-
组竞赛
而不是
组国家
CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(lvUsers.ItemsSource);
        PropertyGroupDescription groupNations = new PropertyGroupDescription("Name");
        view.GroupDescriptions.Add(groupNations);
        PropertyGroupDescription groupCompetions = new PropertyGroupDescription("League");
        view.GroupDescriptions.Add(groupNations);
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        List<Country> items = new List<Country>();
        items.Add(new Country() { Name = "Italy", League = new League { Name = "Serie A" } }); // Added "new League"
        items.Add(new Country() { Name = "Italy", League = new League { Name = "Serie B" } });
        items.Add(new Country() { Name = "England", League = new League { Name = "Premiere League" } });
        items.Add(new Country() { Name = "Spain", League = new League { Name = "Primeira Division" } });
        lvUsers.ItemsSource = items;

        CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(lvUsers.ItemsSource);
        PropertyGroupDescription groupNations = new PropertyGroupDescription("Name");
        view.GroupDescriptions.Add(groupNations);
        PropertyGroupDescription groupCompetions = new PropertyGroupDescription("League.Name"); // Changed "League" to "League.Name"
        view.GroupDescriptions.Add(groupCompetions); // Fixed the variable name here

        lvUsers.ItemsSource = view; // Added, you probably have it but didn't post it
    }
}

public struct League
{
    public string Name { get; set; }
}

public struct Country
{
    public string Name { get; set; }
    public League League { get; set; } // added getter and setter
}
<TextBlock Text="{Binding Name}" FontWeight="Bold" Foreground="Gray" FontSize="22" VerticalAlignment="Bottom" />