WPF中通过MenuItem点击启用/禁用指定TextBox的命令配置问题
核心问题分析
你当前直接写Command="Enable = True"的写法是错误的,而且ContextMenu不在WPF可视化树中,直接通过RelativeSource绑定DataGrid的DataContext会失败——因为ContextMenu的逻辑树和DataGrid的可视化树相互独立,无法直接遍历找到DataGrid。
解决方案步骤
1. 调整TextBox的IsEnabled绑定(MVVM规范方式)
先给ViewModel添加布尔类型属性IsObjektkennzeichenEnabled,然后将TextBox的IsEnabled绑定到该属性:
<TextBox x:Name="Objektkennzeichen" Grid.Column="0" Text="{WPF:ValidatedBinding Value, StringFormat=N}" BorderThickness="1" IsEnabled="{Binding DataContext.IsObjektkennzeichenEnabled, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
2. 配置MenuItem的Command绑定
通过ContextMenu的PlacementTarget(即触发菜单的按钮)获取DataContext,因为按钮属于DataGrid的可视化树,能正确关联到ViewModel。同时给命令传递控制参数(True/False):
<Button.ContextMenu> <ContextMenu Name="cm" StaysOpen="true"> <MenuItem Header="Feld freischalten" Command="{Binding PlacementTarget.DataContext.PsCmd[SetObjektKennzeichenEnabled], RelativeSource={RelativeSource AncestorType=ContextMenu}}" CommandParameter="True"/> <MenuItem Header="Feld sperren" Command="{Binding PlacementTarget.DataContext.PsCmd[SetObjektKennzeichenEnabled], RelativeSource={RelativeSource AncestorType=ContextMenu}}" CommandParameter="False"/> </ContextMenu> </Button.ContextMenu>
3. 实现ViewModel中的命令逻辑
确保PsCmd字典里的SetObjektKennzeichenEnabled命令能接收布尔参数,并更新对应的属性:
// 示例:基于RelayCommand(或其他ICommand实现)的逻辑 PsCmd["SetObjektKennzeichenEnabled"] = new RelayCommand<bool>(isEnabled => { IsObjektkennzeichenEnabled = isEnabled; // 触发属性变更通知(需ViewModel实现INotifyPropertyChanged) OnPropertyChanged(nameof(IsObjektkennzeichenEnabled)); });
之前绑定失败的原因
你尝试的Command="{Binding DataContext.PsCmd[CallPowershellFunction], RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"无法生效,是因为ContextMenu不属于DataGrid的可视化树,RelativeSource无法遍历到DataGrid。通过PlacementTarget获取按钮的DataContext,才能正确关联到ViewModel。
备选方案(无需修改ViewModel)
如果不想改动ViewModel,可以使用EventTrigger结合InvokeCommandAction:
<!-- 需先添加命名空间:xmlns:i="http://schemas.microsoft.com/xaml/behaviors" --> <MenuItem Header="Feld freischalten"> <i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <i:InvokeCommandAction Command="{Binding PlacementTarget.DataContext.PsCmd[SetObjektKennzeichenEnabled], RelativeSource={RelativeSource AncestorType=ContextMenu}}" CommandParameter="True"/> </i:EventTrigger> </i:Interaction.Triggers> </MenuItem>
内容的提问来源于stack exchange,提问作者devopsg-h

