如何在C#中的WinForm UserControl中重载方法和事件?

4
我在C# WinForms中有一个名为BaseControl的自定义控件,在那里我有一个名为Selected的属性。
我想在基础控件中拥有一个名为SelectedChanged的事件和虚方法OnSelecteChanged,并且它们应该像我们在Control类中对许多属性所做的那样,即有Click事件和OnClick方法。
这意味着任何从我的BaseControl派生出来的人都可以绑定到事件或覆盖OnSelectedChanged方法。
因此,当Selected属性的值发生变化时,事件应该被触发,如果方法被覆盖,则控制权应转移到该方法。
我知道如何触发事件,但不知道如何处理方法。
请指导我...
3个回答

3
以下是事件实现的示例:
public class BaseControl : Control
{
    private object _selected;

    public object Selected
    {
        get { return _selected; }
        set
        {
            if (!Equals(_selected, value))
            {
                _selected = value;
                OnSelectedChanged(EventArgs.Empty);
            }
        }
    }

    public event EventHandler SelectedChanged;

    protected virtual void OnSelectedChanged(EventArgs e)
    {
        if (SelectedChanged != null)
            SelectedChanged(this, e);
    }
}

使用此示例,您可以在覆盖类中覆盖OnSelectedChanged,如下所示:
public class MyControl : BaseControl
{
    protected override void OnSelectedChanged(EventArgs e)
    {
        base.OnSelectedChanged(e);

        // My own logic.
    }
}

您的OnSelectedChanged实现存在潜在的线程问题(如果在空值检查和事件触发之间,最后一个侦听器取消订阅会发生什么?--> 您将获得NullReferenceException)。 - Jürgen Steinblock
@SchlaWiener - 对于 UI 编程来说,这不是问题,因为 UI 控件并不是多线程安全的,应该只从一个线程访问。但是,你是正确的。 - Pieter van Ginkel

1
private bool _selected;

public bool Selected
{
    get { return _selected; }
    set
    {
        if (value != _selected)
        {
            _selected = value;
            OnSelectedChanged();
        }
    }
}

public event EventHandler SelectedChanged;

protected virtual void OnSelectedChanged()
{
    var handler = SelectedChanged;
    if (handler != null)
        handler(this, EventArgs.Empty);
}

0
基本上,您不会从Selected属性设置器中触发事件 - 您会调用该方法,并使该方法调用事件。任何重写该方法的人都应该调用base.OnSelectedChanged以确保事件仍然触发。因此,您的方法应该如下所示:
protected virtual void OnSelectedChanged(EventArgs e) {
    EventHandler handler = Selected; // Or your own delegate variable
    if (handler != null) {
        handler(this, e);
    }
}

你为什么要复制事件处理程序? - Pieter van Ginkel

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