我有一个Winform应用程序,它使用颜色突出显示某些内容。我想让用户改变'他们'的颜色。作为练习,我想我会创建一个类的实例,其中包含颜色属性,并将其分配给属性网格(以获得一个漂亮的编辑器)。
这似乎工作正常,但我认为我想让用户重置颜色(在他们摆弄并将它们设置为20种米色色调之后)。所以,我在表单中添加了一个“重置”按钮,它将我的对象的颜色属性设置回默认值。
然而,似乎在重新设置对象的属性时,属性网格不会改变。如果在重置后,我执行属性网格“刷新”,则它具有重置颜色。
我假设属性网格不知道底层对象已被更改?
这个场景中是否缺少某些内容,或者我应该接受它并在重置对象时调用Refresh方法?
由于
(非常相似的问题here)
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();
}
}
答案 0 :(得分:11)
要回答有关PropertyGrid未更改的原因的问题,PropertyGrid的MSDN文档说明了这一点:
网格中显示的信息是属性的快照 在分配对象时。如果是对象的属性值 由SelectedObject指定的代码在运行时更改 在网格中执行操作之前,不会显示新值 导致网格刷新。
因此,似乎PropertyGrid不是可自动更新的控件。我认为这样的线索是PropertyGrid使用SelectedObject
方法而不是DataSource
方法,而后者意味着它可能会监听INotifyPropertyChanged。
你留下LarsTech的建议并手动刷新网格。
答案 1 :(得分:8)
尝试刷新它:
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();
}
答案 2 :(得分:6)
在试图记住我曾经使用的内容时发生了这个问题,并认为它可能对其他人有用。
您可以使用[RefreshProperties]属性触发对Property Grid的更新。
例如:
[RefreshProperties(RefreshProperties.All)]
public int MyProperty{ get; set; }
答案 3 :(得分:0)
使用 DotNetBar AdvPropertyGrid控件。您不需要任何iNotify
调用即可对其进行更新。
每当任何对象属性更改时,它都会自动更新网格。