PropertyGrid没有注意到代码中的属性已更改? [英] PropertyGrid doesn't notice properties changed in code?

查看:124
本文介绍了PropertyGrid没有注意到代码中的属性已更改?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



这似乎工作正常,但是我以为我想让用户重新设置颜色(之后他们已经搞定了,并将它们设置为20色米色)。所以我添加了一个重置按钮到我的表单,它将我的对象的颜色属性设置为默认值。



但是,它似乎设置我的对象的属性返回,属性网格不会更改。如果在重置之后,我做了一个属性网格刷新,它具有重置颜色。



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



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



谢谢



(非常类似的问题这里

  public partial class Form1:Form 
{
public Form1()
{
InitializeComponent();

this.propertyGrid1.SelectedObject = new Colors();
}

private void button1_Click(object sender,EventArgs e)
{
颜色颜色= this.propertyGrid1.SelectedObject为颜色;
colours.Reset();
}
}

public partial class颜色:INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;

public Color ColourP1 {get;组; }

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为INotifyPropertyChanged;
if(_selectedObject!= null)_selectedObject.PropertyChanged + = selectedObject_PropertyChanged;
}

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


解决方案

回答您的问题,为什么PropertyGrid不会更改,MSDN文档为 PropertyGrid 说这个:


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


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



您将留下LarsTech提出的建议并手动刷新网格。


I have a Winform application which uses colour to highlight certain things. I would like to allow the users to change 'their' colours. As an exercise, I thought I would create an instance of a class, with properties for the colours, and assign it to a property grid (to get a nice editor).

This seems to work fine, but I then thought I would like to let the users reset the colours (after they had fiddled and set them to 20 shades of beige). So, I added a "reset" button to my form, which set the colour properties of my object back to the defaults.

However, it seems that while it sets my object's properties back, the property grid doesn't change. If, after the reset, I do a property grid "Refresh", it has the reset colour.

I'm assuming that the property grid doesn't know that the underlying object has been changed ?

Is there something missing in this scenario, or should I just accept it and call the Refresh method when I reset my object ?

Thanks

(very similar question 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"));
  }
}


Following on from my comment of "nothing subscribes to the INotifyPropertyChanged.PropertyChanged", what's the drawback in subsclassing the PropertyGrid control so that it does ?

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

解决方案

To answer your question on why the PropertyGrid doesn't change, the MSDN documentation for the PropertyGrid say this:

The information displayed in the grid is a snapshot of the properties at the time the object is assigned. If a property value of the object specified by the SelectedObject is changed in code at run time, the new value is not displayed until an action is taken in the grid that causes the grid to refresh.

So, it seems that the PropertyGrid is not a control that is auto-updatable. I think the clue to this is that the PropertyGrid uses the SelectedObject method instead of a DataSource method, and the latter would imply it probably listens to INotifyPropertyChanged.

You're left with what LarsTech has suggested and manually refreshing the grid.

这篇关于PropertyGrid没有注意到代码中的属性已更改?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆