PropertyGrid:从CollectionEditor获取PropertyValueChanged通知

时间:2008-11-11 23:28:27

标签: c# winforms .net-2.0

PropertyGrid控件对于在运行时编辑对象非常有用。我正在使用它如下:

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的情况下做到这一点(我无法访问其源代码)?

2 个答案:

答案 0 :(得分:2)

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

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

我在点击其他内容时听取LostFocus事件。对于我的特定用例,这个解决方案就足够了。以为我会提到它,以防其他人认为这有用。

答案 1 :(得分:0)

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

这是

通过创建新的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