ContextMenu CanExecute未更新

时间:2015-10-27 08:55:50

标签: c# wpf contextmenu mvvm-light icommand

我对ContextMenu中的菜单项状态有疑问。我有一个ObversableCollection of Cars。汽车在ListBox中可视化,对于我想要ContextMenu的每个ListBox项。在ContextMenu中有一个选项ReserveCar。

他们遇到的问题是CanExecute Car仅在我点击任意一辆车时执行一次。当我右键点击其他CanExecute时,他们Car将不再被调用。

这导致当我右键单击可以保留的Car时,MenuItem处于活动状态,但是当我右键单击另一个我无法保留的MenuItem时有效(因为CanExecute未再次调用)。

<ListBox
    ItemsSource="{Binding Cars}"
    SelectedItem="{Binding SelectedCar}">
    <ListBox.ContextMenu>
        <ContextMenu>
            <MenuItem Header="Reserve Car" 
                        CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=ContextMenu}, Path=PlacementTarget.SelectedItem}"
                        Command="{Binding ReserveCarCommand}">
                <MenuItem.Icon>
                    <Image Source="{StaticResource ReserveCarIcon}" Width="24" Height="24"/>
                </MenuItem.Icon>
            </MenuItem>
        </ContextMenu>
    </ListBox.ContextMenu>
</ListBox>

我的ViewModel:

private RelayCommand<Car> _reserveCarCommand;
public ICommand ReserveCarCommand
{
    get { return _reserveCarCommand ?? (_reserveCarCommand = new RelayCommanReserveCar, CanReserveCar)); }
}

public bool CanReserveCar(Car car)
{
    return !car.IsReserved && ReservationsAreOpen;
}

public void ReserveCar(Car car)
{
    car.IsReserved = true;
}

此外,当我在执行某些操作时手动刷新命令时,CanExecute会以null作为参数进行调用,因此也无法正常工作。

if (_reserveCarCommand != null) _reserveCarCommand .RaiseCanExecuteChanged();

1 个答案:

答案 0 :(得分:1)

尝试绑定ListBoxItem上的上下文菜单,而不是ListBox。由于ListBox的上下文菜单的绑定仅在第一次右键单击时发生,因此CanExectute在第一次右键单击后不会触发。

<ListBox Name="simpleListBox"
         ItemsSource="{Binding Cars}"
        SelectedItem="{Binding SelectedCar}">
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="ContextMenu">
                <Setter.Value>
                    <ContextMenu>
                        ...
                    </ContextMenu>
                </Setter.Value>
            </Setter>
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>