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。
我对 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。