[英]Datagrid Binding/Grouping
我的ViewModel“ MainWindowModel”中有類型為ObservableCollection<Person>
的Persons
對象。 在MainWindow中,我想要一個帶有“性別”分組的DataGrid。 但是,在組標題行中,性別始終顯示為“ M”: 。
數據綁定中有錯誤嗎?
<Window ...
xmlns:viewmodel="clr-namespace:SimpleDatagridGrouping"
<Window.Resources>
<viewmodel:MainWindowModel x:Key="vm" />
<CollectionViewSource x:Key="cvsPersons"
Source="{Binding Source={StaticResource vm}, Path=Persons}">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="Sex"/>
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
<DataTemplate x:Key="GroupingHeader">
<StackPanel Background="YellowGreen" Orientation="Horizontal"
HorizontalAlignment="Left">
<TextBlock Text="Sex" Margin="5,5,5,5"/>
<TextBlock Margin="0,5,5,5"
Text="{Binding Source={StaticResource cvsPersons},
Path=Sex}"/>
<TextBlock Text="Count" Margin="5,5,5,5"/>
<TextBlock Margin="0,5,5,5" Text="{Binding Path=ItemCount}"/>
</StackPanel>
</DataTemplate>
</Window.Resources>
<Grid DataContext="vm">
<DataGrid ItemsSource="{Binding Source={StaticResource ResourceKey=cvsPersons}}"
SelectionMode="Single"
Margin="10,0,10,10"
AlternationCount="2"
VerticalContentAlignment="Center"
AutoGenerateColumns="False"
MinHeight="35">
<DataGrid.GroupStyle>
<GroupStyle HeaderTemplate="{StaticResource ResourceKey=GroupingHeader}"/>
</DataGrid.GroupStyle>
<DataGrid.Columns>
<DataGridTextColumn Header="Forename" Binding="{Binding Forename}"/>
<DataGridTextColumn Header="Name" Binding="{Binding Name}" />
<DataGridTextColumn Header="Age" Binding="{Binding Age}" />
<DataGridTextColumn Header="Sex" Binding="{Binding Sex}" />
</DataGrid.Columns>
</DataGrid>
</Grid>
視圖模型:
public class Person
{
public string Forename { get; set; }
public string Name { get; set; }
public Int32 Age { get; set; }
public E_Sex Sex { get; set; }
public Person(string forename_, string name_, Int32 age_, E_Sex sex_ )
{...}
}//eoClass: Person
public class MainWindowModel : Notifier
{
public MainWindowModel()
{
IList<Person> persons_ = new List<Person> ();
persons_.Add ( new Person ( "Hans", "Müller", 23, E_Sex.M ) );
//...
this.persons = new ObservableCollection<Person> ( persons_ );
}//eoCtor
private ObservableCollection<Person> persons = null;
public ObservableCollection<Person> Persons
{
get { return this.persons; }
set
{
this.persons = value;
OnPropertyChanged ( "Persons" );
}
}
}//eoClass: MainWindowModel
分組時,模板的標題不會有人。 您得到的是一個名為Name的屬性。 在您的groupstyle中,您期望得到一個人並綁定它的屬性:
<DataTemplate x:Key="GroupingHeader">
.....
<TextBlock
Margin="0,5,5,5"
Text="{Binding Source={StaticResource cvsPersons}, Path=Sex}"
/>
您的模板應該更像:
<DataTemplate x:Key="GroupingHeader">
.....
<TextBlock
Margin="0,5,5,5"
Text="{Binding Name}"
您可以在此處看到完整的示例: https : //docs.microsoft.com/zh-cn/dotnet/framework/wpf/controls/how-to-group-sort-and-filter-data-in-the-datagrid-控制
如果您仔細查看輸出圖片,您將在標題中看到“ Project ....”。 這些是ProjectName。 但是代碼綁定了Name。 這是因為您定義為排序描述符的任何內容都會作為一種稱為Name的特殊字段返回。
為了獲得預期的結果,請將其用於您的組標題DataTemplate
:
<DataTemplate x:Key="GroupingHeader">
<StackPanel Background="YellowGreen" Orientation="Horizontal"
HorizontalAlignment="Left">
<TextBlock Text="Sex" Margin="5,5,5,5"/>
<!--Bind to Name!!-->
<TextBlock Margin="0,5,5,5" Text="{Binding Path=Name}"/>
<TextBlock Text="Count" Margin="5,5,5,5"/>
<TextBlock Margin="0,5,5,5" Text="{Binding Path=ItemCount}"/>
</StackPanel>
</DataTemplate>
那么這是怎么回事? 在此特定的DataTemplate中進行綁定時,必須考慮組頭的DataContext
是什么,因為這是任何綁定所尋找的。 因此,當您說: Text="{Binding Source={StaticResource cvsPersons}, Path=Sex}"
,您說的是去找到StaticResource cvsPersons
並綁定到其DataContext的名為Sex
的屬性。 我必須承認,您得到的行為有點奇怪,因為綁定在我看來應該會失敗(如果我錯了,請糾正我),但看起來它找到了列表中的第一個人並使用了該人的sex作為所有標頭的值。 嘗試一下,將列表中的第一個人更改為女性,所有標頭現在都將顯示F
而不是M
那么什么是組頭的DataContext
? 好吧,這就是所謂的CollectionViewGroup
,它具有以下公共屬性: Name
, Items
和ItemCount
。 如果仔細觀察,您已經在數據ItemCount
的最后一個TextBlock
中綁定到ItemCount
。 Name
是您要分組的對象的值,在您的情況下為'F','M'...,這在邏輯上對於每個組都是唯一的,並且任何給定組中的每個項目都具有對集合進行分組的屬性具有相同的值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.