PropertyGrid没有注意到代码中的属性已更改?

我有一个Winform应用程序,它使用颜色突出显示某些事物。 我想让用户改变’他们’的颜色。 作为练习,我想我会创建一个类的实例,具有颜色属性,并将其分配给属性网格(以获得一个漂亮的编辑器)

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

但是,它似乎在设置我的对象的属性时,属性网格不会改变。 如果在重置后,我执行属性网格“刷新”,它具有重置颜色。

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

在这种情况下是否缺少某些东西,或者我应该接受它并在重置对象时调用Refresh方法?

谢谢

( 这里非常相似的问题)

public partial class Form1 : Form { public Form1() { InitializeComponent(); this.propertyGrid1.SelectedObject = new Colours(); } private void button1_Click(object sender, EventArgs e) { Colours colours = this.propertyGrid1.SelectedObject as Colours; colours.Reset(); } } public partial class Colours : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; public Color ColourP1 { get; set; } public void Reset() { this.ColourP1 = Color.Red; var handler = this.PropertyChanged; if (handler != null) handler(this, new PropertyChangedEventArgs("ColourP1")); } } 

继我的评论“没有订阅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(); } } 

要回答有关PropertyGrid不更改的原因的问题,PropertyGrid的MSDN文档说明:

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

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

你留下了LarsTech的建议并手动刷新网格。

试试吧:

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

假设您将拥有更多属性,则可以使用PropertyChanged事件。 我会像这样修改你的Color类:

 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(); } 

在试图记住我曾经使用的东西并认为它可能对其他人有用时,发生了这个问题。

您可以使用[RefreshProperties]属性来触发对Property Grid的更新。

例如:

  [RefreshProperties(RefreshProperties.All)] public int MyProperty{ get; set; }