How to determine when a PropertyGrid control is about to modify an object's property
I have a control extending PropertyGrid which allows users to set the properties of some of my program objects. These objects have an event which is raised when one of their properties changes, and the PropertyGrid subscribes to this event so that it refreshes itself when a property is changed. My problem occurs when large numbers of objects are selected开发者_Go百科, and the user sets a property on all of the objects at once. The control gets swamped with Refresh() requests, which take a long time (for example, setting a property on ~300 objects takes about 20 seconds with the auto-refresh feature turned on, and just a fraction of a second when it is turned off).
I would like to prevent the event handler from refreshing the grid while the property grid is in the process of setting a property, but unfortunately I haven't been able to find any way to determine when the grid "starts" and "stops" setting the property. I was hoping there would be methods or something I could override, such as...
override void OnSetPropertyStart()
{
suppressRefresh = true;
}
override void OnSetPropertyEnd()
{
suppressRefresh = false;
}
Unfortunately this doesn't seem to be the case. Is there any other way to determine when the property grid is setting a property, or to otherwise achieve this same effect?
Is the type under your control? You could add a FooUpdating
/ FooUpdated
pair of events? Another option would be to write a custom property-model with TypeDescriptionProvider
, but I suspect that would be quite a lot of work. My first attempt would be a before/after pair...
Something like (updated to show 3.5 approach; see history for a 2.0 example):
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"); }
}
}
Then just handle the two events and enable / disable updates as appropriate.
精彩评论