`ListView.ItemContainerStyle` 中的`ContextMenu` 命令绑定不起作用
`ContextMenu` Command binding inside `ListView.ItemContainerStyle` does not work
我有一个列表视图,我想根据 ListView 列中的某些值隐藏 ContextMenuItems
。我可以通过将 ContextMenu 移动到 ListView.ItemContainerStyle
来实现这一点。现在我的问题是我无法在 MenuItem 上触发命令。这曾经在 ContextMenu
直接设置为 ListView
时有效。
这是我尝试过但失败了的方法。 (使用 ElementType
、ElementName
、直接调用等)。
<UserControl Name="RootElement" DataContext=.Some Context.....>
<ListView ItemsSource="{Binding LicensesView}">
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu>
<MenuItem Header="Refresh 1" Command="{Binding Path=DataContext.LicenseListRefreshCommand, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" />
<MenuItem Header="Refresg 2" Command="{Binding Path=DataContext.LicenseListRefreshCommand, RelativeSource={RelativeSource AncestorType=Window, Mode=FindAncestor}}"/>
<MenuItem Header="Refresh 3" Command="{Binding Path= DataContext.LicenseListRefreshCommand, ElementName=RootElement}" Visibility="{Binding Path=Aktif,Converter= {StaticResource BoolToVisibility}}"/>
<MenuItem Header="Refresh 4" Command="{Binding LicenseListRefreshCommand}"/>
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
<GridView>
<GridViewColumn Header="Code" DisplayMemberBinding="{Binding Code}" Width="Auto"/>
<GridViewColumn Header="Active" DisplayMemberBinding="{Binding Active}" Width="150" />
<GridViewColumn Header="Company" DisplayMemberBinding="{Binding Company}" Width="60" />
<GridViewColumn Header="Demo" DisplayMemberBinding="{Binding Demo}" Width="Auto" />
</GridView>
</ListView.View>
</ListView>
</UserControl>
它不起作用的原因是样式是断开连接的 属性,因此它不尊重可视化树。
我通过使用绑定代理解决了这个问题,如 this answer 所示。
关键是将 DataContext 引用添加为 StaticResource
。
<UserControl Name="RootElement" DataContext=.Some Context.....>
<UserControl.Resources>
<BooleanToVisibilityConverter x:Key="BoolToVisibility" />
<helper:BindingProxy x:Key="Proxy" Data="{Binding}" />
</UserControl.Resources>
<ListView ItemsSource="{Binding LicensesView}">
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu>
<MenuItem Header="Refresh 1" Command="{Binding Path=Data.LicenseListRefreshCommand, Source={StaticResource Proxy}}" />
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
<GridView>
<GridViewColumn Header="Code" DisplayMemberBinding="{Binding Code}" Width="Auto"/>
<GridViewColumn Header="Active" DisplayMemberBinding="{Binding Active}" Width="150" />
<GridViewColumn Header="Company" DisplayMemberBinding="{Binding Company}" Width="60" />
<GridViewColumn Header="Demo" DisplayMemberBinding="{Binding Demo}" Width="Auto" />
</GridView>
</ListView.View>
</ListView>
我有一个列表视图,我想根据 ListView 列中的某些值隐藏 ContextMenuItems
。我可以通过将 ContextMenu 移动到 ListView.ItemContainerStyle
来实现这一点。现在我的问题是我无法在 MenuItem 上触发命令。这曾经在 ContextMenu
直接设置为 ListView
时有效。
这是我尝试过但失败了的方法。 (使用 ElementType
、ElementName
、直接调用等)。
<UserControl Name="RootElement" DataContext=.Some Context.....>
<ListView ItemsSource="{Binding LicensesView}">
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu>
<MenuItem Header="Refresh 1" Command="{Binding Path=DataContext.LicenseListRefreshCommand, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" />
<MenuItem Header="Refresg 2" Command="{Binding Path=DataContext.LicenseListRefreshCommand, RelativeSource={RelativeSource AncestorType=Window, Mode=FindAncestor}}"/>
<MenuItem Header="Refresh 3" Command="{Binding Path= DataContext.LicenseListRefreshCommand, ElementName=RootElement}" Visibility="{Binding Path=Aktif,Converter= {StaticResource BoolToVisibility}}"/>
<MenuItem Header="Refresh 4" Command="{Binding LicenseListRefreshCommand}"/>
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
<GridView>
<GridViewColumn Header="Code" DisplayMemberBinding="{Binding Code}" Width="Auto"/>
<GridViewColumn Header="Active" DisplayMemberBinding="{Binding Active}" Width="150" />
<GridViewColumn Header="Company" DisplayMemberBinding="{Binding Company}" Width="60" />
<GridViewColumn Header="Demo" DisplayMemberBinding="{Binding Demo}" Width="Auto" />
</GridView>
</ListView.View>
</ListView>
</UserControl>
它不起作用的原因是样式是断开连接的 属性,因此它不尊重可视化树。 我通过使用绑定代理解决了这个问题,如 this answer 所示。
关键是将 DataContext 引用添加为 StaticResource
。
<UserControl Name="RootElement" DataContext=.Some Context.....>
<UserControl.Resources>
<BooleanToVisibilityConverter x:Key="BoolToVisibility" />
<helper:BindingProxy x:Key="Proxy" Data="{Binding}" />
</UserControl.Resources>
<ListView ItemsSource="{Binding LicensesView}">
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu>
<MenuItem Header="Refresh 1" Command="{Binding Path=Data.LicenseListRefreshCommand, Source={StaticResource Proxy}}" />
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
<GridView>
<GridViewColumn Header="Code" DisplayMemberBinding="{Binding Code}" Width="Auto"/>
<GridViewColumn Header="Active" DisplayMemberBinding="{Binding Active}" Width="150" />
<GridViewColumn Header="Company" DisplayMemberBinding="{Binding Company}" Width="60" />
<GridViewColumn Header="Demo" DisplayMemberBinding="{Binding Demo}" Width="Auto" />
</GridView>
</ListView.View>
</ListView>