ISupportInitialize for ASP.NET?

Ask a Question related to ASP.NET Building Controls, Design and Development.

  1. #1

    Default ISupportInitialize for ASP.NET?

    From my testing ISupportInitialize is not honored in ASP.NET We have a
    control like the following...

    <ni:Meter ID="Meter1" runat="server" Range="67, 73" Value="70" >
    </ni:Meter>

    The Value property checks the range and throws an exception if the range is
    outside its value. The default for the Range is 0-10. The trouble is when a
    user saves the above mark up and closes the designer and reopens it, the
    ASP.NET designer first tries to set the value to 70 before the range has been
    set. The exception is thrown because the range is still its default value of
    0-10. Interestingly, at run time the Range is set first so there is no issue.
    It seems the evaluation of properties is inconsistant:

    RunTime -> left to right
    DesignTime -> right to left.

    Is there anyway I can influence the ordering of properties or set them
    together somehow?
    breeve Guest

  2. #2

    Default RE: ISupportInitialize for ASP.NET?

    Hello Breeve,

    As for the custom webserver control, the design-time property setting and
    persisting does differ from runtime property setting. At runtime, the
    control will initializing the properties according to their sequence in the
    inline aspx template.

    For your scenario, I suggest you separate the validation code (for
    design-time and runtime) into two places:

    1. For runtime validation, you can still put them in the property's setter
    method, but you need to check whether the code is running in ASP.NET
    runtime(or in design-time surface). e.g:

    =================
    if (this.DesignMode)
    {
    ...
    }
    ==================

    2. For design-time valiation, I suggest you consider put the validatino
    code in a custom control designer, since there're some methods in the
    ControlDesigner class in which we can validate the properties:

    #ControlDesigner Class
    [url]http://msdn2.microsoft.com/en-us/library/system.web.ui.design.controldesigne[/url]
    r.aspx

    For example, you can override the designer's "GetDesignTimeHtml" method and
    do the valiadtion against the two properties there since this method is
    called then the deigner will refresh the control's html in deigner surface.

    Hope this helps.


    Sincerely,

    Steven Cheng

    Microsoft MSDN Online Support Lead



    This posting is provided "AS IS" with no warranties, and confers no rights.

    Steven Cheng[MSFT] Guest

  3. #3

    Default RE: ISupportInitialize for ASP.NET?

    If I throw an exception inside of ControlDesigner.GetDesignTimeHtml it
    doesn't get propagated to the user. It is swallowed somewhere up the call
    stack. This is a problem with the approach you suggested above. A user can
    edit the mark up themselves. When I set the Range and Value (int that order)
    in GetDesignTimeHtml I need to let the user know if the value is outside the
    range.

    A better approach, and something I have looked at before, is to use a custom
    ControlBuilder. What I would like to do is to call
    ISupportInitialize.BeginInit before the control is initialized and
    ISupportInitialize.EndInit after. We already have logic in place for this to
    work on the control. Looking at the ControlBuilder API, there is a
    BuildObject method that is virtual. I would like to override this and get the
    instance of the created control and call BeginInit on it. The problem is the
    API does not let me do this. If I call the base version it creates the
    control and there is no way for me to access the control before it starts to
    set properties. For example,

    public override object BuildObject()
    {
    //I would like to Create the instance and pass it to BuildObject so I can call
    //BeginInit on it. If I call the base, the base doesn't let me hook in
    anywhere.
    object buildObject = base.BuildObject();
    //This is too late to call BeginInit. The properties have already been set.
    }

    I guess the issue is how can I get a reference in ControlBuilder of the
    build object without doing everything myself (building the entire object
    myself)?

    breeve Guest

  4. #4

    Default RE: ISupportInitialize for ASP.NET?

    Thanks for your reply Breeve,

    Yes, throw an exception in GetDesignTimeHtml method won't behave quite same
    as in runtime code. However, since the GetDesignTimeHtml method just return
    the html code which will be displayed on design surface, you can return the
    error info as return value.

    BTW, as for the exception handling, the design-time service does capture
    the exception internally, however, you can override the
    ControlDesigner.GetErrorDesignTimeHtml method. And when we throw exception
    in GetDesignTimeHtml method, this will trigger the "GetErrorDesignTimeHtml"
    method and we can return our own error message. e.g.

    ==================
    protected override string GetErrorDesignTimeHtml(Exception e)
    {
    return e.ToString();
    }
    ===================

    Sincerely,

    Steven Cheng

    Microsoft MSDN Online Support Lead


    This posting is provided "AS IS" with no warranties, and confers no rights.


    Steven Cheng[MSFT] Guest

  5. #5

    Default RE: ISupportInitialize for ASP.NET?

    For the interested, I was able to get this to work throught
    ControlBuilder.Init function. It took awhile to figure out because there is
    no documentation:


    private class NumericPointerBuilder : ControlBuilder
    {
    public override void Init(TemplateParser parser, ControlBuilder
    parentBuilder, Type type, string tagName, string id, IDictionary attribs)
    {
    IDictionary order = new Order(attribs);
    base.Init(parser, parentBuilder, type, tagName, id, order);
    }

    private class Order : Hashtable
    {
    public Order(IDictionary items)
    : base(items)
    {
    }

    public override IDictionaryEnumerator GetEnumerator()
    {
    return new Enumerator(this);
    }

    private class Enumerator : IDictionaryEnumerator
    {
    private const string ValueProperty = "Value";
    private const string RangeProperty = "Range";

    private List<DictionaryEntry> _list;
    private int _currentIndex;

    public Enumerator(Hashtable hashTable)
    {
    _currentIndex = -1;
    _list = new List<DictionaryEntry>();

    // getting the IEnumerable interface to call the
    explicit implementation
    // to aviod a recrusive stack overflow here.
    IEnumerable enumerable = hashTable;
    int valueKeyIndex = -1;

    foreach (DictionaryEntry entry in enumerable)
    {
    if (entry.Key is string && ((string)entry.Key)
    == ValueProperty)
    {
    valueKeyIndex = _list.Count;
    }
    if (entry.Key is string && ((string)entry.Key)
    == RangeProperty)
    {
    //Value property has been added
    if (valueKeyIndex != -1)
    {
    //Insert range property before Value
    property.
    _list.Insert(valueKeyIndex, entry);
    continue;
    }
    }

    _list.Add(entry);
    }
    }

    public void Reset()
    {
    _currentIndex = -1;
    }

    public object Current
    {
    get
    {
    return Entry;
    }
    }

    public bool MoveNext()
    {
    _currentIndex++;
    if (_currentIndex >= _list.Count)
    {
    _currentIndex = _list.Count;
    return false;
    }

    return true;
    }


    public DictionaryEntry Entry
    {
    get
    {
    if (_currentIndex < _list.Count && _currentIndex
    >= 0)
    return _list[_currentIndex];
    else
    throw ExceptionBuilder.InvalidOperation();
    }
    }

    public object Key
    {
    get
    {
    return Entry.Key;
    }
    }

    public object Value
    {
    get
    {
    return Entry.Value;
    }
    }
    }
    }
    }

    breeve Guest

Posting Permissions

  • You may not post new threads
  • You may post replies
  • You may not post attachments
  • You may not edit your posts

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139