好的,让我试着解释一下。
我有一个可以触发某种扫描过程的应用程序。这个扫描过程启动(只有很多)10个后台工作人员做某事。之后(再次,只是一个数字)5秒我想
ViewModel
的{{1}}命令绑定,并且PerformUpdateCommand
属性为CanExecute
。当我的任务完成时,IsPerformUpdateAllowed
依赖属性被设置。我以为我会这样做:
IsPerformUpdateAllowed
“勾选”我计算数据并将属性DispatcherTimer
设置为true或false时。这基本上可以按预期工作(UI保持响应,......)只需要一个小的hickup:UI没有被更新(按钮未启用)。只要我将窗口置于后台并返回到前台,就会启用该命令,同时IsPerformUpdateAllowed
属性也会设置为true。此外,当我按下按钮(处于禁用状态)后按下它,它将被启用。
因此,虽然我正确设置了依赖项属性,但UI不会对此更改做出反应。
有人知道为什么吗?有趣的是,我还在UI中将一些文本设置为标签 - 此文本已正确更新。只是告诉命令IsPerformUpdateAllowed
的属性不会触发UI更新。
计时器初始化代码。
CanExecute
编码命令如何绑定到WPF元素(该按钮实际上是超链接):
_scanTimer = new DispatcherTimer();
_scanTimer.Interval = new TimeSpan(0, 0, 0, 3);
_scanTimer.Tick += delegate
{
// After the timer has elapsed (some time passed), cancel all scans and update the result
_scanTimer.Stop();
UpdateScanResults();
CancelNormalScans(false);
};
_scanTimer.Start();
以下是Command
的代码 <Label Grid.Row="1" Grid.Column="1">
<Hyperlink Command="{Binding ReadSettingsCommand}">
<TextBlock Text="{Binding Source={StaticResource Loc}, Path=Labels.ReadSettings}"></TextBlock>
</Hyperlink>
</Label>
代码实际上依赖于两个依赖项属性IsScannedDeviceAvailable AND NOT IsUpdateInProgress。两者都是依赖属性。
更新:我刚刚读到与CanExecute属性的绑定只是一次。如果要重新验证,则需要在命令上调用RaiseCanExecuteChanged。这可行,但它有点麻烦,因为现在每次两个属性中的一个更改时我需要手动调用它。实际上我希望自动处理。关于如何更容易地做到这一点的任何想法?是不是有一些方法可以在CanExecute和属性之间进行单向绑定?
答案 0 :(得分:3)
只要设置了IsScannedDeviceAvailable / IsUpdateInProgress,就可以在VM上调用RaiseCanExecuteChanged。或者我个人最喜欢创建自己的ICommand
实现,因为它非常简单。
public class FooCommand : ICommand
{
private bool _canExecute;
private Action _delegate;
public event EventHandler CanExecuteChanged;
public new bool CanExecute
{
get
{
return _canExecute;
}
set
{
_canExecute = value;
if(CanExecuteChanged != null)
CanExecuteChanged();
}
}
public void Execute(object parameter)
{
_delegate();
}
bool ICommand.CanExecute()
{
return CanExecute;
}
public FooCommand(Action action)
{
_delegate = action;
}
}
答案 1 :(得分:0)
如果您根据属性触发Command.CanExecute()
的更改,也可以致电CommandManager.InvalidateRequerySuggested()
强制重新评估CanExecute()
。