Как предоставить свойства стиля дочернего элемента управления в настраиваемом составном элементе управления WebControl

Я пишу настраиваемый составной элемент управления WebControl и хочу предоставить дизайнеру ASP.NET стили дочерних элементов управления, которые он инкапсулирует. Код, который у меня есть в настоящее время, похож на скелет ниже (который для простоты имеет только один дочерний элемент управления).

С помощью приведенного ниже кода я вижу свойство «ChildPanelStyle» в конструкторе, но когда я пытаюсь изменить одно из свойств (например, CssClass) в конструкторе, оно немедленно сбрасывается до значения по умолчанию. Похоже, сериализации конструктора не происходит.

Что я делаю неправильно?

ОБНОВЛЕНИЕ

Добавление установщика для свойства стиля не помогает и в этом нет необходимости. Я обновил образец, добавив в него дополнительное свойство стиля, которое управляется непосредственно настраиваемым элементом управления, а не просто является свойством дочернего элемента управления.

Свойство HeaderStyle правильно сохраняется дизайнером, а свойство ChildPanelStyle - нет.

Конечно, я мог бы управлять всеми своими стилями, такими как HeaderStyle, и применять их во время рендеринга, но я надеюсь, что есть более простое решение, при котором дочерние элементы управления могут позаботиться о себе сами, и мне не нужен какой-либо пользовательский рендеринг.

public class MyControl : CompositeControl
{
    Panel myChildPanel;

    protected override void CreateChildControls()
    {
        myChildPanel = new Panel();
        this.Controls.Add(myChildPanel);
    }

    [
    Category("Style"),
    Description("Child panel style"),
    DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
    NotifyParentProperty(true),
    PersistenceMode(PersistenceMode.InnerProperty),
    ]
    public System.Web.UI.WebControls.Style ChildPanelStyle
    {
        get
        {
            EnsureChildControls();
            return this.myChildPanel.ControlStyle;
        }
    }

    [
    Category("Style"),
    Description("Header style"),
    DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
    NotifyParentProperty(true),
    PersistenceMode(PersistenceMode.InnerProperty),
    ]
    public System.Web.UI.WebControls.Style HeaderStyle
    {
        get
        {
            if (_headerStyle == null)
            {
                _headerStyle = new Style();
                if (IsTrackingViewState)
                    ((IStateManager)_headerStyle).TrackViewState();
            }
            return _headerStyle;
        }
    }
    private System.Web.UI.WebControls.Style _headerStyle;

    // ... overrides for save/load/tracking ViewState omitted 

    protected override void Render(System.Web.UI.HtmlTextWriter writer)
    {
        EnsureChildControls();
        base.Render(writer);
    }

}

person Joe    schedule 23.02.2010    source источник
comment
Вы решили эту проблему? Я создаю составной элемент управления с тем же свойством стиля для внутреннего дочернего элемента управления. Надеюсь, вы сможете поделиться своим кодом.   -  person ajakblackgoat    schedule 15.04.2013


Ответы (2)


У тебя нет сеттера. К сожалению, вы не можете напрямую установить this.myChildPanel.ControlStyle, поскольку это свойство только для чтения, поэтому вам придется установить свойства it. Измените свойство ChildPanelStyle на следующее:

[
Category("Style"),
Description("Child panel style"),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
NotifyParentProperty(true),
PersistenceMode(PersistenceMode.InnerProperty),
]
public System.Web.UI.WebControls.Style ChildPanelStyle
{
    get
    {
        EnsureChildControls();
        return this.myChildPanel.ControlStyle;
    }
    set
    {
        EnsureChildControls();
        this.myChildPanel.ControlStyle.BackColor = value.BackColor;
        this.myChildPanel.ControlStyle.BorderColor = value.BorderColor;
        this.myChildPanel.ControlStyle.BorderStyle = value.BorderStyle;
        this.myChildPanel.ControlStyle.BorderWidth = value.BorderWidth;
        this.myChildPanel.ControlStyle.CssClass = value.CssClass;
        this.myChildPanel.ControlStyle.Font.Bold = value.Font.Bold;
        this.myChildPanel.ControlStyle.Font.Italic = value.Font.Italic;
        this.myChildPanel.ControlStyle.Font.Name = value.Font.Name;
        this.myChildPanel.ControlStyle.Font.Names = value.Font.Names;
        this.myChildPanel.ControlStyle.Font.Overline = value.Font.Overline;
        this.myChildPanel.ControlStyle.Font.Size = value.Font.Size;
        this.myChildPanel.ControlStyle.Font.Strikeout = value.Font.Strikeout;
        this.myChildPanel.ControlStyle.Font.Underline = value.Font.Underline;
        this.myChildPanel.ControlStyle.ForeColor = value.ForeColor;
        this.myChildPanel.ControlStyle.Height = value.Height;
        this.myChildPanel.ControlStyle.Width = value.Width;
    }
}
person David Morton    schedule 23.02.2010
comment
Я попытался добавить сеттер, и это не имело никакого значения - чего я и ожидал. Я обновил свой образец, чтобы показать случай, когда стиль, управляемый непосредственно свойством, отлично работает в конструкторе без сеттера. - person Joe; 23.02.2010
comment
Кстати, установщик не смог бы обновить ControlStyl, используя что-то вроде myChildPanel.ControlStyle.Reset (); myChildPanel.ControlStyle.MergeWith (значение); - person Joe; 23.02.2010

Если ваш элемент управления является производным от System.Web.UI.Control (что, скорее всего, верно в соответствии с симптомами), вы должны добавить следующие атрибуты, чтобы получить то, что вы хотите:

[ParseChildren(true)]
[PersistChildren(false)]
public class MyControl : CompositeControl
{
    ...
}

Это не обязательно при наследовании от WebControl.


PS вам не нужен сеттер для ... свойств стиля - но убедитесь, что эти стили действительно созданы при первой попытке их получить.

person user488399    schedule 01.02.2012