如何确定PropertyGrid控件何时将修改对象的属性

时间:2009-10-10 20:30:54

标签: c# winforms propertygrid

我有一个控件扩展PropertyGrid,允许用户设置我的一些程序对象的属性。这些对象具有一个事件,当其中一个属性发生更改时会引发该事件,并且PropertyGrid会预订此事件,以便在更改属性时自行刷新。当选择了大量对象时,我的问题就出现了,并且用户一次在所有对象上设置属性。控件淹没了Refresh()请求,这需要很长时间(例如,在自动刷新功能打开的情况下,在~300个对象上设置属性大约需要20秒,而在转动时只需几分之一秒关)。

我想在属性网格处于设置属性的过程中阻止事件处理程序刷新网格,但遗憾的是我无法找到任何方法来确定网格何时“启动”和“停止“设置属性。我希望有可以覆盖的方法或东西,比如......

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

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

1 个答案:

答案 0 :(得分: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"); }
    }
}

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