2015-09-09 2 views
1

Я заполнил ListView объектами, и я привязал ContextMenu к тем элементам в моем ListView. ContextMenu можно открыть только щелчком по элементу. Проблема заключается в том, что Caliburn Micro выдает ошибку, которая не может найти целевой метод для ShowProperties().Caliburn Micro не находит DataContext в ContextMenu в ListView

Я думаю, что эта проблема возникает из-за того, что Caliburn не имеет правильного DataContext доступной ViewModel. Я пробовал много решений на Stackoverflow, чтобы сделать ViewModel доступными для пункта ContextMenu, но безрезультатно, например:

WPF: Binding a ContextMenu to an MVVM Command

“No target found for method” thrown by Caliburn Message.Attach()

WPF Context Menus in Caliburn Micro

Это XAML код моего зрения :

<Window x:Class="CueMaster.Views.AppView" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:dragDrop="clr-namespace:GongSolutions.Wpf.DragDrop;assembly=GongSolutions.Wpf.DragDrop" 
     xmlns:cal="http://www.caliburnproject.org" 
     Height="500" Width="800"> 
<Grid> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="*" /> 
    </Grid.RowDefinitions> 
    <Grid.ColumnDefinitions> 
     <ColumnDefinition Width="200" /> 
     <ColumnDefinition Width="*" /> 
    </Grid.ColumnDefinitions> 

    <ListView Grid.Column="1" Margin="5" 
     ItemsSource="{Binding Cues}" 
     dragDrop:DragDrop.IsDragSource="True" 
     dragDrop:DragDrop.IsDropTarget="True" 
     dragDrop:DragDrop.DropHandler="{Binding}"> 

     <ListView.Resources> 
      <ContextMenu x:Key="ItemContextMenu"> 
       <MenuItem Header="Properties" cal:Message.Attach="ShowProperties($dataContext)" Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListView}}"> 
        <MenuItem.Icon> 
         <Image Source="../PropertyIcon.png" /> 
        </MenuItem.Icon> 
       </MenuItem> 
      </ContextMenu> 
     </ListView.Resources> 

     <ListView.ItemContainerStyle> 
      <Style TargetType="{x:Type ListViewItem}" > 
       <Setter Property="ContextMenu" Value="{StaticResource ItemContextMenu}" /> 
      </Style> 
     </ListView.ItemContainerStyle> 

     <ListView.View> 
      <GridView > 
       <GridViewColumn Width="70" Header="Cue" DisplayMemberBinding="{Binding Id}" /> 
       <GridViewColumn Width="100" Header="Name" DisplayMemberBinding="{Binding Name}" /> 
       <GridViewColumn Width="100" Header="Description" DisplayMemberBinding="{Binding Description}" /> 
       <GridViewColumn Width="70" Header="Duration" DisplayMemberBinding="{Binding Duration}" /> 
       <GridViewColumn Width="70" Header="Elapsed" DisplayMemberBinding="{Binding Elapsed}" /> 
       <GridViewColumn Width="70" Header="Remaining" DisplayMemberBinding="{Binding Remaining}" /> 
      </GridView> 
     </ListView.View> 
    </ListView> 
</Grid> 

Что я пропустил?

ответ

4

Ваше главное, что будет делать CM, поместив привязку Command. Поскольку визуальное дерево понятия не имеет, существует контекстное меню, не говоря уже о том, что цель datacontext.

<ListView.ItemContainerStyle> 
<Style TargetType="{x:Type ListViewItem}"> 
    <Setter Property="Tag" Value="{Binding Path=DataContext, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListView}}"/> 
    <Setter Property="ContextMenu"> 
     <Setter.Value> 
      <ContextMenu cal:Action.TargetWithoutContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Self}}"> 
       <MenuItem Header="Properties" cal:Message.Attach="ShowProperties($dataContext)" > 
       <MenuItem.Icon> 
        <Image Source="../PropertyIcon.png" /> 
       </MenuItem.Icon> 
      </MenuItem> 
      </ContextMenu> 
     </Setter.Value> 
    </Setter> 
</Style> 
</ListView.ItemContainerStyle> 

в то время как я понимаю, что вы пытаетесь сделать с ресурсами в ListView вы стреляете себе в ногу со связыванием командование. Отбросьте ресурс, дайте ItemContainerStyle рулон и посмотрите, работает ли он. Вы всегда можете разбить это на ресурс позже. для тестирования, чтобы увидеть, работает ли он во время внутреннего стиля.

+0

Спасибо, но, к сожалению, до сих пор не находит метод ShowProperties, с или без $ DataContext .. я получаю сообщение, что Тег PlacementTarget не может быть решен в данном контексте типа System.Windows. UIElement, все, что может привести к этому? –

+0

Как ваш проект структурирован? отделенные сборки? Тип контейнера (если есть)? – mvermef

+0

Я ссылался на пакеты Caliburn.Micro и Caliburn.Micro.Platform с использованием NuGet. Я использую обычную структуру Caliburn; Представления и каталоги ViewModels. Полный XML-представление выглядит так, как я опубликовал. Я не уверен, что вы подразумеваете под типами контейнеров. –

0

Используя ответ mvermef, я получил его для работы. Единственное, что нужно было изменить в его коде, это то, что привязка означала «Путешествие по визуальному дереву, поиск первого объекта ContextMenu над этим и привязка к свойству PlacementTarget.Tag». Проблема в том, что привязка относится к самому ContextMenu, поэтому нет родительского объекта ContextMenu. Использование RelativeSource Self исправляет это.

<ListView.ItemContainerStyle> 
      <Style TargetType="{x:Type ListViewItem}"> 
       <Setter Property="Tag" Value="{Binding Path=DataContext, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListView}}"/> 
       <Setter Property="ContextMenu"> 
        <Setter.Value> 
         <ContextMenu cal:Action.TargetWithoutContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Self}}"> 
          <MenuItem Header="Properties" cal:Message.Attach="ShowProperties($dataContext)" > 
           <MenuItem.Icon> 
            <Image Source="../PropertyIcon.png" /> 
           </MenuItem.Icon> 
          </MenuItem> 
         </ContextMenu> 
        </Setter.Value> 
       </Setter> 
      </Style> 
</ListView.ItemContainerStyle> 
Смежные вопросы