2017-02-20 4 views
1

Я работаю над проектом WPF с использованием Caliburn Micro в качестве основы для MVVM, и на прошлой неделе мне посчастливилось найти любое решение любой проблемы на StackOverflow, но теперь у меня большая проблема, которую я не могу решить сам.Caliburn Micro Action внутри ItemContainerStyle - не найдена цель для метода

У меня есть вид, содержащий TreeView; каждый элемент в TreeView должен вызвать метод, когда:

  • это дважды щелкнуть мышью [работает]
  • въездной его контекстного меню нажата [не работает]

Это TreeView:

<TreeView x:Name="projectTreeView" 
       Visibility="{Binding ExplorerVisibility, Converter={StaticResource visibilityConverter}}"> 
     <TreeViewItem Header="{Binding ProjectName}" IsExpanded="True"> 
      <TreeViewItem Header="Category 1"/> 
      <TreeViewItem Header="Category 2" ItemsSource="{Binding Images}"> 
       <TreeViewItem.ItemContainerStyle> 
        <Style TargetType="TreeViewItem"> 
         <Setter Property="ContextMenu"> 
          <Setter.Value> 
           <ContextMenu> 
            <MenuItem Header="Remove" 
               cal:Action.TargetWithoutContext="{Binding Path=DataContext, ElementName=projectTreeView}" 
               cal:Message.Attach="[Event Click] = [Action RemoveResource()]"/> 
           </ContextMenu> 
          </Setter.Value> 
         </Setter> 
        </Style> 
       </TreeViewItem.ItemContainerStyle> 
       <TreeViewItem.ItemTemplate> 
        <HierarchicalDataTemplate> 
         <HierarchicalDataTemplate.ItemContainerStyle> 
          <Style TargetType="TreeViewItem"> 
           <Setter Property="IsExpanded" Value="True" /> 
           <Style.Triggers> 
            <EventTrigger RoutedEvent="Collapsed"> 
             <EventTrigger.Actions> 
              <BeginStoryboard> 
               <Storyboard> 
                <BooleanAnimationUsingKeyFrames 
            Duration="0" 
            Storyboard.TargetProperty="(TreeViewItem.IsExpanded)"> 
                 <DiscreteBooleanKeyFrame KeyTime="0" Value="True" /> 
                </BooleanAnimationUsingKeyFrames> 
               </Storyboard> 
              </BeginStoryboard> 
             </EventTrigger.Actions> 
            </EventTrigger> 
           </Style.Triggers> 
          </Style> 
         </HierarchicalDataTemplate.ItemContainerStyle> 
         <ContentControl cal:Action.TargetWithoutContext="{Binding Path=DataContext, ElementName=projectTreeView}" 
             cal:Message.Attach="[Event MouseDoubleClick] = [Action OpenResource(projectTreeView.SelectedItem)]"> 
          <StackPanel Orientation="Horizontal"> 
           <TextBlock Text="{Binding ResourceName}" Margin="5,0,0,0"/> 
          </StackPanel> 
         </ContentControl> 

         <HierarchicalDataTemplate.ItemTemplate> 
          <DataTemplate> 
           <TextBlock Text="{Binding}"/> 
          </DataTemplate> 
         </HierarchicalDataTemplate.ItemTemplate> 

        </HierarchicalDataTemplate> 
       </TreeViewItem.ItemTemplate> 
      </TreeViewItem> 
     </TreeViewItem> 
    </TreeView> 

В прилагаемой модели представления содержит оба метода:

public class MyViewModel 
{ 
    ... 

    public void OpenResource(object obj) { ... } 

    public void RemoveResource() { ... } 

} 

По какой-то причине OpenResource прекрасно работает, в то время как при нажатии на пункт контекстного меню (после правой кнопкой мыши) сбои приложений, за исключением:

An unhandled exception of type 'System.Exception' occurred in WindowsBase.dll 

Additional information: No target found for method RemoveResource. 

я нашел что-то связано с той же проблемой здесь форум и форум поддержки, но я не смог решить проблему с этими советами.

У вас есть идеи о том, что происходит в моем TreeView?

Большое спасибо за помощь!

+0

ли RemoveResource() должен иметь параметр объекта OBJ? – gabba

+0

http://caliburnmicro.codeplex.com/discussions/287228 Проверьте, работает ли это для вас (последнее сообщение EisenbergEffect). – ShadeOfGrey

ответ

2

ContextMenu находится в собственном визуальном дереве и не может связываться с TreeView с использованием ElementName.

Вы могли бы попытаться связать Tag свойство TreeViewItem родителю TreeView, а затем привязать к нему, используя PlacementTarget свойство ContextMenu:

<Style TargetType="TreeViewItem"> 
    <Setter Property="Tag" Value="{Binding RelativeSource={RelativeSource AncestorType=TreeView}}" /> 
    <Setter Property="ContextMenu"> 
     <Setter.Value> 
      <ContextMenu> 
       <MenuItem Header="Remove" 
            cal:Action.TargetWithoutContext="{Binding Path=PlacementTarget.Tag.DataContext, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}" 
            cal:Message.Attach="[Event Click] = [Action RemoveResource()]"/> 
      </ContextMenu> 
     </Setter.Value> 
    </Setter> 
</Style> 
+0

Большое спасибо, вы здорово! Он работает, я просто пришлось редактировать TargetWithoutContext немного: кал: Action.TargetWithoutContext = "{Binding Path = PlacementTarget.Tag.DataContext, RelativeSource = {RelativeSource Mode = FindAncestor, AncestorType = ContextMenu}}" МОГ пожалуйста, обновите ответ для дальнейшего использования? Теперь у меня есть последний вопрос: как передать объект, привязанный к TreeViewItem, к RemoveResource? Еще раз спасибо!!! – Brutus

+0

Я обновил ответ. Если у вас есть новый вопрос, задайте новый вопрос. В комментариях это немного грязно. – mm8

+1

Я нашел один, это было так же просто, как с помощью [Action RemoveResource ($ datacontext)]. Еще раз спасибо, я действительно понятия не имел, как решить! :) – Brutus

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