我将DataGrid绑定到从IMyInterface派生的不同类型的对象集合。我需要根据对象的实际类型对DataGrid进行分组,并根据每种类型的属性自动生成每个组中的colulmns,因为类型具有不同的属性。
请帮忙。
我正在添加一些现有代码:
XAML:
<Style x:Key="GroupHeaderStyle" TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Expander IsExpanded="False"
Background="White"
Foreground="Black">
<Expander.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}"/>
<TextBlock Text="{Binding Path=ItemCount}" Padding="10, 0, 10, 0"/>
<TextBlock Text="Item(s)"/>
</StackPanel>
</Expander.Header>
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
...
<DataGrid Grid.Row="1" Grid.Column="2" Name="DgPendingMessages" ItemsSource="{Binding }" AutoGenerateColumns="False"
IsReadOnly="True" MaxHeight="400">
<DataGrid.GroupStyle>
<GroupStyle ContainerStyle="{StaticResource GroupHeaderStyle}">
<GroupStyle.Panel>
<ItemsPanelTemplate>
<DataGridRowsPresenter />
</ItemsPanelTemplate>
</GroupStyle.Panel>
</GroupStyle>
</DataGrid.GroupStyle>
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding TheMessage}" Header="Pending Message" />
</DataGrid.Columns>
</DataGrid>
代码隐藏:
public class PendingMessage
{
//public IMyInterface TheMessage { get; set; }
public string TheMessage { get; set; }
public string MessageType { get; set; }
}
PendingMessage是我的模型类,它包含真实Message对象的字符串表示形式和Message对象的原始类型(用于通过它对DataGrid进行分组)。
Message对象可以是从IMyInterface派生的任何类型。
var collectionPendingMessages = new ListCollectionView(PendingMessages);
collectionPendingMessages.GroupDescriptions.Add(new PropertyGroupDescription("MessageType"));
DgPendingMessages.ItemsSource = collectionPendingMessages;
而不是真正的Message对象的字符串表示,我希望有这样的东西:
A型:3件
列N |列Z |第X列|第T栏
数据|数据|数据|数据
数据|数据|数据|数据
数据|数据|数据|数据
B型:4件
列N |列S |第U栏
数据|数据|数据
数据|数据|数据
数据|数据|数据
数据|数据|数据
C型:3件
列N |列Z |第X列|列T |第U栏
数据|数据|数据|数据|数据
数据|数据|数据|数据|数据
数据|数据|数据|数据|数据
答案 0 :(得分:1)
我之前已经解决过这个问题了。如果您基本上使用XAML作为视图,那么对我有用的一个选项是在运行时动态生成您需要的XAML。感觉有点难看,但似乎确实有效。
这是我在其中一个项目中的代码隐藏课程。希望它足够接近您的问题:
public partial class SetupPanel : UserControl
{
public SetupPanel()
{
InitializeComponent();
}
protected override void OnRender(System.Windows.Media.DrawingContext drawingContext)
{
AddParticipantGridViewColumns();
base.OnRender(drawingContext);
}
public void AddParticipantGridViewColumns()
{
...
for (var blockIndex = 0; blockIndex < blockColumnCount; blockIndex++)
{
var column = BuildParticipantGridViewColumn(blockIndex);
dataGrid.Columns.Add(column);
}
}
private DataGridTemplateColumn BuildParticipantGridViewColumn(int blockIndex)
{
var columnXaml = string.Format(@"
<DataGridTemplateColumn
xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml""
Header=""Block {1}"">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text=""{{Binding BlockViewModels[{0}].ConditionLabel}}""
Foreground=""{{Binding BlockViewModels[{0}].TextBrush}}"" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>",
blockIndex, blockIndex + 1);
var column = (DataGridTemplateColumn)XamlReader.Parse(columnXaml);
return column;
}
}
<强>更新强>
再次阅读您的问题,您可能需要做的就是使用AutoGenerateColumns="true"
作为您的DataGrid。但是,只有在您不想自定义列的外观时才能使用此功能。
更新2
查看更新后的问题,看起来您可能真正需要做的就是将消息放入DataTable对象中,这样就可以构建列并在运行时动态填充数据。然后,您可以使用AutoGenerateColumns,或者,如果您需要更多自定义,请使用XAML生成(如上所述)将列添加到DataGrid。