>我有一个包含项目列表的用户控件,当当前索引更改时,我引发一个事件,而且,当它更改时,我必须调用另外两个方法来验证和更改控件的外观(更改图像并阻止/取消阻止某些按钮)。
我想知道的是,主要是出于好奇,因为它已经在工作了,什么时候称这两种方法更合适?
我应该在CurrentIndex
属性本身内调用它们吗?我应该在OnCurrentIndexChanged(...)
内打电话给他们吗?我应该在类中处理事件并在那里进行吗?
我假设您已经实现了标准事件生成模式并使 OnCurrentIndexChanged protected virtual
,以便派生类可以重写该方法并更改事件生成和/或处理。
不幸的是,这需要阅读茶叶,为什么有人想覆盖这种方法? 更严重的是,当他们这样做时,覆盖该方法如何破坏您的控制? 对于任何不太了解代码的人来说,这都很难猜测,对你来说也不容易。 此处应用的原则(也用于 .NET 框架代码)是尽可能少地执行操作。 只是提出事件,没有别的。 当派生类做一些愚蠢但完全常见的事情(例如不调用 base)时,这最大限度地减少了损坏的几率。OnCurrentIndexChanged.
控件的行为是用户控件的实现详细信息。 因此,在 CurrentIndex 属性库器中更改它们的属性,然后调用 OnCurrentIndexChanged()。 如有必要,从您的类派生的任何人都可以重写该行为。 当他们忘记调用您的OnCurrentIndexChanged()方法时,没有任何问题。但请注意,您需要使控制变量受到保护而不是私有。 因此,如果需要,他们可以覆盖该行为。
不要犹豫,如果这对你来说太诡异了,根本不使用虚拟方法。 必须用您的控件容纳数十万程序员的情况并不常见:)
在用户控件中,我将有一个表示所选项的属性。 然后,在对象的资源库期间,引发事件方法以更改用户控件。这样,将来如果需要添加更多侦听器,则只需在 setter 方法中添加另一个处理程序即可。 这在 MVVM 应用程序中很常见,并且非常易于维护。
由于用户控件充当列表控件,因此需要实现两个事件和两个属性。
public event System.EventHandler SelectedIndexChanged;
public event System.EventHandler SelectionChangeCommitted;
public int SelectedIndex {
get;
set;
}
public T SelectedItem { // Where T is whatever your type is
get;
set;
}
SelectedIndexChanged
应始终用于更改所选索引时始终需要触发的操作。 仅当用户物理更改选择时,才应触发SelectionChangeCommitted
。两者之间的分离是一个重要的区别,.NET 中的大多数控件都遵循此模式(例如。组合框),但不能对事件使用相同的名称。
虽如此,如果需要更改其属性的控件也位于同一用户控件中,则当然应在相应事件的用户控件代码中处理该控件。否则,代码应通过订阅事件并在那里执行工作,孤立于实现用户控件(例如窗体或其他用户控件)的任何人。
顺序实际上取决于您的要求,但SelectedIndexChanged
应始终提出(但每次更改不要超过一次,因为这会引入奇怪的行为),并且再次SelectionChangeCommitted
只能由用户提出(例如,设置SelectedIndex或SelectedItem)。
一个好的经验法则是,如果你的内部事情必须在用户知道之前发生,请先调用 SelectedIndexChanged,然后调用 SelectionChangeCommitted。如果没关系,要么。稍后更改顺序可能会导致实现控件的人员发生重大更改,因此请确保您的决定是可靠的。
两者之间的区别在于 SelectedIndex 和 SelectedItem 将通过内部清除列表、添加新项目等方式进行更新,但并不一定意味着这是一个物理用户操作,应该导致您的两个事件都触发。
希望这有帮助。