带有 AccessText 的 wpf xaml 按钮似乎不查询 CanExecute
wpf xaml button with AccessText seems not to query CanExecute
说明
- 目标: 在我的 wpf 桌面应用程序中,我想将
AccessText
添加到绑定到具有谓词的命令的按钮,该谓词评估 window / 控件正忙,因此 enables/disables 按钮。
- 状态: 按钮命令工作正常并且在添加
AccessText
之前已正确启用。 (我使用 MvvmLight 来支持 ICommand。)
- 问题: 添加
AccessText
后命令仍然绑定,但 CanExecute
似乎不再被查询并且按钮始终启用。 (我理想的解决方案是没有代码隐藏只是 XAML。)
例子
XAML:
工作:
<Button Command="{Binding NavToStoresSearchCmd}" Content="Stores" Height="30"/>
不工作:
<Button Command="{Binding NavToStoresSearchCmd}" Height="30">
<AccessText>S_tores</AccessText>
</Button>
C#(视图模型):
public ICommand NavToStoresSearchCmd { get => new RelayCommand(OnNavToStoresSearch, () => IsNotBusy); }
(IsNotBusy
和 OnNavToStoresSearch
命令的代码工作正常,CanExecute
UNTIL 我添加AccessText
.)
刚刚对此进行了测试,它似乎按预期工作。
我的代码:
XAML:
<Button Command="{Binding BrowseCommand}">
<AccessText>_Browse</AccessText>
</Button>
C#(视图模型):
在构造函数中:
BrowseCommand = new RelayCommand( BrowseCommandHandler, () => CanBrowse );
'CanBrowse' 属性:
private bool _canBrowse;
public bool CanBrowse
{
get { return _canBrowse; }
set { _canBrowse = value; BrowseCommand.RaiseCanExecuteChanged(); }
}
我猜你没有在 RelayCommand 上调用 'RaiseCanExecuteChanged()'?
(编辑:刚看到评论在我点击提交之前进来了。抱歉,伙计们!)
正如评论中所说,这里需要RaiseCanExecuteChanged。 WPF 的 CommandManager 在检测到 UI 更改时调用 CanExecute,例如绑定更新、状态更改等。这是不可靠的。您可能在早期测试 CommandManager 对您的反应时很幸运,但(在我看来)最好在您知道它已更改时显式调用 RaiseCanExecuteChanged。
(进一步编辑)
我快速搜索了一下,看来您可以通过更改命名空间条目来绕过调用 'RaiseCanExecuteChanged' 的需要。改变...
using GalaSoft.MvvmLight.Command;
为
using GalaSoft.MvvmLight.CommandWpf;
我迅速从我的测试应用程序中删除了 'RaiseCanExecuteChanged()' 代码,令人震惊的是它似乎可以正常工作。
也许这些年我一直做错了...
说明
- 目标: 在我的 wpf 桌面应用程序中,我想将
AccessText
添加到绑定到具有谓词的命令的按钮,该谓词评估 window / 控件正忙,因此 enables/disables 按钮。 - 状态: 按钮命令工作正常并且在添加
AccessText
之前已正确启用。 (我使用 MvvmLight 来支持 ICommand。) - 问题: 添加
AccessText
后命令仍然绑定,但CanExecute
似乎不再被查询并且按钮始终启用。 (我理想的解决方案是没有代码隐藏只是 XAML。)
例子
XAML:
工作:
<Button Command="{Binding NavToStoresSearchCmd}" Content="Stores" Height="30"/>
不工作:
<Button Command="{Binding NavToStoresSearchCmd}" Height="30">
<AccessText>S_tores</AccessText>
</Button>
C#(视图模型):
public ICommand NavToStoresSearchCmd { get => new RelayCommand(OnNavToStoresSearch, () => IsNotBusy); }
(IsNotBusy
和 OnNavToStoresSearch
命令的代码工作正常,CanExecute
UNTIL 我添加AccessText
.)
刚刚对此进行了测试,它似乎按预期工作。 我的代码:
XAML:
<Button Command="{Binding BrowseCommand}">
<AccessText>_Browse</AccessText>
</Button>
C#(视图模型):
在构造函数中:
BrowseCommand = new RelayCommand( BrowseCommandHandler, () => CanBrowse );
'CanBrowse' 属性:
private bool _canBrowse;
public bool CanBrowse
{
get { return _canBrowse; }
set { _canBrowse = value; BrowseCommand.RaiseCanExecuteChanged(); }
}
我猜你没有在 RelayCommand 上调用 'RaiseCanExecuteChanged()'?
(编辑:刚看到评论在我点击提交之前进来了。抱歉,伙计们!)
正如评论中所说,这里需要RaiseCanExecuteChanged。 WPF 的 CommandManager 在检测到 UI 更改时调用 CanExecute,例如绑定更新、状态更改等。这是不可靠的。您可能在早期测试 CommandManager 对您的反应时很幸运,但(在我看来)最好在您知道它已更改时显式调用 RaiseCanExecuteChanged。
(进一步编辑) 我快速搜索了一下,看来您可以通过更改命名空间条目来绕过调用 'RaiseCanExecuteChanged' 的需要。改变...
using GalaSoft.MvvmLight.Command;
为
using GalaSoft.MvvmLight.CommandWpf;
我迅速从我的测试应用程序中删除了 'RaiseCanExecuteChanged()' 代码,令人震惊的是它似乎可以正常工作。 也许这些年我一直做错了...