2011-05-22 136 views
1

之前我推倒重来...如何处理顺序调用事件处理程序?

这只是一个为说明问题 - 让我们说你有一些数据的收集和前端这显示集合的一个项目后端。

在后端我有ItemIndex - 每当它发生变化,它就会触发OnScroll事件。

我也有AddNewItem方法,它在集合的末尾添加新项目。该方法的结尾调用OnNewItem事件处理程序。

这里是catch-in AddNewItem我必须改变ItemIndex,它会触发OnScroll。 (!)OnScroll和OnNewItem的两个接收者之一,如果前端显示选定的项目。

在这种情况下,它被称为两次(不好)。一种解决方案是改变item_index而不是ItemIndex,并且这样防止OnScroll,但我不喜欢它,因为ItemIndex不再作为黑盒子。

是否有任何已建立的顺序点火事件模式,并且只发送“重要”事件(这里是:OnNewItem重写OnScroll)?我的想法是定义一个事件范围,然后不是直接发送事件,而是将它们注册为发送,并在范围结束时对它们进行排序并发送所需的范围。

一般 - 问题 - 我应该如何处理潜在的顺序事件触发。使用内部消息来避免发送冗余事件?忽略开销? ...?

+0

就像那个问题一样。不知道这个我自己。我的解决方案始终是直接设置字段,或者有一些不会触发事件的ItemIndexInternal。 – 2011-05-22 16:21:35

+0

也是我的,但是如果我的程序变得越来越大,这种方法将会成为问题。 – greenoldman 2011-05-22 16:46:58

回答

2

答案似乎明显,我athough我可以很容易地错过了一些东西:

private bool IsAdding { get; set; } 
private int item_index; 
private IList m_collection; 

public void AddNewItem(object item) 
{ 
    if (item == null) 
    { 
     throw new Exception("Cannot add null item."); // little bit of contracting never hurts 
    } 

    m_collection.Add(item); 
    IsAdding = true; 
    ItemIndex = collection.Count - 1; //I'm just making assumptions about this piece but it is not important how you decide what your index is to answer the question 

    if (OnNewItem != null) 
    { 
     OnNewItem(this, EventArgs.Empty); 
    } 
} 

public int ItemIndex 
{ 
    get { return item_index =; } 
    set 
    { 
     item_index = value; 
     if (!IsAdding && OnScroll != null) //won't double fire event thanks to IsAdding 
     { 
      OnScroll(this, EventArgs.Empty); 
     } 
     IsAdding = false; //need to reset it 
    } 
} 

有一件事我要指出的是,你做的只是简单的直接改变item_index提到但不会有黑箱行为。那么黑匣子是一切都很好......但这个术语只适用于与我们一直在讨论的这个类交互的对象。

你应该感觉自己有权利使用自己班内的内部。黑箱内的项目不是很好的OOP。如果你这样做,那么你的班级可能有设计问题,它应该被分成多个班级。

+0

有关设计的好处,但我仍然更喜欢黑箱 - 加载,保存,添加,删除等等,很容易错过一些东西。最好花更多时间在更坚实的设计上,而不是寻找错误,因为每种方法都会假设其他方法。我将使用你的想法与IsAdding,而是将其更改为EventPending并检查当前的优先级是否更大或更小。 – greenoldman 2011-05-22 16:51:25

+0

@macias给他自己= P你的命名约定可能会更有意义。很高兴帮助。 – 2011-05-22 19:34:10

0

您可以将这两个事件指向一个函数。该功能可以确定发件人并执行适当的操作。

+0

“点”是什么意思? – greenoldman 2011-05-22 15:55:07

+0

只需像通常那样为代表分配一个功能即可。 – Jordan 2011-05-22 16:26:55

+0

我很抱歉,我不明白你在说什么。我的代码是ItemIndex = Items.Count-1; if(OnNewItem!= null)OnNewItem();你在哪里看到另一位代表的位置? – greenoldman 2011-05-22 16:46:12

2

一个解决方案是使用某种形式的“锁存器”。更新时,您通过帮助者执行UI操作,帮助者设置一个标志,说'嗨,我处于特殊状态!'。然后,在提高事件时,检查是否设置了锁定 - 如果是,则跳过提出这些事件。

它基本上是一个非常简单的,马修张贴的通用版本。根据情况,设置一个标志可能绰绰有余。

Jeremy Miller's explanation is worth reading