使用 MVVM,如何从 DataTable 动态生成 WPF DataGrid 列并显示按钮列?

问题描述 投票:0回答:1

我试图从数据表动态生成数据网格,同时显示两个用于“编辑”和“删除”功能的按钮列。我可以在 XAML 中手动创建按钮列,并且可以从 DataTable 动态生成列,但我似乎无法同时执行这两项操作。如果我只是在代码隐藏中对此进行编码,我认为解决问题会简单得多,因为我可以直接访问控件。但是,我正在使用 MVVM 构建此视图,但我想不出一种方法来动态操作视图到这种详细程度。

这是我的一些代码(请注意,对于比我有更多 WPF/MVVM 经验的人来说,可能会有一些“复制/粘贴失败”是显而易见的): XAML:

<DataGrid x:Name="grdMapValues" AutoGenerateColumns="True" ItemsSource="{Binding GridSourceDataTable}"> <DataGrid.Columns> <DataGridTemplateColumn IsReadOnly="True"> <DataGridTemplateColumn.HeaderTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <Button HorizontalAlignment="Left" Command="{Binding Path=DataContext.Commands.AddMapValue, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}" Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}"> <Image Width="14" Height="14" Source="/Controls;component/Resources/Images/new.gif" ToolTip="New" /> </Button> </StackPanel> </DataTemplate> </DataGridTemplateColumn.HeaderTemplate> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <Button Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}" Command="{Binding Path=DataContext.Commands.EditMapValue, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}"> <Image Width="14" Height="14" Source="/Controls;component/Resources/Images/edit.gif" /> </Button> <Button Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}" Command="{Binding Path=DataContext.Commands.DeleteMapValue, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}"> <Image Width="14" Height="14" Source="/Controls;component/Resources/Images/delete.gif" /> </Button> </StackPanel> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> </DataGrid.Columns> </DataGrid>

视图模型:

private DataTable _gridSource; public DataTable GridSourceDataTable { get { return _gridSource; } set { _gridSource = value; OnPropertyChanged("GridSourceDataTable"); } } private void GenerateDataTable() { switch (caseInt) { case 1: if (_isDate) { _gridSource.Columns.Add("Date", typeof(DateTime)); } else { _gridSource.Columns.Add("Number", typeof(string)); } _gridSource.Columns.Add("Value", typeof(decimal)); _gridSource.Columns.Add("SourceString", typeof(string)); GridIsVisible = true; break; //Other similar case blocks removed default: GridIsVisible = false; break; } OnPropertyChanged("GridSourceDataTable"); }

所以我猜测解决方案(如果有的话)将涉及 XAML 和 DataTable 属性的某种混合,或者它将涉及比我的简单 DataTable 更复杂的对象或属性。

我已经为此工作了几个小时,因此我们将非常感谢您提供的任何帮助。

wpf xaml mvvm datagrid datatable
1个回答
5
投票

这是我尝试过的附加行为:

public class DataGridColumnBehavior : Behavior<DataGrid> { public AdditionalColumnsList AdditionalColumns { get; set; } protected override void OnAttached() { base.OnAttached(); AddAdditionalColumns(); } void AddAdditionalColumns() { if(AdditionalColumns == null || AdditionalColumns.Count == 0) return; foreach (var additionalColumn in AdditionalColumns) { AssociatedObject.Columns.Add(new DataGridTemplateColumn { HeaderTemplate = additionalColumn.HeaderTemplate, CellTemplate = additionalColumn.CellTemplate }); } } }

我使用了几个简单的类来表示附加列和附加列列表。

public class AdditionalColumn { public DataTemplate HeaderTemplate { get; set; } public DataTemplate CellTemplate { get; set; } } public class AdditionalColumnsList : List<AdditionalColumn> { }

并且,这就是将行为附加到 DataGrid 的方式:

<DataGrid Margin="5" ItemsSource="{Binding GridSource}"> <i:Interaction.Behaviors> <local:DataGridColumnBehavior> <local:DataGridColumnBehavior.AdditionalColumns> <local:AdditionalColumnsList> <local:AdditionalColumn> <local:AdditionalColumn.HeaderTemplate> <DataTemplate> <TextBlock Text="Button Header" /> </DataTemplate> </local:AdditionalColumn.HeaderTemplate> <local:AdditionalColumn.CellTemplate> <DataTemplate> <Button Content="Button" Command="{Binding ButtonCommand}" /> </DataTemplate> </local:AdditionalColumn.CellTemplate> </local:AdditionalColumn> </local:AdditionalColumnsList> </local:DataGridColumnBehavior.AdditionalColumns> </local:DataGridColumnBehavior> </i:Interaction.Behaviors> </DataGrid>

生成的网格:

enter image description here阅读此 CodeProject

文章

,了解附加行为。 请注意,我在这里使用了混合行为。

这篇

博客文章讨论了依附行为和混合行为之间的差异。

© www.soinside.com 2019 - 2024. All rights reserved.