【发布时间】:2017-08-20 07:08:00
【问题描述】:
我正在更新Datagrid,当用户输入一个已经存在的数字时,我想通知用户该数字已经存在,然后从datagrid 中清除该值。
我知道为什么会发生这种情况,但我不知道如何阻止这种情况或如何解决。
这是非常简化的代码:首先使用 EF 代码和 MVVM 模型。
public partial class StaffMasterData
{
public System.Guid Id { get; set; } // ID (Primary key)
public int? StaffNo { get; set; } // StaffNo
public StaffMasterData()
{
InitializePartial();
}
partial void InitializePartial();
}
StaffMasterData 的实体扩展类:
public partial class StaffMasterData : INotifyPropertyChanged
{
partial void InitializePartial()
{
Id = Guid.NewGuid();
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName]string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
handler?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
以及保存数据的方法:
public void SaveMasterData(StaffMasterData nwRowData)
{
using (var db = CreateDbContext())
{
//MasterDataBinding is the observableCollection
//the datagrid is being bound to.
var staffNoExists = MasterDataBinding.Any(p => p.StaffNo == nwRowData.StaffNo);
if (!staffNoExists)
{
db.StaffMasterDatas.AddOrUpdate(nwRowData);
db.SaveChanges();
}
else
{
Alerts.Error("Staff Number exists");
nwRowData.StaffNo = null;
}
}
}
集合改变事件的分配:
public class ShiftManagerViewModel : INotifyPropertyChanged
{
private ObservableCollection<StaffMasterData> _mMasterDataBinding = new ObservableCollection<StaffMasterData>();
public ObservableCollection<StaffMasterData> MasterDataBinding
{
get { return _mMasterDataBinding; }
set
{
if (value != _mMasterDataBinding)
{
_mMasterDataBinding = value;
OnPropertyChanged();
}
}
}
public ShiftManagerViewModel()
{
_mMasterDataBinding.CollectionChanged += collectionChanged_Event;
}
private void collectionChanged_Event(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.NewItems != null && e.NewItems.Count > 0)
{
foreach (INotifyPropertyChanged item in e.NewItems.OfType<INotifyPropertyChanged>())
{
item.PropertyChanged += propertyChanged_Event;
}
}
if (e.OldItems != null && e.OldItems.Count > 0)
{
foreach (INotifyPropertyChanged item in e.OldItems.OfType<INotifyPropertyChanged>())
{
item.PropertyChanged -= propertyChanged_Event;
}
}
}
public void propertyChanged_Event(object sender, PropertyChangedEventArgs e)
{
if (sender is StaffMasterData)
{
SaveMasterData((StaffMasterData)sender);
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName]string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
handler?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
可能很清楚,当运行这行代码 nwRowData.StaffNo = null; 时,它会再次触发事件,因为集合已被修改,然后又运行 messageBox 代码并弹出两次。
老实说,我已经为此碰壁了,任何正确方向的观点都会受到赞赏。
【问题讨论】:
-
为 StaffNo 属性设置支持字段,而不是设置该属性。
-
如果你使用
AddOrUpdate,为什么要检查现有的。可以使用数据库上的 StaffNo 约束来修复它并尝试/捕获它。其他进程可能会在您的支票之间写入它。 -
在您发布的代码中,StaffNo 属性不会触发任何事件...?
-
StaffNo 如果像您发布的代码那样实现,则根本不会引发任何事件。
-
@mm8,好的,我知道发生了什么,因为这是我第一次尝试 MVVM,在我真正开始编写代码之前经过大量研究,我遇到了一个名为 @ 的 NuGet 包987654331@ 并且它使用了
PropertyChanged,所以没有使用方法并且正在更新属性的原因是由于插件。对于那个很抱歉。我想我要卸载插件并使用OnPropertyChanged方法来更好地了解正在发生的事情。我认为正在发生的事情是正常的行为。再次感谢您抽出时间提供帮助。
标签: c# wpf mvvm datagrid inotifypropertychanged