Mark Olbert
2/1/2007 5:53:00 AM
I came up with a solution, but it's pretty ugly. Basically, I walk the subproperty tree of the Style objects in my ControlDesigner,
and put a ValueChange monitor on every single writable subproperty (like I said, this is ugly). Here's the code:
protected override void PreFilterProperties( System.Collections.IDictionary properties )
{
base.PreFilterProperties(properties);
if( properties.Contains("GroupStyle") )
{
PropertyDescriptor propDesc = (PropertyDescriptor) properties["GroupStyle"];
MonitorSubPropChanges(propDesc.GetChildProperties(attrFilter), propDesc.GetValue(Component));
}
if( properties.Contains("LinkStyle") )
{
// attrFilter contains just BrowsableAttribute(true), because I'm only interested in properties I can browse in the
// property grid editor
PropertyDescriptor propDesc = (PropertyDescriptor) properties["LinkStyle"];
MonitorSubPropChanges(propDesc.GetChildProperties(attrFilter), propDesc.GetValue(Component));
}
}
private void MonitorSubPropChanges( PropertyDescriptorCollection props, object propObject )
{
foreach( PropertyDescriptor prop in props )
{
// only monitor read-write properties
if( !prop.IsReadOnly )
prop.AddValueChanged(propObject, new EventHandler(Subprop_Changed));
MonitorSubPropChanges(prop.GetChildProperties(attrFilter), prop.GetValue(propObject));
}
}
private void Subprop_Changed( object sender, EventArgs e )
{
( (BigPicker) Component ).RecreateChildControlsIfNecessary();
}
As the man said, there has >>got<< to be a better way.
Can someone suggest it, please?
- Mark
On Wed, 31 Jan 2007 20:25:49 -0800, Mark Olbert <ChairmanMAO@newsgroups.nospam> wrote:
>I have a custom composite (databound) control with the following property:
>
>[Category("Styles")]
>[DefaultValue(null)]
>[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
>[PersistenceMode(PersistenceMode.InnerProperty)]
>[Description("The style for the single character selection links")]
>public TableStyle GroupStyle
>{
> get
> {
> if( groupStyle == null ) groupStyle = new TableStyle();
>
> return groupStyle;
> }
>
> set
> {
> if( groupStyle != value )
> {
> groupStyle = value;
>
> RecreateChildControlsIfNecessary();
> }
> }
>}
>
>RecreateChildControlsIfNecessary() basically rebuilds the control hierarchy, applying the style (and yes, I've read I shouldn't
>apply styles until rendering do avoid enlarging ViewState, but that's another issue :)).
>
>My problem is this: if, in the VS2005 visual designer I change a subproperty of GroupStyle (say, BackColor) it doesn't update the
>display. The set accessor never gets called.
>
>I've read elsewhere that this is a problem with the property editor for styles. The proposed cure is to build my own custom property
>editor and force it to always create a new instance of TableStyle when any of its subproperties change.
>
>Which seems like a LOT of work to solve a problem caused by some, ahem, fine programmer at Microsoft forgeting to decorate the
>subproperties of the Style object with NotifyParentPropertyAttribute(true) :).
>
>Is there another solution? What is the simplest solution to fix this misbehavior?
>
>- Mark