2008-11-11 73 views
1

PropertyGrid控件对于在运行时编辑对象非常有用。PropertyGrid:从CollectionEditor获取PropertyValueChanged通知

Form form = new Form(); 
form.Parent = this; 
form.Text = "Editing MyMemberVariable"; 

PropertyGrid p = new PropertyGrid(); 
p.Parent = form; 
p.Dock = DockStyle.Fill; 
p.SelectedObject = _MyMemberVariable; 
p.PropertyValueChanged += delegate(object s, PropertyValueChangedEventArgs args) 
{ 
    _MyMemberVariable.Invalidate(); 
}; 

form.Show(); 

正如你所看到的,我使用的是PropertyValueChanged通知弄清楚何时更新_MyMemberVariable:我如下使用它。但是,_MyMemberVariable是我没有写的类,其中一个成员是Collection类型。 PropertyGrid调用Collection Editor来编辑此类型。但是,收藏编辑器关闭时,我没有收到PropertyValueChanged通知。

显然,我可以通过使用ShowDialog()解决此问题,并在对话框关闭后使_MyMemberVariable无效。

但是,我希望在编辑收藏集时实际获取PropertyValueChanged事件。有没有办法做到这一点,而不修改_MyMemberVariable(我没有访问其源代码)?

回答

1

我做了一些研究,甚至重现了这个问题,但是我找到的解决方案不会帮助你,但我希望这些信息可以帮助别人帮助你。

这里去

的问题是通过创建一个新的Windows窗体项目,添加属性网格和列表框的形式和设置列表框的属性网格的选择对象很容易可再现的。

//designer code excluded 
public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 

     propertyGrid1.SelectedObject = listBox1; 

     propertyGrid1.PropertyValueChanged += delegate(object s, PropertyValueChangedEventArgs args) 
     { 
      MessageBox.Show("Invalidate Me!"); 
     }; 

    } 
} 

编辑列表框的项目集合时,事件永远不会触发,原因是因为Items属性返回对集合的引用。由于将属性添加到集合实际上并未改变引用,因此属性从未出现更改,因此属性网格。

我试过的解决方案是扩展属性网格,并更新比较两者的逻辑并检查集合中的数据是否已更改并调用事件。我试过这个,但PropertyGrid有一个内部类PropertyGridView,对我造成了问题。

我希望这可以帮助别人找出你的问题。

-jeremy

2

这是不是很优雅,但它解决了,当有人更新我遇到的问题/改变的集合从属性网格顺序:

propertyGrid1.PropertyValueChanged += (o, args) => PropertyGridValueChanged(); 
propertyGrid1.LostFocus += (sender, args) => PropertyGridValueChanged(); 

我听当他们点击别的东西时,他们会看到LostFocus事件。对于我的特殊用例,这个解决方案就足够了。以为我会提到它以防别人认为这有用。