2012-01-16 23 views
1

我試圖將一個上下文菜單項綁定到我在ViewModel中定義的命令。上下文菜單位於一個ListView中,我也綁定到一個CollectionViewSource,我認爲這是問題的原因。將一個命令綁定到一個上下文菜單中的viewModel裏面坐在一個ListView中

我已經設法將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"); 
} 

然後在我看來,我已經設置UPP一個ListView如下:

<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不是eithe的一部分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

非常感謝!這就是訣竅!我所要做的就是綁定到BindingProxy中的ListView的祖先,就像我綁定ListView中的SelectedItem一樣 – Ergodyne 2012-01-16 13:33:54

相關問題