for example. When you select a tabpage in a tabcontrol, the TableSelected event will be rosed. But when you are creating a brand new table, you don't want the TableSelected event raised.
without the "latch", if you add a new item and do some initialization:
add a new item -> fire SelectedItemChanged -> event handler -> do initialization to the item
with the "latch"
add a new item (set the flag false) -> fire SelectedItemChanged -> (check the flag and not execute the event handler) event handler -> do initialization to the item
:
public delegate void VoidHandler();
public class Latch
{
private int _count = 0;
public void Increment()
{
_count++;
}
public void Decrement()
{
_count--;
}
public bool IsLatched
{
get { return _count > 0; }
}
public void RunInsideLatch(VoidHandler handler)
{
Increment();
handler();
Decrement();
}
public void RunLatchedOperation(VoidHandler handler)
{
if (IsLatched)
{
return;
}
handler();
}
There isn't too much to the usage. In the method that performs work you might do this:
_latch.RunInsideLatch(delegate
{
// The actions that spawn cascading events
activatePresenter(presenter, page);
_tabControl.Items.Add(page);
_tabControl.SelectedTab = page;
}
);
In an event handler effected by this work you could guard the event propagation by doing this
void TabControl_TabSelected(object sender, TabEventArgs args)
{
if (_latch.IsLatched)
{
return;
}
ContentTab tab = (ContentTab) TabControl.SelectedTab;
activatePresenter(tab.Presenter, tab);
}
or this version (fun with anonymous delegates):
void TabControl_TabSelected(object sender, TabEventArgs args)
{
_latch.RunLatchedOperation(
delegate
{
ContentTab tab = (ContentTab)TabControl.SelectedTab;
activatePresenter(tab.Presenter, tab);
});
}