C# PropertyGrid不';注意不到代码中的属性发生了变化?

C# PropertyGrid不';注意不到代码中的属性发生了变化?,c#,winforms,data-binding,inotifypropertychanged,propertygrid,C#,Winforms,Data Binding,Inotifypropertychanged,Propertygrid,我有一个Winform应用程序,它使用颜色来突出显示某些东西。我希望允许用户更改“他们的”颜色。作为练习,我想创建一个类的实例,带有颜色的属性,并将其分配给属性网格(以获得一个好的编辑器) 这似乎很好,但我想我应该让用户重新设置颜色(在他们摆弄并将其设置为20个米色色调之后)。因此,我在表单中添加了一个“重置”按钮,将对象的颜色属性设置回默认值 但是,虽然它设置了对象的属性,但属性网格似乎没有改变。如果重置后,我执行了属性网格“刷新”,则它具有重置颜色 我假设属性网格不知道底层对象已更改 在这个

我有一个Winform应用程序,它使用颜色来突出显示某些东西。我希望允许用户更改“他们的”颜色。作为练习,我想创建一个类的实例,带有颜色的属性,并将其分配给属性网格(以获得一个好的编辑器)

这似乎很好,但我想我应该让用户重新设置颜色(在他们摆弄并将其设置为20个米色色调之后)。因此,我在表单中添加了一个“重置”按钮,将对象的颜色属性设置回默认值

但是,虽然它设置了对象的属性,但属性网格似乎没有改变。如果重置后,我执行了属性网格“刷新”,则它具有重置颜色

我假设属性网格不知道底层对象已更改

在这个场景中是否缺少一些东西,或者我应该接受它并在重置对象时调用Refresh方法

谢谢

(非常类似的问题)


继我的评论“没有订阅INotifyPropertyChanged.PropertyChanged”之后,对PropertyGrid控件进行子分类的缺点是什么

public partial class MyPropertyGrid : System.Windows.Forms.PropertyGrid
{
  private INotifyPropertyChanged _selectedObject;

  protected override void OnSelectedObjectsChanged(EventArgs e)
  {
     base.OnSelectedObjectsChanged(e);

     if (_selectedObject != null) _selectedObject.PropertyChanged -= selectedObject_PropertyChanged;
     _selectedObject = this.SelectedObject as INotifyPropertyChanged;
     if (_selectedObject != null) _selectedObject.PropertyChanged += selectedObject_PropertyChanged;
  }

  private void selectedObject_PropertyChanged(object sender, PropertyChangedEventArgs e)
  {
     this.Refresh();
  }
}

只要尝试刷新它:

private void button1_Click(object sender, EventArgs e)
{
  Colours colours = this.propertyGrid1.SelectedObject as Colours;
  colours.Reset();
  this.propertyGrid1.Refresh();
}
假设您将拥有更多属性,您可以使用
PropertyChanged
事件。我将修改您的颜色类,如下所示:

public class Colours : INotifyPropertyChanged {
  public event PropertyChangedEventHandler PropertyChanged;

  private Color _ColourP1;

  public void Reset() {
    this.ColourP1 = Color.Red;
  }

  private void OnChanged(string propName) {
    if (PropertyChanged != null)
      PropertyChanged(this, new PropertyChangedEventArgs(propName));
  }

  public Color ColourP1 {
    get { return _ColourP1; }
    set {
      _ColourP1 = value;
      OnChanged("ColourP1");
    }
  }
}
public Form1() {
  InitializeComponent();

  Colours colours = new Colours();
  colours.PropertyChanged += colours_PropertyChanged;
  this.propertyGrid1.SelectedObject = colours;
}

private void colours_PropertyChanged(object sender, PropertyChangedEventArgs e) {
  this.propertyGrid1.Refresh();
}

private void button1_Click(object sender, EventArgs e) {
  ((Colours)this.propertyGrid1.SelectedObject).Reset();
}
那么您的表单将如下所示:

public class Colours : INotifyPropertyChanged {
  public event PropertyChangedEventHandler PropertyChanged;

  private Color _ColourP1;

  public void Reset() {
    this.ColourP1 = Color.Red;
  }

  private void OnChanged(string propName) {
    if (PropertyChanged != null)
      PropertyChanged(this, new PropertyChangedEventArgs(propName));
  }

  public Color ColourP1 {
    get { return _ColourP1; }
    set {
      _ColourP1 = value;
      OnChanged("ColourP1");
    }
  }
}
public Form1() {
  InitializeComponent();

  Colours colours = new Colours();
  colours.PropertyChanged += colours_PropertyChanged;
  this.propertyGrid1.SelectedObject = colours;
}

private void colours_PropertyChanged(object sender, PropertyChangedEventArgs e) {
  this.propertyGrid1.Refresh();
}

private void button1_Click(object sender, EventArgs e) {
  ((Colours)this.propertyGrid1.SelectedObject).Reset();
}

要回答您关于PropertyGrid为何不更改的问题,请参阅该应用程序的MSDN文档,并说明以下内容:

网格中显示的信息是属性的快照 在指定对象时。如果对象的属性值 由SelectedObject指定的值在运行时在代码中发生更改 在网格中执行操作之前,不会显示新值 使网格刷新

因此,PropertyGrid似乎不是一个可自动更新的控件。我认为这方面的线索是PropertyGrid使用
SelectedObject
方法而不是
DataSource
方法,后者意味着它可能侦听INotifyPropertyChanged


您只需了解LarsTech的建议并手动刷新网格。

在试图记住我过去使用的内容并认为它可能对其他人有用时,遇到了这个问题

您可以使用[RefreshProperties]属性触发对属性网格的更新

例如:


使用DotNetBar AdvPropertyGrid控件。您不需要任何
iNotify
调用来更新它。

它会在任何对象属性发生更改时自动更新网格。

您好,谢谢,这几乎就是我已经拥有的。我更感兴趣的是为什么属性网格本身没有注意到属性发生了变化。没有任何内容(即PropertyGrid控件)订阅“PropertyChanged”事件。当然我可以像你一样自己做,但为什么?可能是PropertyGrid控件没有绑定属性,因此不侦听INotifyPropertyChanged事件吗?是的,这基本上概括了它。这对我来说很有效,只需添加对System.ComponentModel的引用。这比乱搞代码来强制刷新要好得多。这是一种奇怪的回答方式。你确实试图回答这个问题,是吗?