2012-11-27 1 views
6

У меня есть окно списка, для которого я ставил ItemContainer, чтобы включить контекстное меню. Вот и xaml для того же.«Цель не найдена для метода», брошенная Caliburn Message.Attach()

<ListBox.ItemContainerStyle> 
    <Style TargetType="{x:Type ListBoxItem}"> 
    ... 
     <Setter Property="ContextMenu"> 
      <Setter.Value> 
       <ContextMenu> 
        <MenuItem Header="Remove Group" cal:Message.Attach="DeleteGroup"/> 
       </ContextMenu> 
      </Setter.Value> 
     </Setter> 
    </Style> 

Я закодировал целевой метод в ViewModel, как показано ниже.

public void DeleteGroup() { //ToDo 
    ... 
} 

модели представления устанавливается как DataContext от UserControl, в котором есть ListBox.

Приведенный выше код приводит к «цели не найдены для метода». Я не знаю, почему это не работает. Я также попытался следующие изменения

<MenuItem Header="Remove Group" cal:Message.Attach="DeleteGroup" 
      cal:Action.Target="{Binding ElementName=UCRelayDispositionView, Path=DataContext}"> 

где UCRelayDispositionView это имя UserControl.

Почему приведенный выше код не работает?

Edit: 1 Также попробовал следующую

<MenuItem Header="Remove Group" cal:Message.Attach="DeleteGroup" 
      cal:Action.TargetWithoutContext="{Binding ElementName=UCRelayDispositionView, Path=DataContext}"> 

и этот

<MenuItem Header="Remove Group" cal:Message.Attach="DeleteGroup" 
      cal:Action.TargetWithoutContext="{Binding ElementName=UCRelayDispositionView}"> 

EDIT: 2 Я пытался использовать тег следующим образом на ItemContainer но он тоже не работает.

<ListBox.ItemContainerStyle> 
    <Style TargetType="{x:Type ListBoxItem}"> 
     <Setter Property="Tag" Value="{Binding Path=DataContext, ElementName=UCRelayDispositionView}"/> 
     <Setter Property="ContextMenu"> 
      <Setter.Value> 
       <ContextMenu> 
        <MenuItem Header="Remove Group" 
           cal:Message.Attach="DeleteGroup()" 
           cal:Action.TargetWithoutContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Self}}"/>          
        </ContextMenu> 
      </Setter.Value> 
    </Style> 
</ListBox.ItemContainerStyle> 

EDIT 3: Связывание Ошибки

System.Windows.Data Error: 40 : BindingExpression path error: 'PlacementTarget' property not found on 'object' ''MenuItem' (Name='')'. BindingExpression:Path=PlacementTarget.Tag; DataItem='MenuItem' (Name=''); target element is 'MenuItem' (Name=''); target property is 'TargetWithoutContext' (type 'Object') 
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'ElementName=UCRelayDispositionView'. BindingExpression:Path=DataContext; DataItem=null; target element is 'ContextMenu' (Name=''); target property is 'Tag' (type 'Object') 

ответ

10

Ваша проблема заключается в том, что вы пытаетесь связать цель к элементу, который не существует в том же визуальном дереве, например, у вас есть ContextMenu, на котором находится элемент.

Чтобы правильно получить цель действия, вам необходимо использовать ContextMenu s PlacementTarget.

Заканчивать следующий ответ на SO для XAML

WPF Context Menus in Caliburn Micro

Так следующий XAML должен работать:

<MenuItem Header="Blah" cal:Message.Attach="SomeMethod()" cal:Action.TargetWithoutContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}"> 

Это следует искать PlacementTarget на ContextMenu и установить цели для действия со значением PlacementTarget.Tag (который должен быть ListBoxItem).

Если вы установили ListBoxItem.Tag (как вы уже сделали), чтобы быть DataContext родительского контейнера (ListBox), вы должны быть в порядке

поэтому тег привязки должен быть:

<Setter Property="Tag" Value="{Binding Path=DataContext, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListBox}}"/> 

например все это должно быть:

<ListBox.ItemContainerStyle> 
    <Style TargetType="{x:Type ListBoxItem}"> 
     <Setter Property="Tag" Value="{Binding Path=DataContext, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListBox}}"/> 
     <Setter Property="ContextMenu"> 
      <Setter.Value> 
       <ContextMenu cal:Action.TargetWithoutContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}"> 
        <MenuItem Header="Remove Group" cal:Message.Attach="DeleteGroup()" /> 
       </ContextMenu> 
      </Setter.Value> 
     </Setter> 
    </Style> 
</ListBox.ItemContainerStyle> 
+0

Ваш код не работает. Все еще дает ту же ошибку. Что касается использования тега, где его разместить? У меня есть это контекстное меню на ItemContainerStyle! – Jatin

+0

Если вы посмотрите в ссылке SO, которую я опубликовал, есть пример того, где ее разместить. В основном вам нужно использовать свойство ContextMenu.PlacementTarget', чтобы получить элемент, который породил контекстное меню и привязал его к «DataContext», хотя для этого может потребоваться взломать «DataContext» родительского контейнера в свойство «Tag» , Это работает для меня (возможно, стоит создать событие в представлении, чтобы вы могли попасть в код и отлаживать его при нажатии на элемент меню. Таким образом, вы можете изучить граф объектов и найти правильный путь привязки) – Charleh

+0

Я отредактировал вопрос, помеченный как ** EDIT 2 **. Я не уверен, можем ли мы использовать стиль для установки тега, как это, но такая же ошибка сохраняется. – Jatin

Смежные вопросы