2012-01-16 13 views
1

私はViewModelで定義したコマンドにコンテキストメニュー項目をバインドしようとしています。コンテキストメニューは、私もCollectionViewSourceにバインドしているListView内に座って、これは私が問題の原因だと思う。リストビュー内にあるコンテキストメニュー内のviewModelへのコマンドのバインド

listViewコレクションの選択したアイテムを自分のViewModelにバインドすることができましたが、同じ方法でコンテキストメニュー項目のコマンドをViewModelにバインドしようとしても機能しません。私は誰もが以下のすべてのコードを読んで、私が間違っていることについて私にいくつかのアイデアを与える時間を持っていることを願っています。

ps。私は、アプリケーションが何であるかを知らせないために、いくつかの名前を変更しなければなりませんでした。私のViewModelで

私はfollowningが定義されている次のように

public ObservableCollection<ListItemViewModel> ListViewItemViewModels {get; set;} 

public MyListItem SelectedListItemViewModel {get; set;} 

private RelayCommand _runCommand; 
public ICommand RunCommand { 
    get { 
    return _runCommand ?? 
     (_runCommand = new RelayCommand(param => RunReport(), param => CanRunReport)); 
    } 
} 

private void RunReport() { 
    Logger.Debug("Run report"); 
} 

はその後、私のビューでは、私はListViewコントロールUPP設定されている次のように

<ListView DataContext="{StaticResource ListGroups}" 
    ItemsSource="{Binding}" 
    ItemContainerStyle="{StaticResource ListItemStyle}" 
    IsSynchronizedWithCurrentItem="True" 
    SelectedItem="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Grid},AncestorLevel=1 }, Path=DataContext.SelectedListItem, UpdateSourceTrigger=PropertyChanged}" 
    Margin="10,10,0,10"> 
    <ListView.GroupStyle> 
     <StaticResourceExtension ResourceKey="AccountGroupStyle"/> 
    </ListView.GroupStyle> 
    <ListView.View> 
     <GridView> 
      <GridViewColumn Header="Title" DisplayMemberBinding="{Binding Path=DisplayTitle}"/> 
      <GridViewColumn Header="Date" DisplayMemberBinding="{Binding Path=DateString}"/> 
     </GridView> 
    </ListView.View> 
    <ListView.ContextMenu> 
     <ContextMenu Name="ListViewContextMenu"> 
      <MenuItem Header="Run" Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Grid},AncestorLevel=1 }, Path=DataContext.RunCommand}"/> 
     </ContextMenu> 
    </ListView.ContextMenu> 


</ListView> 

がCollectionViewSourceが定義されている:

<DataTemplate x:Key="ListViewListTemplate" DataType="{x:Type ViewModels:ListItemViewModel}"> 
    <StackPanel Orientation="Vertical"> 
     <TextBlock Text="{Binding Path=DisplayTitle}" Margin="8,0,0,0"/> 
    </StackPanel> 
</DataTemplate> 

<CollectionViewSource Source="{Binding Path=ListItemViewModels}" x:Key="ListItemGroups"> 
    <CollectionViewSource.GroupDescriptions> 
     <PropertyGroupDescription PropertyName="ListItemGroupName"/> 
    </CollectionViewSource.GroupDescriptions> 
    <CollectionViewSource.SortDescriptions> 
     <ComponentModel:SortDescription PropertyName="Index" Direction="Ascending"/> 
     <ComponentModel:SortDescription PropertyName="DisplayTitle" Direction="Ascending"/> 
    </CollectionViewSource.SortDescriptions> 
</CollectionViewSource> 

<GroupStyle x:Key="ListItemGroupStyle"> 
    <GroupStyle.HeaderTemplate> 
     <DataTemplate> 
      <!-- The text binding here is refered to the property name set above in the propertyGroupDescrition --> 
      <TextBlock x:Name="text" Background="{StaticResource DateGroup_Background}" FontWeight="Bold" Text="{Binding Path=Name}" 
         Foreground="White" 
        Margin="1" 
        Padding="4,2,0,2"/> 

     </DataTemplate> 
    </GroupStyle.HeaderTemplate> 
</GroupStyle> 

<Style x:Key="ListItemStyle" TargetType="{x:Type ListViewItem}"> 

    <Setter Property="HorizontalContentAlignment" Value="Stretch"/> 

    <!-- 
    Bind the IsSelected property of a ListViewItem to the 
    IsSelected property of a ReconciliationTaskViewModel object. 
    --> 
    <Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=TwoWay}" /> 
    <Style.Triggers> 
     <MultiTrigger> 
      <MultiTrigger.Conditions> 
       <Condition Property="ItemsControl.AlternationIndex" Value="1" /> 
       <Condition Property="IsSelected" Value="False" /> 
       <Condition Property="IsMouseOver" Value="False" /> 
      </MultiTrigger.Conditions> 
      <Setter Property="Background" Value="#EEEEEEEE" /> 
     </MultiTrigger> 
    </Style.Triggers> 
</Style> 

答えて

3

問題の原因は、ContextMenuが電子メールの一部ではないということですr ListViewの論理ツリーまたは視覚ツリーなので、RelativeSource/FindAncestorは機能せず、DataContextは継承されません。

私は次のようにあなたがそれを使用することができ、数ヶ月前にこの問題へa solution投稿:

<ListView ...> 
    <ListView.Resources> 
     <local:BindingProxy x:Key="proxy" Data="{Binding}" /> 
    </ListView.Resources> 

    ... 

    <ListView.ContextMenu> 
     <ContextMenu Name="ListViewContextMenu"> 
      <MenuItem Header="Run" Command="{Binding Source={StaticResource proxy}, Path=Data.RunCommand}"/> 
     </ContextMenu> 
    </ListView.ContextMenu> 


    ... 

</ListView> 
+0

おかげでたくさん!それはトリックでした!私がやらなければならなかったのは、ListViewのSelectedItemをバインドするときと同じように、BindingProxyのListViewの祖先にバインドすることだけでした – Ergodyne