3

我正在使用一个自定义类,并且有一个事件处理程序来监视一个属性,并且只在特定情况下做出反应。

这是基类的一个片段:

public class PageView
{
    private UIView activePage;
    public List<UIView> Pages { get; set; }
    public delegate void PageChangedEventHandler(object sender, PageChangedEventArgs e);
    public event PageChangedEventHandler PageChanged;

    public UIView ActivePage
    {
        get { return activePage; }
        set
        {
            if (!activePage.Equals(value))
            {
                activePage = value;
                OnPageChanged();
            }
        }
    }

    protected virtual void OnPageChanged()
    {
        if (PageChanged != null) 
           PageChanged(this, new PageChangedEventArgs(Pages.IndexOf(activePage)));
    }
}

这是我在子类中尝试做的事情:

public class LoopingPageView : PageView
{
    protected override void OnPageChanged()
    {
        if (PageChanged != null && 
            Pages.IndexOf(ActivePage) > 0 && 
            Pages.IndexOf(ActivePage) < Pages.Count - 1) 
          PageChanged(this, Pages.IndexOf(ActivePage) - 1);
    }
}

但是,我收到消息,PageChanged 只能存在于 += 或 -= 语句的左侧。处理这种情况的正确方法是什么?

4

1 回答 1

6

PageChanged是场类事件。从声明类之外——甚至在子类中——你只能使用它来订阅和取消订阅事件。

这里的解决方案通常是简单地委托给有条件的基本实现OnPageChanged

public class LoopingPageView : PageView
{
    protected override void OnPageChanged()
    {
        int pageIndex = Pages.IndexOf(ActivePage);
        if (pageIndex > 0 && pageIndex < Pages.Count - 1)
        {
            base.OnPageChanged();
        }
    }
}

但是,在这种情况下,您也尝试更改传递给处理程序的值。您无法使用当前设置执行此操作。

如果你真的需要这样做(这对我来说似乎很奇怪,并且违反了最不意外的原则 - 子类的行为与基类有很大不同)你可能应该OnPageChanged()委托一个使用页面索引的重载(或 - PageChangedEventArgs) 在这种情况下,您的覆盖OnPageChanged()可以使用不同的索引调用它。例如:

protected virtual void OnPageChanged()
{ 
    OnPageChanged(new PageChangedEventArgs(Pages.IndexOf(activePage));
}

// Note: this doesn't need to be virtual.
protected void OnPageChanged(PageChangedEventArgs args)
{
    // Null-safe event raising
    var handler = PageChanged;
    if (handler != null)
    {
        handler(this, args);
    }
}

然后在派生类中:

protected override void OnPageChanged()
{
    int pageIndex = Pages.IndexOf(ActivePage);
    if (pageIndex > 0 && pageIndex < Pages.Count - 1)
    {
        base.OnPageChanged(new PageChangedEventArgs(pageIndex - 1));
    }
}
于 2013-08-05T16:17:49.030 回答