c# - 如何插入多个GroupDescription?

标签 c# wpf xaml

我制作了一个应用程序,可以获取比赛的实时结果。 现在每场比赛的组织是这样的:

Nation->League->Match list

所以我的NationLeague的容器,而LeagueMatch的容器。我首先做的是创建一个 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>

你可以看到有一个ListView有一个GroupStyle定义,在这个我保存了所有的Nation。您可以在演示解决方案中尝试 XAML 并检查结果。

在此之后,我创建了允许我存储值的结构:

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

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

非常简单,一个League结构用于保存所有联赛,一个Country结构用于保存国家。我以这种方式评估了国家:

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; 

所以我实际上在列表中包含意大利(2)、英格兰、西类牙。然后,我将 items 插入到 ListView(XAML 控件)的 ItemsSource 中。

为了创建标题组作为 Nation 名称,我使用了 CollectionView:

CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(lvUsers.ItemsSource);
        PropertyGroupDescription groupNations = new PropertyGroupDescription("Name");

这段代码允许我创建多个 header ,结果正是我想要的。我也对 League 做了同样的事情,因为我需要将 League 名称作为 sub-header 插入到 Nation 中 容器( header ):

        view.GroupDescriptions.Add(groupNations);
        PropertyGroupDescription groupCompetions = new PropertyGroupDescription("League");
        view.GroupDescriptions.Add(groupNations);

但实际上这是结果:

enter image description here

如何才能看到仅出现国家标题,但 League 标题未出现在 Nation 标题内。我做错了什么?

最佳答案

您可以通过创建 League 来“修复”它属性(添加 getter 和 setter - WPF 绑定(bind)附加到属性,而不是字段),使第二组描述按 "League.Name" 分组而不仅仅是"League"并制作第二组样式TextBlock绑定(bind) 绑定(bind)到 Name ,不是League .

然后你会得到这个:

enter image description here

但我想说你正在以错误的方式处理这个问题并以一种非常奇怪的方式建模你的数据。如果ListView旨在列出 Matches ,那么您应该绑定(bind)到 Match 的集合对象(或它们的 View ),以及每个 Match应引用其父项 League ,以及每个League应引用其父项 Country .

或者,使用树而不是列表,然后得到 Country与 child 的集合Leagues ,以及每个League与 child 的集合Matches .

或者两者都有 - a League其中包含 Matches 的集合,但每个匹配项都有一个父项 League引用,类似 Country/League .

它在代码中的方式有​​点奇怪。

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

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

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
}

对 XAML 的更改,只需 1 行:

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

{Binding Name}{Binding League}在您的原始代码中。

关于c# - 如何插入多个GroupDescription?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37026326/

相关文章:

c# - 无法将类型 'System.String' 的对象强制转换为 "..Controls.SurfaceListBoxItem' 异常

c# - 延迟加载 ListView 中的可见项

c# - 如何在.net Core 3.0中显示400错误的自定义页面

c# - Listpicker 错误 SelectedItem 必须始终设置为有效值

c# - 对列表框中的列表项进行 HitTest

c# - RichTextBlock 不断在 UWP 中的运行之间插入空格

c# - 如何添加一个选项以有选择地从 ComboBox 中删除项目?

c# - 如何在 linq where 子句中使用函数的返回值?

c# - 什么是 Template10 导航服务的 NavigationServices.FirstOrDefault()?

c# - 无法在 MVVM 中完成模式中介