在属性更改后何时调用方法

时间:2012-04-12 18:59:10

标签: c# winforms events user-controls event-handling

我有一个用户控件,其中包含一个项目列表,当currentIndex发生更改时我会引发一个事件,当它发生更改时,我必须调用另外两个方法两个验证并更改控件的外观(更改图像和阻止/取消阻止某些按钮。)

我想知道的,主要是出于好奇,因为它已经有效了,何时调用这两种方法更合适?

我应该在CurrentIndex财产本身内打电话给他们吗?我应该在OnCurrentIndexChanged(...)内打电话给他们吗?我应该在课堂上处理这个事件吗?

3 个答案:

答案 0 :(得分:6)

我假设您已经实现了标准事件生成模式并使OnCurrentIndexChanged protected virtual成为派生类可以覆盖该方法并改变事件生成和/或处理。

不幸的是,这需要阅读茶叶,为什么会有人想要覆盖这个方法吗?更严重的是,如何覆盖该方法会破坏你的控制权?对于那些不熟悉代码的人来说,这非常难以猜测,对你来说也不是很容易。这里应用的原则,在.NET框架代码中使用,也是尽可能少的。只是举起活动,别的什么。当派生类做了一些愚蠢的事情时,它最大限度地减少了破损的可能性,但是很常见,比如不调用base.OnCurrentIndexChanged。

控件的行为是UserControl的实现细节。因此,在CurrentIndex属性设置器中更改其属性,然后调用OnCurrentIndexChanged()。如果需要,任何派生自您的类的人都可以覆盖该行为。当他们忘记调用你的OnCurrentIndexChanged()方法时没有出错。但请注意,您需要使控制变量受保护而不是私有。因此,如果他们需要,他们可以覆盖行为。

如果这对你来说太怪异,请不要犹豫,不要使用虚拟方法。使用您的控件来容纳成千上万的程序员并不常见:)

答案 1 :(得分:2)

在用户控件中,我将拥有一个表示所选项目的属性。然后,在对象的setter期间,引发事件方法以更改用户控件。这样,在将来,如果需要添加更多侦听器,则只需在setter方法中添加另一个处理程序。这在MVVM应用程序中非常常见,并且非常易于维护。

答案 2 :(得分:1)

因为UserControl充当ListControl,所以需要实现两个事件和两个属性。

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应始终用于在更改所选索引时始终需要触发的操作。当用户实际更改选择时,{em} 会被触发。两者之间的分离是一个重要的区别,.NET中的大多数控件都遵循这种模式(例如ComboBox),但可能不会对事件使用相同的名称。

现在,如上所述,如果您需要更改属性的控件也在同一个用户控件中,那么您当然应该在适当的事件中在用户控件代码中处理它。否则,代码应该通过订阅事件并在那里进行工作而孤立于实现用户控件的任何人(例如,表单或其他用户控件)。

订单实际上取决于您的要求,但SelectionChangeCommitted应该总是被引发(但每次更改不会超过一次,因为这会引入奇怪的行为),并再次{{1}只应由用户引发(例如,设置SelectedIndex或SelectedItem)。

一个好的经验法则是,如果您的内部资料必须在用户知道之前发生,请先调用SelectedIndexChanged,然后调用SelectionChangeCommitted。如果无关紧要,或者。稍后更改订单可能会导致实施控制的人员发生变化,因此请确保您的决定是可靠的。

两者之间的区别是SelectedIndex和SelectedItem将通过内部清除列表,添加新项目等等来更新,但并不一定意味着它是一个物理用户操作,应该导致您的事件都被触发。

希望这有帮助。