【问题标题】:Best Way to Override ComboBox.Items覆盖 ComboBox.Items 的最佳方法
【发布时间】:2011-06-25 06:11:42
【问题描述】:

我创建了一个继承自 ComboBox 的自绘用户控件。

控件存储专门的项目,但 Items 集合仍然接受并返回 Object 类型的项目。关于覆盖此集合以确保类型安全的最佳方式的任何提示?

我能想到的唯一方法是创建自己的集合类。该类不会是一个真正的集合——它将一个 ObjectCollection 作为构造函数的参数,并简单地将其方法扩展为。

用户控件会将原始的 Items 集合传递给新类的构造函数。然后重写 Items 属性以返回新类的实例。

这似乎有些令人费解。有没有更好的办法?

【问题讨论】:

  • 即使你这样做了,设计师也不会非常关心你的重新实现。你可能无法使用它。为什么首先需要对集合进行强类型化?
  • “可能无法使用它”是什么意思。我确定您知道可以以编程方式添加项目。如果将我的专用类型以外的任何内容添加到列表中,我的代码将崩溃。 (我假设你也知道类型安全的好处。)
  • 第二句引用第一句:您可能无法在设计器中使用它。显然,我知道您可以通过编程方式与控件进行交互,但对于大多数习惯于 Visual Studio 特权的开发人员来说,这通常是遥不可及的第二选择。我理解类型安全的好处,我只是担心你在这里失去的东西可能不值得这些好处。控件是在前泛型时代开发的,对此没有特别好的解决方案。隐藏/遮蔽方法不是真正的多态性。
  • @Cody:是的,这是一个简单的任务,最后,我放弃了覆盖 Items 集合。和你一样,我得出的结论是,对此没有特别好的解决方案。

标签: c# winforms inheritance controls ownerdrawn


【解决方案1】:

您可以通过几种不同的方式进行操作。首先,我对您创建一个继承自 ComboBox 的“用户控件”感到有些困惑。您可以创建一个继承自 ComboBox 的 自定义 控件,但不能同时继承自 UserControl(这是“用户控件”的通常定义)和 ComboBox。

如果您定义一个真正的 UserControl 派生类,这会变得容易一些。就像我说的,UserControl 不能成为 ComboBox,但它可以拥有 ComboBox。因此,您可以将 ComboBox 拖放到您的 UserControl 表面,然后重新实现您需要能够使用的任何属性,例如 Items。这将允许您将项目重新创建为您选择的集合,可能是强类型列表。唯一的问题是确切地知道你想要重新实现什么; ComboBox 有很多有用的属性,除非您实现修改 UserControl 中包含的 ComboBox 的“传递”属性,否则您将无法在设计器或代码中访问它们。

如果你直接从 ComboBox 继承,它在某些方面会变得有点棘手,而在其他方面则更容易。您可以通过定义自己的并使用 new 关键字来隐藏 Items 的基类实现。执行此操作时,您可以更改可见性、类型和其他修饰符。这将阻止将您的控件作为 CustomComboBox(或您命名的任何名称)处理的代码使用基类上的对象数组;他们必须使用您的强类型 Items 数组。您的新属性仍然可以访问旧属性(它需要它才能使其工作)。您还可以免费获得 ComboBox 的所有其他公共属性;你只需要重新实现你想要改变的东西。但是,将您的自定义 ComboBox 引用为任何基类将导致运行时使用对该类有效的 Items 版本;也就是说,对象数组,而不是你的强类型数组。

【讨论】:

  • 如前所述,它继承自 ComboBox。我想它叫什么并不重要。我不确定“将您的自定义 ComboBox 称为任何基类”是什么意思,但您的最后一段更接近我想要的。也许我可以隐藏 Items 属性,而无需创建新属性。 (我只会添加 Add() 等方法)
  • 当我说“将您的自定义 ComboBox 称为任何基类”时,我的意思是如果您有逻辑查看 ComboBox 的 Controls 层次结构,它将找到您的自定义控件(这是一个 ComboBox)并可能将其视为 ComboBox 而不是自定义类。如果发生这种情况,并且它引用了 Items,它将使用基于 Objects 的 Items 属性,而不是您定义的新 Items 属性。
  • 好吧,我不太在意这个。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-07-22
  • 2017-08-05
  • 1970-01-01
  • 2013-04-28
  • 1970-01-01
  • 1970-01-01
  • 2018-09-06
相关资源
最近更新 更多