【问题标题】:How to determine when a PropertyGrid control is about to modify an object's property如何确定 PropertyGrid 控件何时要修改对象的属性
【发布时间】:2009-10-10 20:30:53
【问题描述】:

我有一个扩展 PropertyGrid 的控件,它允许用户设置我的一些程序对象的属性。这些对象有一个事件,当它们的某个属性发生更改时会引发该事件,并且 PropertyGrid 订阅此事件,以便在属性更改时刷新自身。 My problem occurs when large numbers of objects are selected, and the user sets a property on all of the objects at once.控件被 Refresh() 请求淹没,这需要很长时间(例如,在打开自动刷新功能的情况下,在大约 300 个对象上设置属性大约需要 20 秒,而在打开自动刷新功能时只需几分之一秒关闭)。

我想阻止事件处理程序在属性网格正在设置属性的过程中刷新网格,但不幸的是我无法找到任何方法来确定网格何时“开始”和“停止”设置属性。我希望有一些方法或我可以覆盖的东西,例如......

override void OnSetPropertyStart()
{
    suppressRefresh = true;
}
override void OnSetPropertyEnd()
{
    suppressRefresh = false;
}

不幸的是,情况似乎并非如此。有没有其他方法可以确定属性网格何时设置属性,或者以其他方式实现相同的效果?

【问题讨论】:

    标签: c# winforms propertygrid


    【解决方案1】:

    类型在您的控制之下吗?您可以添加 FooUpdating / FooUpdated 一对事件吗?另一种选择是使用TypeDescriptionProvider 编写自定义属性模型,但我怀疑这将是很多工作。我的第一次尝试是前/后对...

    类似的东西(更新为显示 3.5 方法;参见历史以获取 2.0 示例):

    class MyType : INotifyPropertyChanged, INotifyPropertyChanging
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public event PropertyChangingEventHandler PropertyChanging;
    
        protected void UpdateField<T>(ref T field, T newValue, string propertyName)
        {
            if (!EqualityComparer<T>.Default.Equals(field, newValue))
            {
                OnPropertyChanging(propertyName);
                field = newValue;
                OnPropertyChanged(propertyName);
            }
        }
        protected void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this,
                new PropertyChangedEventArgs(propertyName));
        }
        protected void OnPropertyChanging(string propertyName)
        {
            PropertyChangingEventHandler handler = PropertyChanging;
            if (handler != null) handler(this,
                new PropertyChangingEventArgs(propertyName));
        }
        private string name;
    
        public string Name
        {
            get { return name; }
            set { UpdateField(ref name, value, "Name"); }
        }
        private DateTime dateOfBirth;
        public DateTime DateOfBirth
        {
            get { return dateOfBirth; }
            set { UpdateField(ref dateOfBirth, value, "DateOfBirth"); }
        }
    }
    

    然后只需处理这两个事件并根据需要启用/禁用更新。

    【讨论】:

    • 在 .NET 3.5 或更高版本上,最好实现框架定义的 INotifyPropertyChanging 接口,而不是创建自定义的 PropertyChanging 事件。这将避免不必要的扩散,并且可以更好地使用框架定义的功能,例如数据绑定。
    • 感谢您的回答 - 我会看看这需要付出多少努力(我有很多不同的对象类型和很多属性,我必须编辑才能做到这一点)。与此同时,我通过限制 PropertyGrid 刷新来缓解这个问题,这样它们只能每 25 毫秒发生一次。这足够快,以至于用户不会注意到它,并且似乎解决了大量 Refresh() 请求一次“堆积”的问题。
    猜你喜欢
    • 2011-08-11
    • 2021-05-15
    • 2019-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-11
    • 2013-03-22
    • 1970-01-01
    相关资源
    最近更新 更多