C# 基于propertyvaluechange事件创建撤消/重做命令

C# 基于propertyvaluechange事件创建撤消/重做命令,c#,propertygrid,C#,Propertygrid,我想创建undo/redo命令,它可以为某些属性设置新/旧值。我使用propertygrid操作属性值。我尝试使用PropertyValueChanged事件执行此操作 我的尝试: private void pg_PropertyValueChanged(object s, PropertyValueChangedEventArgs e) { var item = propertyGrid.SelectedObject; var propertyName = e.ChangedI

我想创建
undo/redo命令
,它可以为某些属性设置新/旧值。我使用
propertygrid
操作属性值。我尝试使用
PropertyValueChanged事件
执行此操作

我的尝试:

private void pg_PropertyValueChanged(object s, PropertyValueChangedEventArgs e)
{
    var item = propertyGrid.SelectedObject;
    var propertyName = e.ChangedItem.PropertyDescriptor.Name;
    PropertyInfo pi = item.GetType().GetProperty(propertyName);

    var oldValue = e.OldValue;
    var newValue = propertyInfo.GetValue(item, null);

    //create command here
}
如果属性的父对象是
propertyGrid.SelectedObject
,则此操作正常。 但如果我有课:

Class A {
    public Size Size {get;set;}
}
它有时不起作用。 示例:
propertyGrid.SelectedObject
Class A
propertyName
Width
Width
不是
Class A
属性,它是
Size
属性,所以我得到了异常


我如何解决这个问题?如何创建
undo/redo命令来解决这种情况?

以下工作可以完成吗

private void pg_PropertyValueChanged(object s, PropertyValueChangedEventArgs e)
{
  var item = e.ChangedItem;
  var propertyName = item.PropertyDescriptor.Name;
  PropertyInfo pi = item.GetType().GetProperty(propertyName);

  var oldValue = e.OldValue;
  var newValue = propertyInfo.GetValue(item, null);

  //create command here
}

在属性网格中查找数据的类名:

e.ChangedItem.PropertyDescriptor.ComponentType.Name
然后记录撤销信息,包括类名。因此,当用户撤消更改时,您知道需要撤消哪个类

private void pg_PropertyValueChanged(object s, PropertyValueChangedEventArgs e)
{
        string className = e.ChangedItem.PropertyDescriptor.ComponentType.Name;
        string propertyName = e.ChangedItem.PropertyDescriptor.Name;

        var oldValue = e.OldValue;
        var newValue = e.ChangedItem.Value;

        //Record the above variables in your undo class
        //Something like
        RedoClass.AddToUndoList(className,propertyName,oldValue);
}

一般来说,这对我很有效:

private void prg_PropertyValueChanged(对象s、PropertyValueChangedEventArgs e)
{
变量项=e.ChangedItem;
var propertyName=item.PropertyDescriptor.Name;
PropertyInfo pi=prg.SelectedObject.GetType().GetProperty(propertyName);
var oldValue=e.oldValue;
pi.SetValue(prg.SelectedObject,oldValue,null);
}

其中prg是PropertyGrid的名称

你究竟为什么要编写asm.GetType(item.GetType().FullName)
?我不明白。当我编辑
Width
时,
asm.GetType(item.GetType().FullName)
return
Class A
而不是
Size
。这很明显,因为
属性网格。但我的问题是,当我写这篇文章时,我怎么才能得到
大小
,我没有考虑这种情况。。这是我第一次尝试使用属性网格。我再次查看并将
asm.GetType(item.GetType().FullName)
更改为
item.GetType()
。但这并不能解决问题。。因为问题不是获取
项的
类型,而是获取
属性
父项..它不起作用。我的代码和你的代码一样(我在你回答之前15分钟编辑了我的代码)。我建议的方法正文的第一行与你问题的第一行不同?哦,你是对的。我没有注意到这一点。但是它也不起作用。为了使它起作用,你必须实际实现这个命令。OP是一个新手。您可以使用
e.ChangedItem.Value
而不是
PropertyInfo.GetValue