如何在C#中重写Form.Show()方法

3
我想为表单覆盖Show()方法,但是C#不允许我这么做。我想在回到先前的窗口时刷新列表框。 我不想使用ObservableCollection等方法。
 protected override void Show() {
            base.Show();
            list.Items.Clear();
            loadListItems();
        }

'Sklep.OknoProduktow.Show()':无法覆盖继承的成员'System.Windows.Forms.Control.Show()',因为它没有标记为virtual、abstract或override。

为什么不把那段代码放到“Shown”事件处理程序方法中呢? - TLama
@HansPassant,Show是一个方法,而不是事件。 - Abdusalam Ben Haj
@TLama,我找不到OnShow,只有OnShown? - user1825608
抱歉,我的(Delphi)失误。如果您想在窗体首次显示时加载这些项,我本意是使用“Shown”事件。 - TLama
你是否正在从主窗体显示另一个窗口作为模态窗口? - Karthik
为什么不在构造函数中执行Show,然后再执行其余部分呢?您可以将这三行代码放在窗体的构造函数中,以获得相同的结果。将基类更改为this,或者直接删除它。 - David Parvin
3个回答

14
您无法覆盖 Show 方法,但可以进行屏蔽。将此代码放入窗体类中:
public new void Show()
{
     //your code here

     //call the shadowed Show method on our form.       
     base.Show();

}

对我来说是一个新的学习主题,谢谢! - SBU

12
你需要区分事件方法。如果一个事件没有声明为虚拟的话,那么重写该事件是不可能的。Form.Shown事件既不是虚拟的,也不是受保护的。
在Winforms中,还有另一种机制可以用于重写事件处理。每个事件Xxxx都有一个对应的受保护方法名为OnXxxx。OnXxxx()方法的职责是触发Xxxx事件,最终由基类中的实现来处理,如此处的Form.OnShown()。
这种方式的好处在于你可以有更多选择的方式来覆盖事件的默认处理:
  • 你可以先调用base.OnShown(),然后做任何你想要自定义事件的事情。这样就可以覆盖自定义事件处理程序的操作,例如,在OnPaint事件处理程序中非常普遍,当你想确保自己绘制的任何内容都在基类或事件处理程序绘制的任何内容之上时。
  • 你可以编写自定义代码,然后调用base.OnShown()。这样做的目标相反,自定义事件处理程序可以覆盖你所做的任何事情。这是正常的方式。
  • 你可以编写自定义代码,并且调用base.OnShown()。这将完全阻止事件处理程序运行。这样做很少见,但当你的自定义操作非常复杂,客户端代码的事件处理程序可能会出错时,你需要这样做。
  • 你可以编写自定义代码,调用base.OnShown(),但仍然触发Shown事件。这也很少见,但如果基础实现有所妨碍,你必须这样做。
因此,你方法的最可能正确实现是:
    protected override void OnShown(EventArgs e) {
        loadListItems();
        //Call the original OnShown.
        base.OnShown(e);
    }

使用第二个项目符号,允许事件处理程序自定义加载的列表。

为了不混淆更大的问题,您正在错误地执行此操作。列表应在表单构造函数中初始化。


4

为什么不使用激活事件呢?

这会有所帮助。当您的表单被激活时,您的列表框将会刷新。

我认为您不能重写 show() 方法,这就是为什么它没有解决您的问题的原因。

private void Form1_Activated(object sender, System.EventArgs e)
{
  list.Items.Clear();
  loadListItems();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接