在WPF应用程序中,我的ContextMenu有一个小但烦人的问题 我使用DataTemplate作为我的ViewModel对象列表来创建可视元素。在DataTemplate中,我只需将UserControl设置为:
<!-- Define a data-template for the 'RoomViewModel' class. This generates the UI for each node. -->
<DataTemplate DataType="{x:Type model:RoomViewModel}">
<network:RoomView network:ConstraintView.ArgumentChanged="ConstraintView_ArgumentChanged"></network:RoomView>
</DataTemplate>
我希望RoomView有一个ContextMenu,如果用户点击MenuItem,应该执行RelayCommand。我对RoomView的UserControl现在看起来像这样:
<UserControl x:Name="userControl" x:Class="NetworkUI.RoomView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:network="clr-namespace:NetworkUI"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300" DataContextChanged="userControl_DataContextChanged">
<UserControl.Resources>
<!-- UI commands -->
<RoutedCommand x:Key="Commands.NewConstraintCmd"></RoutedCommand>
</UserControl.Resources>
<UserControl.CommandBindings>
<CommandBinding x:Name="newConst" Command="{StaticResource Commands.NewConstraintCmd}" Executed="NewConstraint_Executed"></CommandBinding>
</UserControl.CommandBindings>
<Grid Width="Auto" Height="Auto" MinWidth="50" >
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Grid Grid.Row="0" Width="Auto" Height="20" MinWidth="50" >
<Rectangle Stroke="Black" Fill="White" RadiusX="4" RadiusY="4" SnapsToDevicePixels="True" ></Rectangle>
<Grid Margin="-4" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" MinWidth="10" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<network:EditableTextBlock Grid.Column="1" Grid.Row="1" x:Name="nameTextBox" Text="{Binding Name, Mode=TwoWay}" HorizontalAlignment="Center" VerticalAlignment="Center" BorderBrush="{x:Null}" />
<network:ConnectorItem Grid.Row="1" Grid.Column="0" DataContext="{Binding Connectors[0]}" />
<network:ConnectorItem Grid.Row="1" Grid.Column="2" DataContext="{Binding Connectors[1]}" />
</Grid>
</Grid>
<StackPanel Grid.Row="1" x:Name="roomProperties" Width="Auto" HorizontalAlignment="Stretch" >
<ItemsControl ItemsSource="{Binding PropertyGroups}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<network:ConstraintCollectionView></network:ConstraintCollectionView>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</Grid>
<UserControl.ContextMenu>
<ContextMenu x:Name="contextMenu">
<MenuItem Header="new Constraint" Command="{StaticResource Commands.NewConstraintCmd}"></MenuItem>
</ContextMenu>
</UserControl.ContextMenu>
</UserControl>
我不确定我的UserControl代码是否正常。在我的CodeBehind文件中,我定义了一个
public ICommand NewConstraintCmd;
- 当用户单击Item时应执行的命令。我的Executed处理程序很简单,如下所示:
private void NewConstraint_Executed(object sender, ExecutedRoutedEventArgs e) {
ViewModel.AddConstraint();
}
ViewModel确实是一个RoomViewModel,而NewConstraintCmd是在DataContextChanged - 事件中设置的(此处不显示)。
我的简单问题是,为什么我的ContextMenu-Item始终被禁用?我的意思是从不检查RelayCommand.CanExecute,这可能是问题吗?
我还没有找到解决问题的方法。
谢谢你的帮助!
答案 0 :(得分:-1)
谢谢Rohit Vats!我将ICommand定义更改为:
public static readonly ICommand NewConstraint = new RelayCommand((rvm) => AddConstraint(rvm));
由于这是一个静态方法,我需要参数(我的RoomView的DataContext) 我的方法现在定义如下:
private static void AddConstraint(object rvm) {
if (rvm is RoomViewModel)
(rvm as RoomViewModel).AddConstraint();
}
首先检查参数,如果确定(RoomViewModel对象),我调用对象的实际函数。
我不知道为什么它现在有效,真的:/。
我对MenuItem的XAML代码现在看起来像这样:
<MenuItem Header="new Constraint" Command="network:RoomView.NewConstraint" CommandParameter="{Binding}"></MenuItem>
如前所述,我需要CommandParameter来调用它上面的函数。由于所需的Object是我的DataContext,我只需使用{Binding}来传递对象。
现在这真的很好用,我希望将来也可以使用InputBindings :)! 再次感谢您的帮助!