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