Wpf MVVM指示灯-中继命令无法执行问题
我的MVVM灯有问题。我使用版本5.3.0.0 .XAMLWpf MVVM指示灯-中继命令无法执行问题,wpf,mvvm-light,Wpf,Mvvm Light,我的MVVM灯有问题。我使用版本5.3.0.0 .XAML <DockPanel Dock="Top"> <Button Margin="5" VerticalAlignment="Top" HorizontalAlignment="Center" Command="{Binding CancelDownloadCommand}" FontSize="20" Background="Transparent" BorderThic
<DockPanel Dock="Top">
<Button Margin="5" VerticalAlignment="Top" HorizontalAlignment="Center" Command="{Binding CancelDownloadCommand}" FontSize="20"
Background="Transparent" BorderThickness="2" BorderBrush="{StaticResource AccentColorBrush4}" ToolTip="Cancelar"
DockPanel.Dock="Right">
<StackPanel Orientation="Horizontal">
<Image Source="Images/48x48/Error.png" Height="48" Width="48"/>
<Label Content="{Binding ToolTip, RelativeSource={RelativeSource AncestorType={x:Type Button}}}" FontFamily="Segoe UI Light"/>
</StackPanel>
</Button>
<Button Margin="5" VerticalAlignment="Top" HorizontalAlignment="Center" Command="{Binding DownloadCommand}" FontSize="20"
Background="Transparent" BorderThickness="2" BorderBrush="{StaticResource AccentColorBrush4}" ToolTip="Descargar"
DockPanel.Dock="Right">
<StackPanel Orientation="Horizontal">
<Image Source="Images/48x48/Download.png" Height="48" Width="48"/>
<Label Content="{Binding ToolTip, RelativeSource={RelativeSource AncestorType={x:Type Button}}}" FontFamily="Segoe UI Light"/>
</StackPanel>
</Button>
</DockPanel>
通过使用CommandManager.invalidateRequestSuggested(),我修复了它。但请阅读不推荐的地方,因为此命令检查所有RelayCommand。这以前没有发生在我身上
但如果在任务内,请运行,不要添加任何内容。它工作得很好。按钮被再次激活和停用
private async void Download()
{
Reset();
await Task.Run(() =>
{
// WIDTHOUT CODE
// WIDTHOUT CODE
// WIDTHOUT CODE
});
Reset();
}
我注意到的一点是,您的
已启用
属性(IsEnabled,IsEnabledCancel)是私有的
,而它们应该是公共的
。但是,这并不能解决您的问题:)
一个简单的修复方法是去掉命令中的CanExecute
部分
乙二醇
并在按钮上绑定到您的属性。我在xaml中启用了属性
乙二醇
...
希望这有助于当您更新CanExecute
时,在您的情况下IsEnabled
和IsEnabledCancel
属性,您必须引发CanExecuteChanged
事件
更重要的是,您可以稍微简化您的代码
private bool _isEnabled;
public bool IsEnabled
{
get { return _isEnabled; }
set
{
if (Set(ref _isEnabled, value))
{
DownloadCommand.RaiseCanExecuteChanged();
}
}
}
同样的方法更新您的IsEnabledCancel
属性
当然,您必须将命令声明为RelayCommand
,而不是ICommand
private RelayCommand _downloadCommand;
public RelayCommand DownloadCommand
{
get { return _downloadCommand ?? (_downloadCommand = new RelayCommand(Download, () => IsEnabled)); }
}
您还可以阅读:“。查看,它基于CommandManager.invalidateRequestSuggested()
(反)模式。由于(反)模式的全球性,你正确地说这是一个巨大的性能猪
问题在于构造函数<代码>公共RelayCommand(操作执行,函数执行)
由于canExecute
是Func
,因此无法(在运行时)获取属性名,因此无法绑定INotifyPropertyChanged.PropertyChanged
事件。从而导致命令重新评估canExecute
@kubakista向您展示了如何通过调用RaiseCanExecuteChanged
方法强制重新评估。但这确实打破了单一责任原则,泄露了ICommand
的实现
private RelayCommand _downloadCommand;
public RelayCommand DownloadCommand
{
get { return _downloadCommand ?? (_downloadCommand = new RelayCommand(Download, () => IsEnabled)); }
}
我的建议是使用ReactiveUI
的ReactiveCommand
。这允许您执行以下操作:
DownloadCommand = ReactiveCommand.Create(Download, this.WhenAnyValue(x => x.IsEnabled).Select(enabled => enabled));
CancelDownloadCommand = ReactiveCommand.Create(CancelDownload, this.WhenAnyValue(x => x.IsEnabled).Select(enabled => false == enabled));
public bool IsEnabled
{
get {return _isEnabled; }
set
{
_isEnabled = value;
OnPropertyChanged();
}
}
另请参见和中解释的错误
private RelayCommand _downloadCommand;
public RelayCommand DownloadCommand
{
get { return _downloadCommand ?? (_downloadCommand = new RelayCommand(Download, () => IsEnabled)); }
}
DownloadCommand = ReactiveCommand.Create(Download, this.WhenAnyValue(x => x.IsEnabled).Select(enabled => enabled));
CancelDownloadCommand = ReactiveCommand.Create(CancelDownload, this.WhenAnyValue(x => x.IsEnabled).Select(enabled => false == enabled));
public bool IsEnabled
{
get {return _isEnabled; }
set
{
_isEnabled = value;
OnPropertyChanged();
}
}