CanExecute true 如果选择了列表框中的项目

CanExecute true iff an item in a listBox is selected

我对 WPF 比较陌生,所以这可能是微不足道的,但我想不通。 假设我有一个 ListBox 和一个 Button。该按钮绑定到一个命令,该命令对列表的 selected 项目执行某些操作。

示例:

<ListBox Name="List" ItemsSource="{Binding Items}" />
<Button Content="Show!" Command="{Binding ShowCommand}" CommandParameter="{Binding ElementName=List, Path=SelectedItem}"/>

我希望当且仅当没有项目被 selected 时禁用该按钮,我理想情况下希望通过 ShowCommand.CanExecute 函数来实现。 我尝试检查 null 参数并且它工作 如果一开始只检查一次。如果我 select 一个项目按钮仍然是禁用的。

我尝试了这里的建议:WPF CommandParameter binding not updating 但它根本不起作用......(同样的问题)我做错了什么吗?

当我 select 列表中的项目时,如何让他回忆起 canExecute? .

您可以使用 DataTrigger

轻松实现
<ListBox Name="List" ItemsSource="{Binding Items}" />
<Button Content="Show!" Command="{Binding ShowCommand}" CommandParameter="{Binding ElementName=List, Path=SelectedItem}">
        <Button.Style>
            <Style TargetType="Button">
                <Setter Property="IsEnabled" Value="True" />
                <Style.Triggers>
                    <DataTrigger Binding="{Binding SelectedItem,ElementName=List}" Value="{x:Null}">
                        <Setter Property="IsEnabled" Value="False"></Setter>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Button.Style>
</Button>

更新

你无法使用 CanExecute 实现的原因很可能是因为没有引发 CanExecuteChanged 事件,要解决这个问题,你可以利用 CommandManager.RequerySuggested将此事件链接到您命令的 CanExecuteChanged 事件[1]

此处是 ICommand 的基本实现和使用,适用于您的情况:

public class Command : ICommand
{
    private readonly Action<object> _action;
    public Command(Action<object> action)
    {
        _action = action;
    }
    public bool CanExecute(object parameter)
    {
        //the selected item of the ListBox is passed as parameter
        return parameter != null;
    }
    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    public void Execute(object parameter)
    {
        //the selected item of the ListBox is passed as parameter
        _action(parameter);
    }
}

您的 VM 中定义的命令应如下所示:

 private ICommand _showCommand;
    public ICommand ShowCommand => _showCommand ?? (_showCommand = new Command(ButtonClickAction));

    public void ButtonClickAction(object parameter)
    {
       //Your action
    }

您可能还想看看 Routed Commands 以避免自己引发 CanExecuteChanged 事件。

您可以通过几种解决方案实现它: 1) 将 ListBox 的 SelecteItem 绑定到视图模型中的某些 属性,并在 属性 setter 上调用 ShowCommand.RaiseCanExecuteChanged()。 2)使用一些将空值转换为布尔值的转换器将按钮的 IsEnabled 绑定到 ListBox 的 SelecteItem。