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}
。您如何确定它在内部而不是下方。狗仔队不确定,但也许还有另一个问题。现在我无法打印联盟的名称。因此,您还添加了一个新的XAMLGroupStyle
?你能给我看一下修改过的代码吗?我想我将来会用类替换结构。但是你为什么不建议结构呢?与类相比,结构是一种轻量级数据。结果应该是这样的:我只添加了联赛。@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" />