如何在自定义复合WebControl中公开子控件样式属性

时间:2010-02-23 19:00:08

标签: asp.net coding-style designer web-controls

我正在编写一个自定义复合WebControl,并希望将它封装的子控件的样式公开给ASP.NET设计器。我目前的代码类似于下面的骨架(为简单起见,它只有一个子控件)。

使用下面的代码,我可以在设计器中看到属性“ChildPanelStyle”,但是当我尝试修改设计器中的一个属性(例如CssClass)时,它会立即将自身重置为其默认值。看起来设计师序列化没有发生。

我做错了什么?

更新

为style属性添加setter没有帮助,也没有必要。我已经使用由自定义控件直接管理的其他样式属性更新了示例,而不是简单地将其作为子控件的属性。

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);
    }

}

2 个答案:

答案 0 :(得分:1)

你没有二传手。不幸的是,你不能直接设置this.myChildPanel.ControlStyle,因为它是一个只读属性,所以你必须设置它的属性。将您的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;
    }
}

答案 1 :(得分:0)

如果你的控件派生自System.Web.UI.Control(根据simptoms很可能是真的),你应该添加以下属性来获得你想要的东西:

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

从WebControl派生时,这不是必需的。


PS 你不需要setter for ...样式属性 - 但要确保在第一次尝试获取它们时真正创建这些样式。