【问题标题】:What to extend for a new custom control?为新的自定义控件扩展什么?
【发布时间】:2013-08-12 10:19:05
【问题描述】:

有些人建议只扩展Panel,但我也知道UserControl,这听起来像是我应该扩展以进行自己的控制。

Panel vs. UserControl vs. Control vs. another_alternative

// inheritance depth:
Control
Panel : ScrollableControl : Control
UserControl : ContainerControl : ScrollableControl : Control

我只需要一个矩形来绘制和完整的 WinApi 功能(Handle、WndProc 等)。但我想避免所有可能出现在游戏中的额外内容。我想使用我的自定义控件将它们添加到标准表单中。没有极端行为。

另一方面,UserControl 扩展了 ContainerControl,它可能具有我想要的功能(我不确定)。


我从 Control 继承了一个 OpenGL 框和一些其他简单的控件。到目前为止,他们工作得很好。我没有注意到任何功能损失。 有什么东西反对Control 吗? (如果我不需要任何额外的功能)

【问题讨论】:

  • 使用用户控件,在发布问题之前请检查一下,谷歌中的信息非常多,甚至在 youtube 中也有示例,因此您可以查看可以获得的信息
  • 为什么继承深度很重要?
  • @joe 仅供参考。
  • 对于 WinAPI,您不需要在 window 级别处理所有事情吗?您只需要一个支持键盘焦点的元素(即 any UIElement),并为执行 if (Keyboard.FocusedElement == yourElement) ... 的主机窗口设置一个 WndProc

标签: c# winforms user-controls


【解决方案1】:

我认为非官方和公认的“标准”只是继承自UserControl。至少这是我在其他地方看到的。 但这并不意味着它是正确的!

另一方面,我认为您也可能过于关注在这里做的“正确的事情”。对我来说,这几乎类似于过早优化。您要确保明智地使用资源。

另外请记住,这样的事情以后总是可以更改的。

如果您出于某种原因担心,我肯定会选择最简单具有最低继承深度的控件。

【讨论】:

  • @mini-me - 然后去Panel。追随您的开发者之心。
  • 我喜欢Control,因为它是最简单和最低继承深度的。
【解决方案2】:

大多数情况下,UserControl 是最好的继承类。另一种选择可能是从我们要自定义的类继承。

在您的情况下,Panel 应该是最好的继承类,因为它是满足您要求的最简单的控制类。

【讨论】:

    【解决方案3】:

    Panel 在这里是理想的,因为您没有为控件定义布局。它也不需要ControlTemplate。自定义渲染方案通常建议使用Panel。虽然Control 是您可以获得的最简单的“布局”元素,但Panel 可以在您以后需要时托管子控件。完美!

    【讨论】:

    • 嗯,control 已经可以托管控件了。按钮可以承载 GridBox 和各种疯狂的东西。
    • 按钮继承自 ContentControl,而不是直接继承自 control。这允许他们托管单个子内容(任何对象)。面板能够开箱即用地托管许多元素(包括内容控件)。继承者唯一需要定义的是布局方法。 msdn.microsoft.com/en-us/library/…
    • a) 这在我看来像是 MSDN 中的一个错误。因为从 .NET Framework Button 的元数据来看,没有继承自任何 ContentControl。 b) 一个控件(也有按钮)可以托管(具有子控件)任意数量的其他控件。
    • @mini-me 我不知道你在看什么元数据,但typeof(ContentControl).IsAssignableFrom(typeof(Button)) 是真的,所以 Button 肯定继承了 ContentControl。但是,您是对的,所有控件都可以托管其他控件,因为它们使用 ControlTemplates。 “内容”和简单嵌套控件的区别在于使用了ContentPresenter,它通过DataTemplates 将数据转换为元素。例如,当您将 Content 设置为字符串时,presenter 将生成一个 TextBlock。
    • 当我说 ContentControl 只能托管一个孩子时,我的意思是一个 直接 孩子。
    【解决方案4】:

    “Pro WPF”一书中对 UserControl 与 ContentControl 的确切区别进行了描述,该书提供的信息比 MSDN 更多。这是该部分的直接链接:

    http://books.google.ca/books?id=znAVMHNSen0C&pg=PA518&lpg=PA518&dq=%22taking+a+closer+look+at+user+controls%22&source=bl&ots=DjZT-9JCQd&sig=R4MoAzW72PaHvqgZjxPnkkJRs6c&hl=en&sa=X&ei=OdQIUrPgDeTYyAGl6oHYAQ&ved=0CC8Q6AEwAQ#v=onepage&q=%22taking%20a%20closer%20look%20at%20user%20controls%22&f=false

    最有趣的区别在于它如何处理路由事件。包含的元素引发的所有事件都将其 Source 重置为 UserControl 本身。

    我认为概念上的区别在于 ContentControl“包含”其内容,而 UserControl 的内容是 UserControl 的“一部分”。因此,ContentControl 是一个不同的元素(可聚焦/制表位),其内容是单独处理的;并且设置 UserControl 的内容是其设计过程的一部分,其元素直接在 UserControl 的代码隐藏中处理。

    所以,我的规则是:

    • 如果用户打算继承它并在代码隐藏中处理内容,则继承 UserControl。
    • 如果要按原样使用并提供任意内容,请继承 ContentControl。
    • 如果它定义了自己的内容,并且没有任意内容的占位符,则继承Control并设置其Template。

    如果您只想要一个渲染表面,我认为您不需要Control。您可以为此使用ImageSource,例如InteropBitmap 或D3DImage,可以附加到ImageBrush。例如,它可以用在一个独立的矩形中:

    <Rectangle>
        <Rectangle.Fill>
            <ImageBrush>
                <ImageBrush.ImageSource>
                    <!-- ImageSource here -->
                </ImageBrush.ImageSource>
            </ImageBrush>
        </Rectangle.Fill>
    <Rectangle>
    

    或任何其他接受Brush 的地方,包括另一个控件的Background。

    【讨论】:

    • 好吧,我只想告诉你,这不是我的世界。我看不到您如何编写 C# 应用程序。我使用 .NET Framework 4.0 和 ContentControl 不能导入到新的 WinForms 应用程序中。我不知道你在使用什么额外的东西。我会不惜一切代价避免将自己编码到人们不会理解我的角落。
    • 那么,难怪你不知道我和 Gusdor 在说什么。 WPF 也有名为 Panel、UserControl 和 Control 的类,它自 3.0 以来一直是 .NET 的一部分,并且它在 stackoverflow 上的关注者数量是 winforms 的 3 倍以上。请务必使用winforms 标记您的问题以避免混淆。
    猜你喜欢
    • 2016-06-22
    • 1970-01-01
    • 2013-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-18
    • 1970-01-01
    相关资源
    最近更新 更多