WPF XAML按钮的AccessText似乎无法查询CanExecute。

4

解释

  • 目标:在我的wpf桌面应用程序中,我想向一个绑定到命令的按钮添加AccessText,该命令具有谓词,该谓词评估窗口/控件是否繁忙,从而启用/禁用按钮。
  • 状态:按钮命令运行良好,并且在添加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也正常工作直到我添加AccessText。)


我没有看到你调用 RaiseCanExecuteChanged 的地方。 - Андрей NOP
相信RaiseCanExecuteChanged是MvvmLight的一部分。此外,在添加AccessText之前我的代码可以正常工作,这让我觉得它被正确调用了。 - David Savage
如果没有AccessText,命令是否会真正执行?例如,在OnNavStoresSearch中设置断点并单击按钮,是否会被触发?在getter中创建一个“new RelayCommand”对我来说有点奇怪,通常我期望在构造函数中创建一个实例,然后使用它(并且应该像上面说的一样调用RaiseCanExecuteChanged)。 - MaSiMan
问题无法重现。虽然按钮上的文字是黑色的,但是该按钮不可用且命令未被执行。 - Андрей NOP
1个回答

2

经过测试,这似乎按预期工作了。

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上调用'ReaiseCanExecuteChanged()'吗?
(编辑:刚看到评论提出的问题。对不起各位!)
如评论中所述,需要使用'ReaiseCanExecuteChanged'。当WPF的CommandManager检测到UI更改时会调用CanExecute,例如绑定更新、状态更改等。这种做法是不可靠的。你之前在测试中可能运气好,但(在我看来)最好在知道更改后显式地调用RaiseCanExecuteChanged。
(进一步编辑) 我快速搜索了一下,发现你可以通过更改命名空间条目来避免需要调用“RaiseCanExecuteChanged”。将...更改为...
using GalaSoft.MvvmLight.Command;

for

using GalaSoft.MvvmLight.CommandWpf;

我迅速将“RaiseCanExecuteChanged()”代码从我的测试应用程序中删除,令人震惊的是它似乎起作用了。 也许这些年来我一直做错了...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接