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

发布于 2024-08-23 09:06:49 字数 1975 浏览 7 评论 0原文

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

}

I am writing a custom composite WebControl and want to expose styles of child controls it encapsulates to the ASP.NET designer. The code I currently have is similar to the skeleton below (which for simplicity only has one child control).

With the code below, I can see property "ChildPanelStyle" in the designer, but when I try to modify one of the properties (e.g. CssClass) in the designer, it immediately resets itself to its default value. It looks like the designer serialization isn't happening.

What am I doing wrong?

UPDATE

Adding a setter for the style property doesn't help and shouldn't be necessary. I've updated the sample with an additional style property that is managed directly by the custom control, rather than simply being the property of a child control.

The HeaderStyle property is persisted properly by the designer, but the ChildPanelStyle property isn't.

Of course I could manage all my styles like HeaderStyle, and apply them during rendering, but I'm hoping there's a simpler solution whereby child controls can take care of themselves, and I don't need any custom rendering.

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

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

唯憾梦倾城 2024-08-30 09:06:49

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

You've got no setter. Unfortunately, you can't directly set this.myChildPanel.ControlStyle, as it's a read-only property, so you'll have to set it's properties. Change your ChildPanelStyle property to the following:

[
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;
    }
}
指尖上得阳光 2024-08-30 09:06:49

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

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

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


聚苯乙烯
您不需要 ...Style 属性的 setter - 但确保这些样式是在第一次尝试获取它们时真正创建的。

If your control derived from System.Web.UI.Control (which most likely is true according to simptoms), you should add the following attributes to get what you want:

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

This is not nesessary when deriving from WebControl.


PS
you do not need setter for ...Style properties - but ensure those styles are really created upon first attempt to get them.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文