Refresh design time HTML on style change

Discussion in 'ASP .Net Building Controls' started by TJoker .NET, Feb 20, 2004.

  1. TJoker .NET

    TJoker .NET Guest

    Hi, in my control I have some properties that are style objects (ex of type
    TableItemStyle)
    One example is below:

    private TableItemStyle _itemStyle;

    [
    Category("Style"),
    Description("whatever...."),
    DesignerSerializationVisibility(
    DesignerSerializationVisibility.Content),
    NotifyParentProperty(true),
    PersistenceMode(PersistenceMode.InnerProperty)
    ]
    public TableItemStyle ItemStyle {
    get {
    if (_itemStyle == null) {
    _itemStyle = new TableItemStyle();
    if (IsTrackingViewState) {
    ((IStateManager)_itemStyle).TrackViewState();
    }
    }
    return _itemStyle;
    }
    }

    When the developer changes the style settings in this property, using the
    properties window, the design time view of the control does not get
    refreshed. What can I do to make the changes to the style proeprties be
    reflected in the design time view ?

    Thanks.
    --
    TJoker
    MVP: Paint, Notepad, Solitaire

    ****************************************
     
    TJoker .NET, Feb 20, 2004
    #1
    1. Advertising

  2. Make sure your Render method rebuilds and outputs the appropriate HTML
    to the HtmlTextWriter every time it is called.

    The following example would NOT update on style changes:

    private bool _isRendered = false;
    public override void Render( HtmlTextWriter output )
    {
    if( ! this._isRendered )
    {
    // Rendering logic
    this._isRendered = true;
    }
    }

    If you've implemented a DataBind( ) method, you need to call it every
    time the Render method is called as well, especially if you put HTML
    rendering logic in the DataBind( ) method (I use DataBind to build an
    HtmlTable and then simply call HtmlTableRenderControl( ) on the Render
    method's HtmlTextWriter. I have to call DataBind( ) explicitly in each
    and every call to the Render( ) method to ensure styles are updated,
    however).

    The other thing you might want to check is that PersistenceMode and
    viewstate stuff...I've never really messed with that before, so I
    can't help, but I've never used it and my stuff has so far turned out
    okay.

    Hope that helps,

    - Jesse



    "TJoker .NET" <> wrote in message news:<>...
    > Hi, in my control I have some properties that are style objects (ex of type
    > TableItemStyle)
    > One example is below:
    >
    > private TableItemStyle _itemStyle;
    >
    > [
    > Category("Style"),
    > Description("whatever...."),
    > DesignerSerializationVisibility(
    > DesignerSerializationVisibility.Content),
    > NotifyParentProperty(true),
    > PersistenceMode(PersistenceMode.InnerProperty)
    > ]
    > public TableItemStyle ItemStyle {
    > get {
    > if (_itemStyle == null) {
    > _itemStyle = new TableItemStyle();
    > if (IsTrackingViewState) {
    > ((IStateManager)_itemStyle).TrackViewState();
    > }
    > }
    > return _itemStyle;
    > }
    > }
    >
    > When the developer changes the style settings in this property, using the
    > properties window, the design time view of the control does not get
    > refreshed. What can I do to make the changes to the style proeprties be
    > reflected in the design time view ?
    >
    > Thanks.
     
    Jesse Sweetland, Feb 20, 2004
    #2
    1. Advertising

  3. TJoker .NET

    TJoker .NET Guest

    Jesse, thanks for the response but that's not exaclty my
    case. I'm creating a composite control, overrding the
    CreateChildControls method and leaving the Render method
    alone.
    Let me give you an example.
    In any property of my control that changes its visible
    HTML (like texts, colors, etc) I do something like this:
    public string SomeLabelText
    {
    get
    {
    string o = (string)ViewState
    ["SomeLabelText"];
    return (o == null)?"":eek:;
    }
    set
    {
    ViewState["SomeLabelText"] = value;
    //force it to rebuild control tree
    if(base.HasControls()) {base.Controls.Clear
    (); ChildControlsCreated=false;};
    }
    }

    But my Style proporties return only have "get" accessors
    because they return the Style object, so I cannot detect
    when the Style object's properties are being changed:

    public virtual Style SomeStyle()
    {
    get
    {
    if (this.privateSomeStyle == null)
    {
    this.privateSomeStyle = new Style();
    if (base.IsTrackingViewState)
    {

    this.privateSomeStyle.TrackViewState();
    }
    }
    return this.privateSomeStyle;
    }
    }

    There are no events to help me and I couldn't find any
    attribute to put in the Style property to cause my control
    to refresh. I think I'm implementing this similarly to how
    the DataGrid control does, but I couldn't figure out how
    it works for the DataGrid.

    Thanks.

    --
    TJoker
    MVP: Paint, Notepad, Solitaire

    ****************************************

    >-----Original Message-----
    >Make sure your Render method rebuilds and outputs the

    appropriate HTML
    >to the HtmlTextWriter every time it is called.
    >
    >The following example would NOT update on style changes:
    >
    >private bool _isRendered = false;
    >public override void Render( HtmlTextWriter output )
    >{
    > if( ! this._isRendered )
    > {
    > // Rendering logic
    > this._isRendered = true;
    > }
    >}
    >
    >If you've implemented a DataBind( ) method, you need to

    call it every
    >time the Render method is called as well, especially if

    you put HTML
    >rendering logic in the DataBind( ) method (I use DataBind

    to build an
    >HtmlTable and then simply call HtmlTableRenderControl( )

    on the Render
    >method's HtmlTextWriter. I have to call DataBind( )

    explicitly in each
    >and every call to the Render( ) method to ensure styles

    are updated,
    >however).
    >
    >The other thing you might want to check is that

    PersistenceMode and
    >viewstate stuff...I've never really messed with that

    before, so I
    >can't help, but I've never used it and my stuff has so

    far turned out
    >okay.
    >
    >Hope that helps,
    >
    >- Jesse
    >
    >
    >
    >"TJoker .NET" <> wrote in message

    news:<>...
    >> Hi, in my control I have some properties that are style

    objects (ex of type
    >> TableItemStyle)
    >> One example is below:
    >>
    >> private TableItemStyle _itemStyle;
    >>
    >> [
    >> Category("Style"),
    >> Description("whatever...."),
    >> DesignerSerializationVisibility(
    >> DesignerSerializationVisibility.Content),
    >> NotifyParentProperty(true),
    >> PersistenceMode(PersistenceMode.InnerProperty)
    >> ]
    >> public TableItemStyle ItemStyle {
    >> get {
    >> if (_itemStyle == null) {
    >> _itemStyle = new TableItemStyle();
    >> if (IsTrackingViewState) {
    >> ((IStateManager)

    _itemStyle).TrackViewState();
    >> }
    >> }
    >> return _itemStyle;
    >> }
    >> }
    >>
    >> When the developer changes the style settings in this

    property, using the
    >> properties window, the design time view of the control

    does not get
    >> refreshed. What can I do to make the changes to the

    style proeprties be
    >> reflected in the design time view ?
    >>
    >> Thanks.

    >.
    >
     
    TJoker .NET, Feb 23, 2004
    #3
  4. "TJoker .NET" <> wrote in message
    news:1458901c3fa2a$22cd34b0$...
    > Jesse, thanks for the response but that's not exaclty my
    > case. I'm creating a composite control, overrding the
    > CreateChildControls method and leaving the Render method
    > alone.
    > Let me give you an example.
    > In any property of my control that changes its visible
    > HTML (like texts, colors, etc) I do something like this:
    > public string SomeLabelText
    > {
    > get
    > {
    > string o = (string)ViewState
    > ["SomeLabelText"];
    > return (o == null)?"":eek:;
    > }
    > set
    > {
    > ViewState["SomeLabelText"] = value;
    > //force it to rebuild control tree
    > if(base.HasControls()) {base.Controls.Clear
    > (); ChildControlsCreated=false;};
    > }
    > }



    Why don't you just set ChildControlsCreated to false? You don't have to
    clear the Controls collection.
    --
    John Saunders
    John.Saunders at SurfControl.com
     
    John Saunders, Feb 24, 2004
    #4
  5. "TJoker .NET" <> wrote in message
    news:1458901c3fa2a$22cd34b0$...
    > Jesse, thanks for the response but that's not exaclty my
    > case. I'm creating a composite control, overrding the
    > CreateChildControls method and leaving the Render method
    > alone.


    BTW, try the RefreshProperties attribute:

    [Category("Style"),
    Description("The style for the table caption"),
    DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
    NotifyParentProperty(true)]
    [RefreshProperties(RefreshProperties.Repaint)]
    [PersistenceMode(PersistenceMode.Attribute)]
    public Style CaptionStyle
    {
    get
    {
    if (captionStyle == null)
    {
    captionStyle = new Style();
    if (IsTrackingViewState)
    ((IStateManager) captionStyle).TrackViewState();
    }
    return captionStyle;
    }
    }

    --
    John Saunders
    John.Saunders at SurfControl.com
     
    John Saunders, Feb 24, 2004
    #5
  6. TJoker .NET

    TJoker .NET Guest

    John, the problem here is that the RefreshProperties (I
    think) is considered only if I change the value of the
    property, exactly what I'm not doing. In this case I'm
    changing the value of a subproperty of the Style class, I
    don't even have a "set" accessor for my ow property.
    I tried and as I suspected it didn;t work, unfortunately.
    I would think that the Style class would have some
    attribute to help here but it doesn't seem to.

    Thanks for the response.

    TJ!

    --
    TJoker
    MVP: Paint, Notepad, Solitaire

    ****************************************

    >-----Original Message-----


    >BTW, try the RefreshProperties attribute:
    >
    >[Category("Style"),
    >Description("The style for the table caption"),
    >DesignerSerializationVisibility

    (DesignerSerializationVisibility.Content),
    >NotifyParentProperty(true)]
    >[RefreshProperties(RefreshProperties.Repaint)]
    >[PersistenceMode(PersistenceMode.Attribute)]
    >public Style CaptionStyle
    >{
    > get
    > {
    > if (captionStyle == null)
    > {
    > captionStyle = new Style();
    > if (IsTrackingViewState)
    > ((IStateManager)

    captionStyle).TrackViewState();
    > }
    > return captionStyle;
    > }
    >}
    >
    >--
    >John Saunders
    >John.Saunders at SurfControl.com
    >
    >
    >.
    >
     
    TJoker .NET, Feb 24, 2004
    #6
  7. TJ,
    Have you tried to merge the style into the the table cell to whom you want
    this custom style applied. Also just like jesse stated, you will have to
    perform this in your render method call if you are databinding
    Can you showcase the code where you are copying the custom style you exposed
    as a property into the table. I have a hunch you are not merging this style
    into the table cell, if you are, show some of this code, makes a lot easier
    to help ;P



    "TJoker .NET" <> wrote in message
    news:06a801c3fae9$a0a074a0$...
    > John, the problem here is that the RefreshProperties (I
    > think) is considered only if I change the value of the
    > property, exactly what I'm not doing. In this case I'm
    > changing the value of a subproperty of the Style class, I
    > don't even have a "set" accessor for my ow property.
    > I tried and as I suspected it didn;t work, unfortunately.
    > I would think that the Style class would have some
    > attribute to help here but it doesn't seem to.
    >
    > Thanks for the response.
    >
    > TJ!
    >
    > --
    > TJoker
    > MVP: Paint, Notepad, Solitaire
    >
    > ****************************************
    >
    > >-----Original Message-----

    >
    > >BTW, try the RefreshProperties attribute:
    > >
    > >[Category("Style"),
    > >Description("The style for the table caption"),
    > >DesignerSerializationVisibility

    > (DesignerSerializationVisibility.Content),
    > >NotifyParentProperty(true)]
    > >[RefreshProperties(RefreshProperties.Repaint)]
    > >[PersistenceMode(PersistenceMode.Attribute)]
    > >public Style CaptionStyle
    > >{
    > > get
    > > {
    > > if (captionStyle == null)
    > > {
    > > captionStyle = new Style();
    > > if (IsTrackingViewState)
    > > ((IStateManager)

    > captionStyle).TrackViewState();
    > > }
    > > return captionStyle;
    > > }
    > >}
    > >
    > >--
    > >John Saunders
    > >John.Saunders at SurfControl.com
    > >
    > >
    > >.
    > >
     
    Alessandro Zifiglio, Feb 24, 2004
    #7
  8. TJoker .NET

    TJoker .NET Guest

    Here's what I'm doing. I removed unnecessary code and
    tried to show all that involved Styles and viewstate and
    rendering.
    I do not have a Render() override. My control is built
    during the CreateChildControls() call, using composition.
    It is basically a table with some fixed number of rows (no
    databinding). I have the ItemStyle property that defines
    the Style to be applied to each TableRow. No styles are
    applied to any TableCell directly.
    So, what is happening is that if I change the Style
    directly editing the ASPX markup, the changes are
    reflected immediately in the Design view of the page, but
    if I change using the Properties window then the changes
    are not seen until I manually edit something in the ASPX.
    If i change a non-reference property, like SomeLabelText
    shown below, I have the "set" accessor to force the
    refresh by setting ChildControlsCreated to false.

    Thanks for helping.


    [
    Category("Style"),
    Description("blahblahblah"),
    DesignerSerializationVisibility
    (DesignerSerializationVisibility.Content),
    NotifyParentProperty(true),
    PersistenceMode(PersistenceMode.InnerProperty)
    ]
    public TableItemStyle ItemStyle
    {
    get
    {
    if (itemStyle == null)
    {
    itemStyle = new Style();
    if (IsTrackingViewState)
    ((IStateManager)itemStyle).TrackViewState();
    }
    return itemStyle;
    }
    }

    private TableItemStyle itemStyle;

    public string SomeLabelText
    {
    get
    {
    string o = (string)ViewState
    ["SomeLabelText"];
    return (o == null)?"":eek:;
    }
    set
    {
    ViewState["SomeLabelText"] = value;
    //force it to rebuild control tree
    if(base.HasControls())
    {
    base.Controls.Clear();
    ChildControlsCreated=false;
    }
    }
    }

    protected override void CreateChildControls()
    {
    Controls.Clear();

    TableRow tr;
    TableCell td;

    Table table = new Table();
    table.ID = this.ID;

    //add a row
    tr = new TableRow();
    if(itemStyle != null) tr.ControlStyle.MergeWith
    (itemStyle);
    //create table cells without style (omitted)
    //...
    table.Controls.Add(tr);

    //add more rows similarly ...

    this.Controls.Add(table);

    }

    protected override void LoadViewState(object savedState)
    {
    object[] data = (object[])savedState;
    //first item is the regular viewstate information
    base.LoadViewState(data[0]);

    //omitted other data

    if (data[2] != null)((IStateManager)
    this.ItemStyle).LoadViewState(data[2]);
    }

    protected override object SaveViewState()
    {
    object[] data = new object[numberOfItems];
    //first item is the regular viewstate information
    data[0] = base.SaveViewState();

    //omitted other data

    data[2] = (this.itemStyle != null)?
    ((IStateManager)this.itemStyle).SaveViewState():null;

    return data;
    }

    protected override void TrackViewState()
    {
    base.TrackViewState();

    if (this.itemStyle != null) ((IStateManager)
    this.itemStyle).TrackViewState();
    }


    public override void RenderEndTag(HtmlTextWriter writer)
    {
    //empty
    //just avoid the default <span> by doing nothing
    }

    public override void RenderBeginTag(HtmlTextWriter writer)
    {
    //empty
    //just avoid the default </span> by doing nothing
    }



    --
    TJoker
    MVP: Paint, Notepad, Solitaire

    ****************************************



    >-----Original Message-----
    >TJ,
    >Have you tried to merge the style into the the table cell

    to whom you want
    >this custom style applied. Also just like jesse stated,

    you will have to
    >perform this in your render method call if you are

    databinding
    >Can you showcase the code where you are copying the

    custom style you exposed
    >as a property into the table. I have a hunch you are not

    merging this style
    >into the table cell, if you are, show some of this code,

    makes a lot easier
    >to help ;P
    >
     
    TJoker .NET, Feb 24, 2004
    #8
  9. 1. Instead of overriding RenderEndTag and RenderBeginTag, to stop the spans
    supply the controls base attributes to your table that way any styling you
    set for your control will go directly into your tables inline style css.
    This is as far as the span tags are concerned even if this is not the issue
    you want to resolve.

    2. You should apply styles to the child controls in the render phase, so
    that they are not persisted in the view state.

    so in your render method this should work for you with the code in your
    createChildControls method as you have it, emitting the style merge part :
    protected override void Render(HtmlTextWriter writer) {
    // Apply styles to the control hierarchy
    // and then render it out.

    // Apply styles during render phase, so the user can change
    styles
    //without the property changes ending
    // up in view state.
    PrepareControlHierarchy();

    //RenderContents will outout what your childcontrols
    RenderContents(writer);
    }

    private void PrepareControlHierarchy() {
    Table table = (Table)Controls[0];

    table.CopyBaseAttributes(this);
    if (ControlStyleCreated) {
    table.ApplyStyle(ControlStyle);
    }
    int rowCount = table.Rows.Count;
    for (int i = 0; i < rowCount; i++) {
    table.Rows(i).MergeStyle(itemstyle)
    }
    }//PrepareControlHierarchy
    "TJoker .NET" <> wrote in message
    news:09eb01c3fafa$7e6bfc40$...
    > Here's what I'm doing. I removed unnecessary code and
    > tried to show all that involved Styles and viewstate and
    > rendering.
    > I do not have a Render() override. My control is built
    > during the CreateChildControls() call, using composition.
    > It is basically a table with some fixed number of rows (no
    > databinding). I have the ItemStyle property that defines
    > the Style to be applied to each TableRow. No styles are
    > applied to any TableCell directly.
    > So, what is happening is that if I change the Style
    > directly editing the ASPX markup, the changes are
    > reflected immediately in the Design view of the page, but
    > if I change using the Properties window then the changes
    > are not seen until I manually edit something in the ASPX.
    > If i change a non-reference property, like SomeLabelText
    > shown below, I have the "set" accessor to force the
    > refresh by setting ChildControlsCreated to false.
    >
    > Thanks for helping.
    >
    >
    > [
    > Category("Style"),
    > Description("blahblahblah"),
    > DesignerSerializationVisibility
    > (DesignerSerializationVisibility.Content),
    > NotifyParentProperty(true),
    > PersistenceMode(PersistenceMode.InnerProperty)
    > ]
    > public TableItemStyle ItemStyle
    > {
    > get
    > {
    > if (itemStyle == null)
    > {
    > itemStyle = new Style();
    > if (IsTrackingViewState)
    > ((IStateManager)itemStyle).TrackViewState();
    > }
    > return itemStyle;
    > }
    > }
    >
    > private TableItemStyle itemStyle;
    >
    > public string SomeLabelText
    > {
    > get
    > {
    > string o = (string)ViewState
    > ["SomeLabelText"];
    > return (o == null)?"":eek:;
    > }
    > set
    > {
    > ViewState["SomeLabelText"] = value;
    > //force it to rebuild control tree
    > if(base.HasControls())
    > {
    > base.Controls.Clear();
    > ChildControlsCreated=false;
    > }
    > }
    > }
    >
    > protected override void CreateChildControls()
    > {
    > Controls.Clear();
    >
    > TableRow tr;
    > TableCell td;
    >
    > Table table = new Table();
    > table.ID = this.ID;
    >
    > //add a row
    > tr = new TableRow();
    > if(itemStyle != null) tr.ControlStyle.MergeWith
    > (itemStyle);
    > //create table cells without style (omitted)
    > //...
    > table.Controls.Add(tr);
    >
    > //add more rows similarly ...
    >
    > this.Controls.Add(table);
    >
    > }
    >
    > protected override void LoadViewState(object savedState)
    > {
    > object[] data = (object[])savedState;
    > //first item is the regular viewstate information
    > base.LoadViewState(data[0]);
    >
    > //omitted other data
    >
    > if (data[2] != null)((IStateManager)
    > this.ItemStyle).LoadViewState(data[2]);
    > }
    >
    > protected override object SaveViewState()
    > {
    > object[] data = new object[numberOfItems];
    > //first item is the regular viewstate information
    > data[0] = base.SaveViewState();
    >
    > //omitted other data
    >
    > data[2] = (this.itemStyle != null)?
    > ((IStateManager)this.itemStyle).SaveViewState():null;
    >
    > return data;
    > }
    >
    > protected override void TrackViewState()
    > {
    > base.TrackViewState();
    >
    > if (this.itemStyle != null) ((IStateManager)
    > this.itemStyle).TrackViewState();
    > }
    >
    >
    > public override void RenderEndTag(HtmlTextWriter writer)
    > {
    > //empty
    > //just avoid the default <span> by doing nothing
    > }
    >
    > public override void RenderBeginTag(HtmlTextWriter writer)
    > {
    > //empty
    > //just avoid the default </span> by doing nothing
    > }
    >
    >
    >
    > --
    > TJoker
    > MVP: Paint, Notepad, Solitaire
    >
    > ****************************************
    >
    >
    >
    > >-----Original Message-----
    > >TJ,
    > >Have you tried to merge the style into the the table cell

    > to whom you want
    > >this custom style applied. Also just like jesse stated,

    > you will have to
    > >perform this in your render method call if you are

    > databinding
    > >Can you showcase the code where you are copying the

    > custom style you exposed
    > >as a property into the table. I have a hunch you are not

    > merging this style
    > >into the table cell, if you are, show some of this code,

    > makes a lot easier
    > >to help ;P
    > >

    >
     
    Alessandro Zifiglio, Feb 24, 2004
    #9
  10. TJoker .NET

    TJoker .NET Guest

    Alessandro, I much appreciate your help.
    However, I think that if I do not put the Style in the
    ViewState of the control, then the control user will not
    have the ability to change the Style at runtime because
    the Merge will keep the current settings of each row for
    the same style attribute.
    As for setting the styles during the Render method, that
    works correctly and that's how the controls based on
    BaseDataList do (ex: DataGrid).
    It just seems very un-natural for me to build part of my
    control during CreateChildControls and part during the
    Render method.

    Thanks

    TJ!

    >-----Original Message-----
    >1. Instead of overriding RenderEndTag and RenderBeginTag,

    to stop the spans
    >supply the controls base attributes to your table that

    way any styling you
    >set for your control will go directly into your tables

    inline style css.
    >This is as far as the span tags are concerned even if

    this is not the issue
    >you want to resolve.
    >
    >2. You should apply styles to the child controls in the

    render phase, so
    >that they are not persisted in the view state.
    >
    >so in your render method this should work for you with

    the code in your
    >createChildControls method as you have it, emitting the

    style merge part :
    >protected override void Render(HtmlTextWriter writer) {
    > // Apply styles to the control hierarchy
    > // and then render it out.
    >
    > // Apply styles during render phase, so the

    user can change
    >styles
    > //without the property changes ending
    > // up in view state.
    > PrepareControlHierarchy();
    >
    >//RenderContents will outout what your childcontrols
    > RenderContents(writer);
    > }
    >
    >private void PrepareControlHierarchy() {
    >Table table = (Table)Controls[0];
    >
    > table.CopyBaseAttributes(this);
    > if (ControlStyleCreated) {
    > table.ApplyStyle(ControlStyle);
    > }
    >int rowCount = table.Rows.Count;
    > for (int i = 0; i < rowCount; i++) {
    > table.Rows(i).MergeStyle(itemstyle)
    >}
    >}//PrepareControlHierarchy
    >"TJoker .NET" <> wrote in message
    >news:09eb01c3fafa$7e6bfc40$...
    >> Here's what I'm doing. I removed unnecessary code and
    >> tried to show all that involved Styles and viewstate and
    >> rendering.
    >> I do not have a Render() override. My control is built
    >> during the CreateChildControls() call, using

    composition.
    >> It is basically a table with some fixed number of rows

    (no
    >> databinding). I have the ItemStyle property that defines
    >> the Style to be applied to each TableRow. No styles are
    >> applied to any TableCell directly.
    >> So, what is happening is that if I change the Style
    >> directly editing the ASPX markup, the changes are
    >> reflected immediately in the Design view of the page,

    but
    >> if I change using the Properties window then the changes
    >> are not seen until I manually edit something in the

    ASPX.
    >> If i change a non-reference property, like SomeLabelText
    >> shown below, I have the "set" accessor to force the
    >> refresh by setting ChildControlsCreated to false.
    >>
    >> Thanks for helping.
    >>
    >>
    >> [
    >> Category("Style"),
    >> Description("blahblahblah"),
    >> DesignerSerializationVisibility
    >> (DesignerSerializationVisibility.Content),
    >> NotifyParentProperty(true),
    >> PersistenceMode(PersistenceMode.InnerProperty)
    >> ]
    >> public TableItemStyle ItemStyle
    >> {
    >> get
    >> {
    >> if (itemStyle == null)
    >> {
    >> itemStyle = new Style();
    >> if (IsTrackingViewState)
    >> ((IStateManager)itemStyle).TrackViewState();
    >> }
    >> return itemStyle;
    >> }
    >> }
    >>
    >> private TableItemStyle itemStyle;
    >>
    >> public string SomeLabelText
    >> {
    >> get
    >> {
    >> string o = (string)ViewState
    >> ["SomeLabelText"];
    >> return (o == null)?"":eek:;
    >> }
    >> set
    >> {
    >> ViewState["SomeLabelText"] = value;
    >> //force it to rebuild control tree
    >> if(base.HasControls())
    >> {
    >> base.Controls.Clear();
    >> ChildControlsCreated=false;
    >> }
    >> }
    >> }
    >>
    >> protected override void CreateChildControls()
    >> {
    >> Controls.Clear();
    >>
    >> TableRow tr;
    >> TableCell td;
    >>
    >> Table table = new Table();
    >> table.ID = this.ID;
    >>
    >> //add a row
    >> tr = new TableRow();
    >> if(itemStyle != null) tr.ControlStyle.MergeWith
    >> (itemStyle);
    >> //create table cells without style (omitted)
    >> //...
    >> table.Controls.Add(tr);
    >>
    >> //add more rows similarly ...
    >>
    >> this.Controls.Add(table);
    >>
    >> }
    >>
    >> protected override void LoadViewState(object savedState)
    >> {
    >> object[] data = (object[])savedState;
    >> //first item is the regular viewstate information
    >> base.LoadViewState(data[0]);
    >>
    >> //omitted other data
    >>
    >> if (data[2] != null)((IStateManager)
    >> this.ItemStyle).LoadViewState(data[2]);
    >> }
    >>
    >> protected override object SaveViewState()
    >> {
    >> object[] data = new object[numberOfItems];
    >> //first item is the regular viewstate information
    >> data[0] = base.SaveViewState();
    >>
    >> //omitted other data
    >>
    >> data[2] = (this.itemStyle != null)?
    >> ((IStateManager)this.itemStyle).SaveViewState():null;
    >>
    >> return data;
    >> }
    >>
    >> protected override void TrackViewState()
    >> {
    >> base.TrackViewState();
    >>
    >> if (this.itemStyle != null) ((IStateManager)
    >> this.itemStyle).TrackViewState();
    >> }
    >>
    >>
    >> public override void RenderEndTag(HtmlTextWriter writer)
    >> {
    >> //empty
    >> //just avoid the default <span> by doing nothing
    >> }
    >>
    >> public override void RenderBeginTag(HtmlTextWriter

    writer)
    >> {
    >> //empty
    >> //just avoid the default </span> by doing nothing
    >> }
    >>
    >>
    >>
    >> --
    >> TJoker
    >> MVP: Paint, Notepad, Solitaire
    >>
    >> ****************************************
    >>
    >>
    >>
    >> >-----Original Message-----
    >> >TJ,
    >> >Have you tried to merge the style into the the table

    cell
    >> to whom you want
    >> >this custom style applied. Also just like jesse stated,

    >> you will have to
    >> >perform this in your render method call if you are

    >> databinding
    >> >Can you showcase the code where you are copying the

    >> custom style you exposed
    >> >as a property into the table. I have a hunch you are

    not
    >> merging this style
    >> >into the table cell, if you are, show some of this

    code,
    >> makes a lot easier
    >> >to help ;P
    >> >

    >>

    >
    >
    >.
    >
     
    TJoker .NET, Feb 24, 2004
    #10
  11. TJ,
    When you create a new style object, the controls viewstate is not passed to
    the style constructor(which you are not doing anyway and going about this
    correctly). A controls viewstate is passed to the style constructor only
    when creating a controls ControlStyle property, and not for any other
    properties of type Style. These style objects manage their own state, and
    you have already implemented customized state management to preserve
    additional styles across round trips to the client so no problem here and
    because of this you do the merge in the render phase, this way you do not
    additionally persist style in viewstate. I believe this is why you were
    having that unwanted retardation behavior in that when applying styles from
    the propertygrid your styles werent being written to page immidiately unless
    you invoked another non-subproperty of your control.

    This is what i meant when I stated : You should apply styles to the child
    controls in the render phase, so that they are not persisted in the view
    state --

    Under most circumstances when developing composite controls you do not have
    to override the Render method because child controls provide rendering logic
    but there are exceptions to this case and yours is one.

    "TJoker .NET" <> wrote in message
    news:0e7401c3fb2b$afafb7c0$...
    > Alessandro, I much appreciate your help.
    > However, I think that if I do not put the Style in the
    > ViewState of the control, then the control user will not
    > have the ability to change the Style at runtime because
    > the Merge will keep the current settings of each row for
    > the same style attribute.
    > As for setting the styles during the Render method, that
    > works correctly and that's how the controls based on
    > BaseDataList do (ex: DataGrid).
    > It just seems very un-natural for me to build part of my
    > control during CreateChildControls and part during the
    > Render method.
    >
    > Thanks
    >
    > TJ!
    >
    > >-----Original Message-----
    > >1. Instead of overriding RenderEndTag and RenderBeginTag,

    > to stop the spans
    > >supply the controls base attributes to your table that

    > way any styling you
    > >set for your control will go directly into your tables

    > inline style css.
    > >This is as far as the span tags are concerned even if

    > this is not the issue
    > >you want to resolve.
    > >
    > >2. You should apply styles to the child controls in the

    > render phase, so
    > >that they are not persisted in the view state.
    > >
    > >so in your render method this should work for you with

    > the code in your
    > >createChildControls method as you have it, emitting the

    > style merge part :
    > >protected override void Render(HtmlTextWriter writer) {
    > > // Apply styles to the control hierarchy
    > > // and then render it out.
    > >
    > > // Apply styles during render phase, so the

    > user can change
    > >styles
    > > //without the property changes ending
    > > // up in view state.
    > > PrepareControlHierarchy();
    > >
    > >//RenderContents will outout what your childcontrols
    > > RenderContents(writer);
    > > }
    > >
    > >private void PrepareControlHierarchy() {
    > >Table table = (Table)Controls[0];
    > >
    > > table.CopyBaseAttributes(this);
    > > if (ControlStyleCreated) {
    > > table.ApplyStyle(ControlStyle);
    > > }
    > >int rowCount = table.Rows.Count;
    > > for (int i = 0; i < rowCount; i++) {
    > > table.Rows(i).MergeStyle(itemstyle)
    > >}
    > >}//PrepareControlHierarchy
    > >"TJoker .NET" <> wrote in message
    > >news:09eb01c3fafa$7e6bfc40$...
    > >> Here's what I'm doing. I removed unnecessary code and
    > >> tried to show all that involved Styles and viewstate and
    > >> rendering.
    > >> I do not have a Render() override. My control is built
    > >> during the CreateChildControls() call, using

    > composition.
    > >> It is basically a table with some fixed number of rows

    > (no
    > >> databinding). I have the ItemStyle property that defines
    > >> the Style to be applied to each TableRow. No styles are
    > >> applied to any TableCell directly.
    > >> So, what is happening is that if I change the Style
    > >> directly editing the ASPX markup, the changes are
    > >> reflected immediately in the Design view of the page,

    > but
    > >> if I change using the Properties window then the changes
    > >> are not seen until I manually edit something in the

    > ASPX.
    > >> If i change a non-reference property, like SomeLabelText
    > >> shown below, I have the "set" accessor to force the
    > >> refresh by setting ChildControlsCreated to false.
    > >>
    > >> Thanks for helping.
    > >>
    > >>
    > >> [
    > >> Category("Style"),
    > >> Description("blahblahblah"),
    > >> DesignerSerializationVisibility
    > >> (DesignerSerializationVisibility.Content),
    > >> NotifyParentProperty(true),
    > >> PersistenceMode(PersistenceMode.InnerProperty)
    > >> ]
    > >> public TableItemStyle ItemStyle
    > >> {
    > >> get
    > >> {
    > >> if (itemStyle == null)
    > >> {
    > >> itemStyle = new Style();
    > >> if (IsTrackingViewState)
    > >> ((IStateManager)itemStyle).TrackViewState();
    > >> }
    > >> return itemStyle;
    > >> }
    > >> }
    > >>
    > >> private TableItemStyle itemStyle;
    > >>
    > >> public string SomeLabelText
    > >> {
    > >> get
    > >> {
    > >> string o = (string)ViewState
    > >> ["SomeLabelText"];
    > >> return (o == null)?"":eek:;
    > >> }
    > >> set
    > >> {
    > >> ViewState["SomeLabelText"] = value;
    > >> //force it to rebuild control tree
    > >> if(base.HasControls())
    > >> {
    > >> base.Controls.Clear();
    > >> ChildControlsCreated=false;
    > >> }
    > >> }
    > >> }
    > >>
    > >> protected override void CreateChildControls()
    > >> {
    > >> Controls.Clear();
    > >>
    > >> TableRow tr;
    > >> TableCell td;
    > >>
    > >> Table table = new Table();
    > >> table.ID = this.ID;
    > >>
    > >> //add a row
    > >> tr = new TableRow();
    > >> if(itemStyle != null) tr.ControlStyle.MergeWith
    > >> (itemStyle);
    > >> //create table cells without style (omitted)
    > >> //...
    > >> table.Controls.Add(tr);
    > >>
    > >> //add more rows similarly ...
    > >>
    > >> this.Controls.Add(table);
    > >>
    > >> }
    > >>
    > >> protected override void LoadViewState(object savedState)
    > >> {
    > >> object[] data = (object[])savedState;
    > >> //first item is the regular viewstate information
    > >> base.LoadViewState(data[0]);
    > >>
    > >> //omitted other data
    > >>
    > >> if (data[2] != null)((IStateManager)
    > >> this.ItemStyle).LoadViewState(data[2]);
    > >> }
    > >>
    > >> protected override object SaveViewState()
    > >> {
    > >> object[] data = new object[numberOfItems];
    > >> //first item is the regular viewstate information
    > >> data[0] = base.SaveViewState();
    > >>
    > >> //omitted other data
    > >>
    > >> data[2] = (this.itemStyle != null)?
    > >> ((IStateManager)this.itemStyle).SaveViewState():null;
    > >>
    > >> return data;
    > >> }
    > >>
    > >> protected override void TrackViewState()
    > >> {
    > >> base.TrackViewState();
    > >>
    > >> if (this.itemStyle != null) ((IStateManager)
    > >> this.itemStyle).TrackViewState();
    > >> }
    > >>
    > >>
    > >> public override void RenderEndTag(HtmlTextWriter writer)
    > >> {
    > >> //empty
    > >> //just avoid the default <span> by doing nothing
    > >> }
    > >>
    > >> public override void RenderBeginTag(HtmlTextWriter

    > writer)
    > >> {
    > >> //empty
    > >> //just avoid the default </span> by doing nothing
    > >> }
    > >>
    > >>
    > >>
    > >> --
    > >> TJoker
    > >> MVP: Paint, Notepad, Solitaire
    > >>
    > >> ****************************************
    > >>
    > >>
    > >>
    > >> >-----Original Message-----
    > >> >TJ,
    > >> >Have you tried to merge the style into the the table

    > cell
    > >> to whom you want
    > >> >this custom style applied. Also just like jesse stated,
    > >> you will have to
    > >> >perform this in your render method call if you are
    > >> databinding
    > >> >Can you showcase the code where you are copying the
    > >> custom style you exposed
    > >> >as a property into the table. I have a hunch you are

    > not
    > >> merging this style
    > >> >into the table cell, if you are, show some of this

    > code,
    > >> makes a lot easier
    > >> >to help ;P
    > >> >
    > >>

    > >
    > >
    > >.
    > >
     
    Alessandro Zifiglio, Feb 25, 2004
    #11
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. jensen bredal
    Replies:
    4
    Views:
    515
    jensen bredal
    May 18, 2005
  2. Replies:
    0
    Views:
    660
  3. flamesrock
    Replies:
    8
    Views:
    502
    Hendrik van Rooyen
    Nov 24, 2006
  4. Ken Varn
    Replies:
    0
    Views:
    492
    Ken Varn
    Apr 26, 2004
  5. Patrick

    Custom asp.net control using collection - Design Time Refresh

    Patrick, Oct 7, 2005, in forum: ASP .Net Building Controls
    Replies:
    3
    Views:
    370
    Patrick
    Oct 13, 2005
Loading...

Share This Page