PropertyGrid:从 CollectionEditor 获取 PropertyValueChanged 通知

发布于 2024-07-08 22:14:20 字数 934 浏览 6 评论 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 调用集合编辑器来编辑此类型。 但是,当集合编辑器关闭时,我没有收到 PropertyValueChanged 通知。

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

但我实际上希望在编辑集合时触发 PropertyValueChanged 事件。 有没有办法在不修改 _MyMemberVariable 的情况下做到这一点(我无权访问其源代码)?

The PropertyGrid control is very useful for editing objects at run-time. I'm using it as follows:

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

As you can see, I'm using the PropertyValueChanged notification to figure out when to update _MyMemberVariable. However, _MyMemberVariable is a class that I didn't write, and one of its members is a Collection type. The PropertyGrid calls the Collection Editor to edit this type. However, when the Collection Editor is closed, I do not get a PropertyValueChanged notification.

Obviously, I could work around this problem by using ShowDialog() and invalidating _MyMemberVariable after the dialog is closed.

But I'd like to actually get PropertyValueChanged events to fire when collections have been edited. Is there a way to do that without modifying _MyMemberVariable (I don't have access to its source code)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

铃予 2024-07-15 22:14:20

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

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

当他们单击其他内容时,我会监听 LostFocus 事件。 对于我的特定用例,这个解决方案就足够了。 我想我会提到它以防其他人发现这有用。

This isn't very elegant, but it solved the issue I was having when someone updates / changes the order of a collection from a property grid:

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

I listen to the LostFocus event when they click on something else. For my particular use case this solution is sufficient. Thought I'd mention it in case someone else finds this useful.

青巷忧颜 2024-07-15 22:14:20

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

通过创建一个新的 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 给我带来了问题。

我希望这可以帮助其他人解决您的问题。

-杰里米

I did some research and even reproduced the problem, however the solution I found won't help you, but I'm hoping the information may help another person help you.

Here goes

The problem is easily reproducable by creating a new windows form project, adding a property grid and a listbox to the form and setting the listbox as the property grid's selected object.

//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!");
        };

    }
}

When editing the items collection of the listbox, the event will never fire, the reason is because the Items property returns a reference to the collection. Since adding items to the collection doesn't actually change the reference when the property never appears to change so the property grid.

The solution I tried would be to extend property grid, and update the logic that compares the two and checks if the data in the collection has changed and call the event. I tried this but the PropertyGrid had an internal class PropertyGridView that caused problems for me.

I hope this helps someone else figure out your problem.

-jeremy

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文