locked
Inheriting from DynamicControl RRS feed

  • Question

  • User-1825738080 posted

    I am creating my own derivative class because my solution requires custom attributes to mark properties as [EditableBoolean] and [EditableTextBox]

    I would like to use reflection inside the control to determine the properties for the DynamicControl.

     

    1            protected override void OnInit(EventArgs e)
    2            {
    3                base.OnInit(e);
    4                DecorateDynamicControlFeild(this.Column.EntityTypeProperty);
    5            }
    

     It turns out I have to perform the decorating after the initialization of the control because that is when DynamicControl populates the Column property (which I need for reflection).

    The only problem is that the UIHint seems to be used in the initialization of the control and setting it after has no effect.

    Work around? Suggestions?

    Friday, December 26, 2008 11:55 AM

Answers

  • User-797310475 posted

    I would like to use reflection inside the control to determine the properties for the DynamicControl.

    It turns out I have to perform the decorating after the initialization of the control because that is when DynamicControl populates the Column property (which I need for reflection).

    The only problem is that the UIHint seems to be used in the initialization of the control and setting it after has no effect.

    To clarify your scenario, what you are trying to do is: have a derived DynamicControl control where in the OnInit method you are trying to modify the value of the UIHint property based on some custom attributes you have declared on the column in order to affect which field template gets loaded. However, you cannot do so because the setting of the Column property and the loading and initialization of the field template happens in one step in OnInit (let me know if i've missed something).

    So basically you need to get the value of Column. This can easily be done by copying the code that DynamicControl performs in OnInit. Would somethign like the following work as a workaround for you?

    protected override void OnInit(EventArgs e) {
        if (!DesignMode) {
            MetaColumn column = Table.GetColumn(DataField);
            DecorateDynamicControlField(column.EntityTypeProperty);
        }
        base.OnInit(e);
    }
     
    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, December 30, 2008 3:38 PM

All replies

  • User-330204900 posted

    Create your own control (inheriting DynamicField) and then use a mapping in the web.config to swap out the normal DynamicField see example: 

    <pages>
      <controls>
    ...

    </controls> <tagMapping> <add tagType="System.Web.DynamicData.FilterRepeater" mappedTagType="Microsoft.Web.DynamicData.AdvancedFilterRepeater" /> </tagMapping> </pages>

    In the above example from the DD Futures sample site you can see that FilterFepeater is swapped out for the AdvancedFilterRepeater. This allows you to swap out any control without rewriting every page it's on [:D] one of my favorite thins I found out while digging about in DD.

    Hope this helps [:D]

    Friday, December 26, 2008 12:38 PM
  • User-1825738080 posted

    Here is my solution.

    Create my own typedescription provider and do the decorating there.

    Thanks to sjnaighton for his post on custom meta model providers. It pointed me in the right direction.

     

        public class DefaultAttributesTypeDescriptor : CustomTypeDescriptor
    {
    private Type Type { get; set; }

    public DefaultAttributesTypeDescriptor(ICustomTypeDescriptor parent, Type type)
    : base(parent)
    {
    this.Type = type;
    }


    public override PropertyDescriptorCollection GetProperties()
    {
    List<propertydescriptor> propertyDescriptors = new List<propertydescriptor>();

    foreach (PropertyDescriptor propDescriptor in base.GetProperties())
    {


    if(propDescriptor.HasAttribute<editableattribute>())
    {
    List<attribute> newAttributes = new List<attribute>();
    EditableAttribute attribute = null;
    foreach(Attribute a in propDescriptor.Attributes)
    {
    attribute = a as EditableAttribute;
    if (attribute != null)
    {
    break;
    }
    }

    newAttributes.Add(new UIHintAttribute(attribute.TemplateName));
    propertyDescriptors.Add(new WrappedPropertyDescriptor(propDescriptor, newAttributes.ToArray()));
    }

    }
    return new PropertyDescriptorCollection(propertyDescriptors.ToArray(),true);
    }


    private class WrappedPropertyDescriptor : PropertyDescriptor
    {
    private PropertyDescriptor _wrappedPropertyDescriptor;

    public WrappedPropertyDescriptor(PropertyDescriptor wrappedPropertyDescriptor, Attribute[] attributes)
    : base(wrappedPropertyDescriptor, attributes)
    {
    _wrappedPropertyDescriptor = wrappedPropertyDescriptor;
    }

    public override bool CanResetValue(object component)
    {
    return _wrappedPropertyDescriptor.CanResetValue(component);
    }

    public override Type ComponentType
    {
    get { return _wrappedPropertyDescriptor.ComponentType; }
    }

    public override object GetValue(object component)
    {
    return _wrappedPropertyDescriptor.GetValue(component);
    }

    public override bool IsReadOnly
    {
    get { return _wrappedPropertyDescriptor.IsReadOnly; }
    }

    public override Type PropertyType
    {
    get { return _wrappedPropertyDescriptor.PropertyType; }
    }

    public override void ResetValue(object component)
    {
    _wrappedPropertyDescriptor.ResetValue(component);
    }

    public override void SetValue(object component, object value)
    {
    _wrappedPropertyDescriptor.SetValue(component, value);
    }

    public override bool ShouldSerializeValue(object component)
    {
    return _wrappedPropertyDescriptor.ShouldSerializeValue(component);
    }
    }



    }</attribute></attribute></editableattribute></propertydescriptor></propertydescriptor>
      

     

    Saturday, December 27, 2008 1:49 AM
  • User-330204900 posted

    Hi Theonlylawislove, one small point you can only run the TypeDesriptor once, at the same time as using the in memory metadata provider from DD Futures which would allow you to do pretty much the same thing. Where as wrapping the DynamicField control with your own would allow you to dynamically chaqnge the UIHint whilst runnung [:D]

    Also it was Matt Berseth who wrote the original article and my thanks goes to him [:D]

    Saturday, December 27, 2008 4:03 AM
  • User-797310475 posted

    I would like to use reflection inside the control to determine the properties for the DynamicControl.

    It turns out I have to perform the decorating after the initialization of the control because that is when DynamicControl populates the Column property (which I need for reflection).

    The only problem is that the UIHint seems to be used in the initialization of the control and setting it after has no effect.

    To clarify your scenario, what you are trying to do is: have a derived DynamicControl control where in the OnInit method you are trying to modify the value of the UIHint property based on some custom attributes you have declared on the column in order to affect which field template gets loaded. However, you cannot do so because the setting of the Column property and the loading and initialization of the field template happens in one step in OnInit (let me know if i've missed something).

    So basically you need to get the value of Column. This can easily be done by copying the code that DynamicControl performs in OnInit. Would somethign like the following work as a workaround for you?

    protected override void OnInit(EventArgs e) {
        if (!DesignMode) {
            MetaColumn column = Table.GetColumn(DataField);
            DecorateDynamicControlField(column.EntityTypeProperty);
        }
        base.OnInit(e);
    }
     
    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, December 30, 2008 3:38 PM
  • User-1825738080 posted

    Thats exactly what I was looking for!

    After working the the TypeDescriptionProvider, I realized that this is the best place to parse my custom attributes.

    Thursday, January 1, 2009 1:57 PM