【问题标题】:How can I hide inherited properties of an ASP.NET custom control?如何隐藏 ASP.NET 自定义控件的继承属性?
【发布时间】:2015-09-01 02:48:08
【问题描述】:

这是我创建自定义控件的第一次体验。我的真实示例要大得多,但为了清楚起见,将其归结为。最终,我需要尽可能多地隐藏自定义控件的属性,这样当我与团队的其他成员共享我的新控件时,他们只需要担心所需的少数属性。

我有一个名为 TimeNow 的控件,它继承 System.Web.UI.WebControls.Literal,基本上只是在网页上打印当前时间:

public class TimeNow : Literal

// Set to private so Text is hidden from the editor.
private string Text
{
    get;
    set;
}

protected override void Render(HtmlTextWriter writer)
{
    // Get and write the time of now.
}

工作,但看起来很笨重。当我将控件放在网页上时,我不再在智能感知中看到可用的文本,但我确实收到一条警告,指出我的文本正在隐藏继承的文本。有没有更好的方法来隐藏 Text 属性?

【问题讨论】:

    标签: c# asp.net inheritance custom-controls


    【解决方案1】:

    该警告消息应该有更多内容,建议您使用 new 关键字,如果您真的打算隐藏继承的成员,照它说的做:

    public class TimeNow : Literal
    {
        new private string Text
        {
            get;
            set;
        }
    }
    

    【讨论】:

    • 请在这样做之前考虑一下。这有几个陷阱。您仍然可以通过 cast ((Literal)myvar).Text 访问 Literal.Text。所以你仍然可以错误地使用你的界面,例如when 循环遍历包含您的 TimeNow 类的 Literals 列表。 Literal.Text 变量与 TimeNow 中定义为私有的变量不同(现在您有 2 个)!!!在此处使用 new 关键字时要小心。
    • 嘿,迷人!我读了那部分,但我只是假设这不是我想做的。学过的知识。谢谢!
    • @Beachwalker 感谢您的提醒!我发现如果我以声明方式设置像 Text 这样的属性,我仍然会在我的代码中覆盖它;但是,我真的只是想减少队友混乱的机会。谢谢!
    • @mrcoulson 但这肯定会让你的队友感到困惑,因为你在这里没有覆盖,接口应该是安全的,不会以错误的方式使用。从我的角度来看,这不是很干净的编码,从我的角度来看是一个糟糕的解决方案。仅在 hacks 中看到了 new 的用法。一个好的控件应该不需要这个。
    • 因此我来这里是为了更好的想法 :) 我知道这很糟糕,但我不确定更好的答案是什么。
    【解决方案2】:

    试试这个:

    [Browsable(false)]
    [EditorBrowsable(EditorBrowsableState.Never)]
    private string Text
    {
    
    }
    

    【讨论】:

    • 这仍然让我隐藏了一个继承的属性。
    • 我不明白你的意思!您不想隐藏该属性吗?
    • 也许你应该考虑组合而不是继承。通过这种方式,您可以指定自己的接口,而无需使某些东西表现得像不打算使用的东西。否则 Text 属性没有在那里定义和实现。
    【解决方案3】:

    如果您从行为类似于ITextControlLiteral 派生(Literal 已实现此接口),然后您尝试删除基本的 Text 属性,我认为您做错了什么?这就像从 cat 派生,但不想让它们“喵”并迫使它们像鸭子一样飞翔。我认为您正在搜索 Animal 类。

    我不太了解 ASP.NET(仅适用于桌面的 .Net)。也许可以使用组合而不是继承(如果你真的不需要 Literal -> "Cat"),你可以从 System.Web.UI.Control (-> "Animal") 继承。

    public class TimeNow : System.Web.UI.Control
    {
       // no need to do something here with the Text property, is not defined
    }
    

    或组合

    public class TimeNow : System.Web.UI.Control
    {
         private readonly Literal literal;
    
         public TimeNow()
         {
             this.literal = new Literal();
             // ... and set the Text etc., no one else can access
         }
    
         // or something like this
    
         public TimeNow(ILiteralFactory literalFactory)
         {
             // the factory is just an example... don't know your context but this way your newly created literal can't be accessed
             this.literal = literalFactory.CreateNewLiteral();
             // do what you want with the text control, e.g. store internally
             // Clone() the Literal etc.
             // the
         }
    }
    

    更新: 快速浏览了 MSDN,也许 Content Control 是您正在寻找的东西,而不是文字。 (如果有错误,请写桌面应用程序)

    【讨论】:

    • 嗯,这一切都说得通。对于这个例子,我真正想做的就是有一个控件,它会在页面上自己吐出一些文本。文字似乎只是在页面上写几个字符。如果这是真正的实现,那将完全有道理。
    • (也就是说,当我明天回去工作并开始编写真正的控件而不是在页面上写时间的控件时,我将从这个开始而不是从我离开的地方开始。 )
    猜你喜欢
    • 2011-01-14
    • 2013-03-28
    • 1970-01-01
    • 2012-11-22
    • 1970-01-01
    • 2011-06-25
    • 1970-01-01
    • 1970-01-01
    • 2010-12-04
    相关资源
    最近更新 更多