我有一个搜索对话框,我想在搜索过程中禁用搜索按钮。这是当前代码,但按钮未取消激活
查看:
<Button Content="Search"
Command="{Binding StartSearchCommand}"
IsEnabled="{Binding IsNotSearching}" />
视图模型:
private bool _isNotSearching;
public bool IsNotSearching
{
get { return _isNotSearching; }
set
{
_isNotSearching = value;
OnPropertyChanged("IsNotSearching");
}
}
private RelayCommand<object> _startSearchCommand;
public ICommand StartSearchCommand
{
get
{
if (_startSearchCommand == null)
_startSearchCommand = new RelayCommand<object>(p => ExecuteSearch());
return _startSearchCommand;
}
}
private void ExecuteSearch()
{
IsNotSearching = false;
//do some searching here
IsNotSearching = true;
}
答案 0 :(得分:7)
我因为这个原因(基于着名的DelegateCommand
)创建了AsyncDelegateCommand
,它在执行命令操作期间在内部禁用命令(在UI中):
public class AsyncDelegateCommand : ICommand
{
readonly Action<object> _execute;
readonly Predicate<object> _canExecute;
bool _running;
public event EventHandler CanExecuteChanged;
public AsyncDelegateCommand(Action<object> execute, Predicate<object> canExecute = null)
{
_execute = execute;
_canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
return (_canExecute == null ? true : _canExecute(parameter)) && !_running;
}
public async void Execute(object parameter)
{
_running = true;
Update();
await Task.Run(() => _execute(parameter));
_running = false;
Update();
}
public void Update()
{
if (CanExecuteChanged != null)
CanExecuteChanged(this, EventArgs.Empty);
}
}
XAML:
<Button Command="{Binding SomeCommand}" .../>
视图模型:
AsyncDelegateCommand SomeCommand { get; }
// in constructor
SomeCommand = new AsyncDelegateCommand(o => { Thread.Sleep(5000); }); // code to run
答案 1 :(得分:0)
我不确定点击和禁用时的外观 - 它可能看起来相同。
但是netaholic是正确的。如果在主UI线程中执行逻辑,则UI可能会冻结,直到执行结束(并且不会更改或更改为快速)。
尝试将您的逻辑放在dispatcher中。就像代码的下一部分一样。
Application.Current.Dispatcher.BeginInvoke(
DispatcherPriority.Background,
new Action(() => {
//do some searching here
}));
BTW,我接受了这段代码there。
编辑:请勿将此用于您的解决方案。这是错误的(检查评论)。
需要更新可视元素异步时使用调度程序。
Application.Current.Dispatcher.BeginInvoke(
DispatcherPriority.Background,
new Action(() => {
textbox.Content = "some result";
}));
答案 2 :(得分:0)
你可以试试命令可以执行以禁用命令而不添加IsEnabled
属性
private RelayCommand _startSearchCommand;
public RelayCommand StartSearchCommand
{
get
{
return _startSearchCommand??
(_startSearchCommand=
//Added can execute command , only execute if system is not busy at the moment.
new RelayCommand(async () => await OnExecuteSearch(), () => !IsBusy));
}
}
命令处理程序
internal async Task OnExecuteSearch()
{
IsBusy = true;
//Execute your action
//and finally
IsBusy = false;
}
的Xaml
<Button Command="{Binding StartSearchCommand}">
中继命令中的canexecute
将为您控制IsEnabled
属性。
答案 3 :(得分:0)
此代码必须有效。
private async void ExecuteSearch() {
IsNotSearching = false;
var task = Task.Factory.StartNew(() => {
//do some searching here
});
await task;
IsNotSearching = true;
}