我将ProgressBar的可见性绑定到一个属性,如果特定任务正在运行,该属性返回true:
查看:
<ProgressBar IsIndeterminate="True"
Visibility="{Binding TaskRunning, Converter={StaticResource boolToVisibilityConverter}}"/>
视图模型:
private Task someTask;
private CancellationTokenSource cancellationTokenSource;
public bool TaskRunning
{
get
{
return someTask!= null && someTask.Status == TaskStatus.Running;
}
}
private void StartTaskHandler()
{
someTask = Task.Run(new Action(() =>
{
// Simulate some work
cancellationTokenSource.Token.WaitHandle.WaitOne(10000);
}), cancellationTokenSource.Token);
someTask.ContinueWith((task) => RaisePropertyChanged("TaskRunning"));
RaisePropertyChanged("TaskRunning");
}
执行StartTaskHandler
时,ProgressBar有时只会变为可见。这是为什么?如何在任务运行时确保ProgressBar可见?
答案 0 :(得分:1)
我强烈建议您将您的财产#barra{
float: left;
margin-top: 0px;
margin-bottom: 4%;
width: 100%;
}
#logosw img{
position: relative;
float: left;
margin-right: 4%;
width: auto;
height: same as #textsw;
}
#textsw{
float: right;
width: calc(100% - #logosw);
height: 100% of the text;
}
重命名为TaskRunning
,因为最好将IsBusy
个变量命名为前缀bool
。
你应该在你的属性TaskRunning中设置setter来设置is
值:
true
并在您的代码中:
private bool _isBusy;
public bool IsBusy
{
get { return _isBusy; }
set
{
_isBusy = value;
RaisePropertyChanged("IsBusy");
}
}
您可以从任何线程引发private void StartTaskHandler()
{
IsBusy=true;
someTask = Task.Run(new Action(() =>
{
// Simulate some work
cancellationTokenSource.Token.WaitHandle.WaitOne(10000);
}), cancellationTokenSource.Token);
someTask.ContinueWith((task) => IsBusy=false;);
}
,因为WPF会自动将PropertyChanged event
的参数分派给UI线程。
<强>更新强>
您的代码无效,因为您的媒体资源PropertyChanged event
只是可读,而您无法设置TaskRunning
或true
值。要为您的属性设置值,您应该添加setter并在为属性false
设置新值时触发事件PropertyChanged:
TaskRunning
这行代码只使用当前值(不是新值)触发事件:
private bool _taskRunning;
public bool TaskRunning
{
get
{
if(someTask!= null && someTask.Status == TaskStatus.Running)
_taskRunning=true;
return _taskRunning;
}
set
{
_taskRunning=value;
RaisePropertyChanged("TaskRunning");
}
}
但是这一行代码会设置属性someTask.ContinueWith((task) => RaisePropertyChanged("TaskRunning"));
的新值,并触发事件TaskRunning
来更新您的用户界面:
PropertyChanged
答案 1 :(得分:0)
someTask.Status
有时可能仍然是TaskStatus.WaitingToRun
。添加此项将解决此问题。但是使用async / await更好:
private bool isBusy = false;
public bool IsBusy
{
get
{
return isBusy;
}
set
{
isBusy = value;
RaisePropertyChanged("IsBusy");
}
}
private async void StartTaskHandler()
{
cancellationTokenSource = new CancellationTokenSource();
IsBusy = true;
someTask = Task.Run(new Action(() =>
{
// Simulate some work
cancellationTokenSource.Token.WaitHandle.WaitOne(10000);
}), cancellationTokenSource.Token);
await someTask;
IsBusy = false;
}