【问题标题】:How to expose child control style properties in a custom composite WebControl如何在自定义复合 WebControl 中公开子控件样式属性
【发布时间】:2011-01-20 05:21:26
【问题描述】:

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

}

【问题讨论】:

  • 你解决了吗?我正在为内部子控件创建一个具有相同样式属性的复合控件。希望你能分享你的代码。

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


【解决方案1】:

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

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

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


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

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 我尝试添加一个 setter,但没有任何区别 - 这是我所期望的。我更新了我的示例,以展示由属性直接管理的样式在设计器中可以正常工作的情况,而无需设置器。
    • 顺便说一句,setter 不可能使用 myChildPanel.ControlStyle.Reset(); 之类的东西来更新 ControlStyl; myChildPanel.ControlStyle.MergeWith(value);
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-10
    • 2022-01-10
    • 2010-11-25
    • 2020-04-11
    • 1970-01-01
    • 2013-06-26
    相关资源
    最近更新 更多