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

Asp.net 如何在自定义复合WebControl中公开子控件样式属性,asp.net,coding-style,designer,web-controls,Asp.net,Coding Style,Designer,Web Controls,我正在编写一个自定义复合WebControl,并希望向ASP.NET设计器公开它封装的子控件的样式。我目前拥有的代码类似于下面的框架(为了简单起见,它只有一个子控件) 使用下面的代码,我可以在设计器中看到属性“ChildPanelStyle”,但当我尝试在设计器中修改其中一个属性(例如CssClass)时,它会立即将自身重置为默认值。看来设计器序列化没有发生 我做错了什么 更新 为style属性添加setter没有帮助,也没有必要。我用一个附加的样式属性更新了示例,该属性由自定义控件直接管理,而

我正在编写一个自定义复合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);
    }

}

你没有二传手。不幸的是,您不能直接设置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;
    }
}

你没有二传手。不幸的是,您不能直接设置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;
    }
}

如果控件派生自System.Web.UI.control(根据simptoms,这很可能是真的),则应添加以下属性以获得所需的内容:

[ParseChildren(true)]
[PersistChildren(false)]
public class MyControl : CompositeControl
{
    ...
}
从网络控制派生时,这不是必需的


PS
您不需要为…样式属性使用setter,但请确保在第一次尝试获取这些样式时确实创建了这些样式。

如果控件派生自System.Web.UI.control(根据simptoms,这很可能是真的),则应添加以下属性以获得所需的内容:

[ParseChildren(true)]
[PersistChildren(false)]
public class MyControl : CompositeControl
{
    ...
}
从网络控制派生时,这不是必需的


PS
样式属性不需要setter,但请确保在第一次尝试获取样式时就真正创建了这些样式。

我尝试添加setter,但没有任何区别,这正是我所期望的。我更新了我的示例,以显示一种情况,即属性直接管理的样式在设计器中运行良好,而没有setter。顺便说一句,setter是否可以使用类似myChildPanel.ControlStyle.Reset()的内容更新控件;myChildPanel.ControlStyle.MergeWith(值);我试着添加一个二传手,但没有什么不同——这正是我所期望的。我更新了我的示例,以显示一种情况,即属性直接管理的样式在设计器中运行良好,而没有setter。顺便说一句,setter是否可以使用类似myChildPanel.ControlStyle.Reset()的内容更新控件;myChildPanel.ControlStyle.MergeWith(值);这个问题解决了吗?我正在为内部子控件创建一个具有相同样式属性的复合控件。希望你能分享你的代码。你解决了这个问题吗?我正在为内部子控件创建一个具有相同样式属性的复合控件。希望你能分享你的代码。