2015-03-24 6 views
0

я читал XML в класс:MenuItem событие вызывается несколько раз

public class MenuItem 
{ 
    public string Header{get;set;} 
    public List<MenuItem> ChildMenuItems{get;set;} 
} 

Так я получаю

  • Меню 1
    • Меню 1.1
    • Меню 1,2
      • меню 1.2.1
      • Меню 1.2.2
  • Меню 2
    • Меню 2.1
    • Меню 2,2

Затем установите список в M enuViewModel

MenuItems = new ObservableCollection<MenuItem>(Service.GetMenu()); 

И в UserControl установить Properites для Caliburn Message.Attach и Action.TargetWithoutContext

<Setter Property="cal:Message.Attach" Value="[Event Click] = [Action MenuClick($originalsourcecontext)]" /> 
<Setter Property="cal:Action.TargetWithoutContext" Value="{Binding Path=DataContext, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}" /> 

Метод "MenuClick" иногда называют еще раз, то ожидается:

Если я Нажмите Меню 1 - > MenuClick выполняется 1 раз
Если я нажму Меню 1.1 -> MenuClick выполняется 2 раза
Если я нажму Меню 1.2.1 -> MenuClick выполняется 3 раза

Но я хотел бы, чтобы события Menu 1.1 и Menu 1.2.1 вызывались только один раз.
Любая идея?

ответ

1

Не знаете, почему это происходит, но это, вероятно, связано с бурлящим событием.

Когда вы нажимаете на верхний пункт меню, сообщение о действии не отправляется. Только когда меню закрывается, срабатывает сообщение о действии.

Если вы хотите этого избежать, вы можете просто взглянуть на RoutedEventArgs и убедиться, что OriginalSource соответствует ActionExecutionContext.Source.

например.

public void MenuClick(ActionExecutionContext context) 
{ 
    var routed = context.EventArgs as RoutedEventArgs; 

    if(routed == null) 
     throw new Exception("No routed event"); 

    if (routed.OriginalSource == context.Source) 
    { 
     MessageBox.Show(((MenuItem)context.Source).Header.ToString()); 
    } 
} 

Отказ от ответственности: Там может быть гораздо более простой способ сделать это

Update:

Ok маркирование Маршрутизованный событие как обработанное останавливает его барботирования, так что-то делать с продуванием - Я бы просто использовал приведенный ниже код, чтобы остановить событие, распространяющееся дальше по дереву

public void MenuClick(ActionExecutionContext context) 
{ 
    var routed = context.EventArgs as RoutedEventArgs; 

    if (routed != null) 
     routed.Handled = true; 

    MessageBox.Show(((MenuItem) context.Source).Header.ToString()); 
} 
Смежные вопросы