我正在尝试将上下文菜单项绑定到我在ViewModel中定义的命令。上下文菜单位于ListView中,我也绑定到CollectionViewSource,我认为这是问题的原因。
我已经设法将listView集合中的选定项目绑定到我的ViewModel,但是当我尝试使用相同的方式将上下文菜单项命令绑定到我的ViewModel时,它不起作用。我希望任何人都有时间阅读下面的所有代码,并让我对我做错了什么有所了解。
聚苯乙烯。我不得不更改一些名称,以免泄露应用程序的内容。
在我的ViewModel中,我定义了以下内容:
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:
<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>
答案 0 :(得分:3)
问题的原因是ContextMenu
不属于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>