在 DataGrid 中编辑后直接保存实体
Posted
技术标签:
【中文标题】在 DataGrid 中编辑后直接保存实体【英文标题】:Save entity directly after edit in DataGrid 【发布时间】:2015-09-24 15:08:45 【问题描述】:我使用DataGrid
将我的数据可视化给用户。编辑后,更新后的数据应直接存储到数据库中,无需使用任何“保存”按钮。
到目前为止,这是我的解决方案,它适用于所有 DataGrid
列,但 ComboBox
使用 EventTrigger
到 InvokeCommandAction
:
<DataGrid ItemsSource="Binding Path=Animals, Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged" SelectionMode="Single"
AutoGenerateColumns="False" CanUserSortColumns="True">
<i:Interaction.Triggers>
<i:EventTrigger EventName="RowEditEnding">
<i:InvokeCommandAction Command="Binding SaveCommand" />
</i:EventTrigger>
</i:Interaction.Triggers>
<DataGrid.Columns>
<DataGridTextColumn Header="EPC" Binding="Binding Epc, Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged"/>
<DataGridTextColumn Header="Visual ID" Binding="Binding VisualId, Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged"/>
<DataGridTextColumn Header="Geschlecht" Binding="Binding Gender, Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged"/>
<DataGridTemplateColumn Header="Bucht">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource=
"Binding DataContext.Pens,RelativeSource=RelativeSource AncestorType=x:Type view:AdministrationView"
DisplayMemberPath="Name"
SelectedItem="Binding Pen, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged"
SelectedValue="Binding Pen.PenId"
SelectedValuePath="PenId"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
ComboBox
选择更改后,如何在我的视图模型中调用 SaveCommand
?
或者是否有更简单的解决方案来实现我想要的行为(每次编辑后自动保存到数据存储)?
【问题讨论】:
【参考方案1】:如果您像这样添加另一个激活您的ICommand
的EventTrigger
,您将获得所需的行为:
<DataGridTemplateColumn Header="Bucht">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="Binding DataContext.Pens, RelativeSource=RelativeSource AncestorType=x:Type view:AdministrationView" DisplayMemberPath="Name" SelectedItem="Binding Pen, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged" SelectedValue="Binding Pen.PenId" SelectedValuePath="PenId">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="Binding DataContext.SaveCommand, RelativeSource=RelativeSource AncestorType=x:Type view:AdministrationView" />
</i:EventTrigger>
</i:Interaction.Triggers>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
【讨论】:
【参考方案2】:在您的 ViewModel 中,我假设您已经像这样定义了您选择的项目?
object selectedPen;
public object SelectedPen
get
return selectedPen;
set
if (selectedPen != value)
selectedPen = value;
DoSave(); // insert saving logic here
OnPropertyChanged("SelectedPen");
当设置器中的值发生变化时,您可以调用保存。
【讨论】:
我不确定我是否喜欢它...在 ViewModel 中有上下文(DoSave() 需要)。通常我会在用户界面中保留保存逻辑(想想明年你使用 SelectPen 会发生什么,我能理解为什么)。 对不起,什么? 是什么意思,想想明年你将使用 SelectPen 时会发生什么,我能理解为什么? 个人意见。如果您通常不以这种方式使用 ViewModel,您可能会忘记(或者您的同事不知道)它节省了属性集。不过是个人意见吗…… 我同意尽量减少 getter/setter 中的逻辑的观点。但是上下文应该在ViewModel
imo 中可用。
是的,视图模型可以通过工作单元/存储库模式访问上下文。【参考方案3】:
一种方法是在您的 ViewModel 上实现 IEditableObject 并实现 DataGrid.CellEditEnding
和 DataGrid.CurrentCellChanged
。
有关详细信息,请参阅 Colin Eberhardt 的 this 博客文章。
private DataRowView rowBeingEdited = null;
private void dataGrid_CellEditEnding(object sender,
DataGridCellEditEndingEventArgs e)
DataRowView rowView = e.Row.Item as DataRowView;
rowBeingEdited = rowView;
private void dataGrid_CurrentCellChanged(object sender, EventArgs e)
if (rowBeingEdited != null)
rowBeingEdited.EndEdit();
【讨论】:
这会在我的视图模型和我的视图之间引入非常紧密的耦合,我想避免这种耦合。通过在我的示例代码中使用 EventTrigger,我在没有紧密耦合的情况下得到了相同的结果。 除了 IEditableObject 接口之外,View 和 ViewModel 之间没有耦合。这都是作用于视图元素的代码隐藏,隐式调用 DataContext 的 IEditableObject-Implementaion。您正在镜像 DataGrid 的内置功能。 啊,我明白了。感谢您的澄清。确实没有紧密耦合:-) 但我想知道这个解决方案是否与我正在使用的解决方案有什么不同。现在我的命令在事件“RowEditEnding”之后触发(参见上面的示例代码)。 使用此解决方案,您可以将提交应用到每个单元格,而无需修改模板。事实上,您可以将这段代码放在一个 Behavior 中并重用 ist 而不会有太多麻烦。是imo维护点少的解决方案。以上是关于在 DataGrid 中编辑后直接保存实体的主要内容,如果未能解决你的问题,请参考以下文章
jquery easyui如何实现单击datagrid的某个格子,就可以直接编辑,离开后直接保存。
EasyUi DataGrid中数据编辑方式及编辑后数据获取,校验处理