C# PropertyGrid不';注意不到代码中的属性发生了变化?
我有一个Winform应用程序,它使用颜色来突出显示某些东西。我希望允许用户更改“他们的”颜色。作为练习,我想创建一个类的实例,带有颜色的属性,并将其分配给属性网格(以获得一个好的编辑器) 这似乎很好,但我想我应该让用户重新设置颜色(在他们摆弄并将其设置为20个米色色调之后)。因此,我在表单中添加了一个“重置”按钮,将对象的颜色属性设置回默认值 但是,虽然它设置了对象的属性,但属性网格似乎没有改变。如果重置后,我执行了属性网格“刷新”,则它具有重置颜色 我假设属性网格不知道底层对象已更改 在这个场景中是否缺少一些东西,或者我应该接受它并在重置对象时调用Refresh方法 谢谢 (非常类似的问题)C# PropertyGrid不';注意不到代码中的属性发生了变化?,c#,winforms,data-binding,inotifypropertychanged,propertygrid,C#,Winforms,Data Binding,Inotifypropertychanged,Propertygrid,我有一个Winform应用程序,它使用颜色来突出显示某些东西。我希望允许用户更改“他们的”颜色。作为练习,我想创建一个类的实例,带有颜色的属性,并将其分配给属性网格(以获得一个好的编辑器) 这似乎很好,但我想我应该让用户重新设置颜色(在他们摆弄并将其设置为20个米色色调之后)。因此,我在表单中添加了一个“重置”按钮,将对象的颜色属性设置回默认值 但是,虽然它设置了对象的属性,但属性网格似乎没有改变。如果重置后,我执行了属性网格“刷新”,则它具有重置颜色 我假设属性网格不知道底层对象已更改 在这个
继我的评论“没有订阅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的引用。这比乱搞代码来强制刷新要好得多。这是一种奇怪的回答方式。你确实试图回答这个问题,是吗?