编辑数据网格上的单元格后运行方法
Posted
技术标签:
【中文标题】编辑数据网格上的单元格后运行方法【英文标题】:Run a method after editing a cell on a datagrid 【发布时间】:2020-10-23 17:28:36 【问题描述】:我正在使用 WPF 和 CaliburnMicro 来绑定数据。我想在每次编辑完单元格时运行一个 Add() 方法,但问题是数据网格的属性没有执行它。
这是我的代码:
<Window x:Class="DataGrid_NotifyOfPropertyChanged.Views.ShellView"
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:DataGrid_NotifyOfPropertyChanged.Views"
mc:Ignorable="d"
Title="ShellView" Height="450" Width="800">
<Grid>
<DataGrid x:Name="Numbers" CanUserAddRows="False"/>
</Grid>
public class NumbersModel
public int Number get; set;
ShellViewModel
public class ShellViewModel: Screen
public ShellViewModel()
Numbers.Add(new NumbersModel Number = 1 );
Numbers.Add(new NumbersModel Number = 2 );
private BindableCollection<NumbersModel> _numbers = new BindableCollection<NumbersModel>();
public BindableCollection<NumbersModel> Numbers
get return _numbers;
set
_numbers = value;
Add();
public void Add()
double result = 0;
foreach(var i in _numbers.ToList())
result += i.Number;
MessageBox.Show(result.ToString());
【问题讨论】:
你可以把你的逻辑放在 Number 的 setter 中。您应该使用更深思熟虑的属性命名。始终在视图模型上执行 inotifypropertychanged。 【参考方案1】:您必须让NumbersModel
实现INotifyPropertyChanged
接口。
这样,您可以在属性更改时收到通知。您通常总是必须在每个用作绑定源的类上实现此接口。
如果没有这个接口,数据绑定也可以工作,但是性能会急剧下降。对于具有许多绑定的应用程序,这将是一个问题。
解决办法是监听NumbersModel.Number
的属性变化。因此我介绍了一个专门的活动NumberChanged
。
事件NumberChanged
是可选的。您也可以收听PropertyChanged
,然后使用switch
语句按属性名称过滤所需的属性。我认为与混乱的switch
块相比,专门的事件显着提高了可读性和对上下文的理解。
为防止删除项目时发生内存泄漏,您必须取消订阅您正在收听的NumbersModel
的每个事件。
因此,您还需要监听 Numbers
集合的 CollectionChanged
事件:
NumbersModel.cs
public class NumbersModel : INotifyPropertyChanged
private int number;
public int Number
get => this.number;
set
if (value == this.number)
return;
this.number = value;
OnPropertyChanged();
OnNumberChanged();
public event EventHandler NumberChanged;
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
protected virtual void OnNumberChanged()
this.NumberChanged?.Invoke(this, EventArgs.Empty);
ShellViewModel.cs
public class ShellViewModel : Screen
public ShellViewModel()
this.Numbers = new BindableCollection<NumbersModel>();
this.Numbers.Add(new NumbersModel Number = 1);
this.Numbers.Add(new NumbersModel Number = 2);
public void Add()
double result = this._numbers.Sum(numbersModel => numbersModel.Number);
MessageBox.Show(result.ToString());
private BindableCollection<NumbersModel> _numbers;
public BindableCollection<NumbersModel> Numbers
get => this._numbers;
set
// Unsubscribe from old collection
if (this.Numbers != null)
this.Numbers.CollectionChanged -= OnCollectionChanged;
this._numbers = value;
// Subscribe to new collection
if (this.Numbers != null)
this.Numbers.CollectionChanged += OnCollectionChanged;
Add();
private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
switch (e.Action)
case NotifyCollectionChangedAction.Add:
foreach (NumbersModel newItem in e.NewItems.Cast<NumbersModel>())
newItem.NumberChanged += OnNumberChanged;
break;
case NotifyCollectionChangedAction.Remove:
case NotifyCollectionChangedAction.Reset:
foreach (NumbersModel newItem in e.OldItems.Cast<NumbersModel>())
newItem.NumberChanged -= OnNumberChanged;
break;
private void OnNumberChanged(object sender, EventArgs e)
Add();
【讨论】:
【参考方案2】:我想在每次编辑完一个单元格时运行一个
Add()
方法
使用 Caliburn.Micro 执行此操作的方法是使用 EventTrigger
和 ActionMessage
来处理 CellEditEnding
事件:
<DataGrid x:Name="Numbers" CanUserAddRows="False"
cal:Message.Attach="[Event CellEditEnding] = [Action Add()]" />
【讨论】:
我已经尝试过了,但输出不是我所期望的。假设我有两个实例(Number=1 和 Number=2)。更新绑定到 Number=1 的数据网格中的单元格并将其替换为 2 并执行 Add() 方法结果为 3 而不是 4。我在这里做错了吗? 如何以及何时更新源属性是另一个主题。如果您有其他问题,请提出一个新问题。您最初的问题是关于如何“每次完成编辑单元格时运行 Add() 方法”,不是吗? 很清楚你不明白“完成编辑单元格”。从输出来看,单元格根本没有被编辑过。以上是关于编辑数据网格上的单元格后运行方法的主要内容,如果未能解决你的问题,请参考以下文章
EasyUI datagrid editCell 编辑完单元格后如何取消编辑状态?
easyui datagrid 编辑单元格后失去焦点结束编辑状态,怎么做啊?