RelayCommand CanExecute 行为不起作用
我无法使用 RelayCommand
正确启用/禁用附加控件。
我有一个附加到按钮的 EventToCommand
元素。该命令通过数据绑定到 ViewModel。最初,该按钮被禁用(预期行为),但我似乎无法让 CanExecute
逻辑来检查它的值。当 CurrentConfigFile
设置并存在时,应启用该按钮。我已执行代码并在调试中检查文件的值以确保其已设置,但控件仍处于禁用状态。我已尝试 CommandManager.InvalidateRequerySuggested()
和 command.RaiseCanExecuteChanged()
,但它无法启用。
我想知道 lambda 是否无法正确用于 CanExecute
行为(即使示例使用它们),或者 CanExecute
行为需要将数据绑定到另一个元素。
这是我的代码:
// The FileInfo being checked for existence before the button should be enabled
public const string CurrentConfigFilePN = "CurrentConfigFile";
public FileInfo CurrentConfigFile
{
get
{
return _currentConfigFile;
}
set
{
if (_currentConfigFile == value)
{
return;
}
var oldValue = _currentConfigFile;
_currentConfigFile = value;
// Update bindings, no broadcast
RaisePropertyChanged(CurrentConfigFilePN);
}
}
public MainViewModel()
{
// snip //
SaveCommand = new RelayCommand(SaveConfiguration,
() => CurrentConfigFile != null && CurrentConfigFile.Exists);
}
private void SaveConfiguration()
{
// export model information to xml document
ExportXMLConfiguration(CurrentConfigFile);
}
和标记
<Button x:Name="SaveButton" Content="Save" Width="75" Margin="20,5">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<GalaSoft:EventToCommand x:Name="SaveETC"
Command="{Binding SaveCommand}"
MustToggleIsEnabledValue="true" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
更新:
根据 Isak Savo 的建议,我将 RelayCommand
直接绑定到按钮
<Button x:Name="SaveButton" Content="Save" Width="75" Margin="20,5"
Command="{Binding SaveCommand}"/>
,当 FileInfo 时,它开始禁用并正确启用已设置。我想我应该记住不要修理没有损坏的东西!
I'm having trouble getting the RelayCommand
to enable/disable the attached control properly.
I've got an EventToCommand
element attached to a button. The command is databound to the ViewModel. Initially, the button is disabled (expected behavior), but I cannot seem to get the CanExecute
logic to check it's value. When CurrentConfigFile
is set and exists, the button should be enabled. I've executed code and checked the file's value in debug to make sure it's set, but the control is still disabled. I've tried CommandManager.InvalidateRequerySuggested()
and command.RaiseCanExecuteChanged()
, but it will not enable.
I've wondered if lambdas don't work correctly for the CanExecute
behavior (even though the examples use them) or that the CanExecute
behavior needs to be databound to another element.
Here's my code:
// The FileInfo being checked for existence before the button should be enabled
public const string CurrentConfigFilePN = "CurrentConfigFile";
public FileInfo CurrentConfigFile
{
get
{
return _currentConfigFile;
}
set
{
if (_currentConfigFile == value)
{
return;
}
var oldValue = _currentConfigFile;
_currentConfigFile = value;
// Update bindings, no broadcast
RaisePropertyChanged(CurrentConfigFilePN);
}
}
public MainViewModel()
{
// snip //
SaveCommand = new RelayCommand(SaveConfiguration,
() => CurrentConfigFile != null && CurrentConfigFile.Exists);
}
private void SaveConfiguration()
{
// export model information to xml document
ExportXMLConfiguration(CurrentConfigFile);
}
and markup
<Button x:Name="SaveButton" Content="Save" Width="75" Margin="20,5">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<GalaSoft:EventToCommand x:Name="SaveETC"
Command="{Binding SaveCommand}"
MustToggleIsEnabledValue="true" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
Update:
As per Isak Savo's suggestion, I bound the RelayCommand
directly to the button with
<Button x:Name="SaveButton" Content="Save" Width="75" Margin="20,5"
Command="{Binding SaveCommand}"/>
and it started disabled and correctly enabled when the FileInfo
was set. Guess I should remember not to fix what isn't broken!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
为什么不直接从按钮绑定到命令?
也许您正在使用的 EventToCommand 东西将命令的 CanExecute 通知搞乱了。
关于 CanExecute 问题 - 您确定在设置 CurrentConfigFile 属性后调用 CanExecute 处理程序吗?我发现,尽管 WPF 在重新查询 CanExecute 方面做得很好,但有时我仍然需要通过 CommandManager。编辑
:正如评论中指出的,OP已经尝试过命令管理器方法。
Why don't you just bind to the Command directly from the Button?
Maybe the EventToCommand thing you are using is messing things up with the command's CanExecute notification.
And regarding the CanExecute problem - are you sure that your CanExecute handler is called after the CurrentConfigFile property is set? I've found that even though WPF mostly does a good job of requerying CanExecute, I still sometimes need to force a requery through the CommandManager.
EDIT: As pointed out in the comments, the OP has already tried the command manager approach.
在 msdn 中写道:
第一次调用时,FileInfo 会调用 Refresh 并缓存有关文件的信息。在后续调用中,您必须调用 Refresh 来获取最新的信息副本。
但是,我不会在 CanExecute 处理程序中执行此类检查。这可能会减慢你的 UI,因为 CanExecute 被调用很多次,我可以想象这样的 IO 检查会变得很慢,例如,如果文件位于网络共享上。
In msdn is written:
When first called, FileInfo calls Refresh and caches information about the file. On subsequent calls, you must call Refresh to get the latest copy of the information.
However, I would not do such a check in the CanExecute-handler. This may slow down your UI because CanExecute is called a lot of times and I could imagine that such IO-checks can become slow, for example if the file lies on a network share.