运行 编辑数据网格上的单元格后的方法
Run a method after editing a cell on a datagrid
我正在使用 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());
}
}
您必须让 NumbersModel
实现 INotifyPropertyChanged
接口。
这样您就可以在 属性 更改时收到通知。通常,您 总是 必须在每个用作绑定源的 class 上实现此接口。
没有这个接口数据绑定也可以工作,但是性能会急剧下降。对于具有许多绑定的应用程序,这将是一个问题。
解决办法是监听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();
}
}
I want to run an Add()
method every time I finished editing a cell
使用 Caliburn.Micro 执行此操作的方法是使用 EventTrigger
和 ActionMessage
来处理 CellEditEnding
事件:
<DataGrid x:Name="Numbers" CanUserAddRows="False"
cal:Message.Attach="[Event CellEditEnding] = [Action Add()]" />
我正在使用 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());
}
}
您必须让 NumbersModel
实现 INotifyPropertyChanged
接口。
这样您就可以在 属性 更改时收到通知。通常,您 总是 必须在每个用作绑定源的 class 上实现此接口。
没有这个接口数据绑定也可以工作,但是性能会急剧下降。对于具有许多绑定的应用程序,这将是一个问题。
解决办法是监听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();
}
}
I want to run an
Add()
method every time I finished editing a cell
使用 Caliburn.Micro 执行此操作的方法是使用 EventTrigger
和 ActionMessage
来处理 CellEditEnding
事件:
<DataGrid x:Name="Numbers" CanUserAddRows="False"
cal:Message.Attach="[Event CellEditEnding] = [Action Add()]" />