以下是实例化具有不确定进度条的窗口的代码,此代码在某个视图的viewmdodel中调用:
Views.InstallingWindow installing = new Views.InstallingWindow();
installing.Show();
Application.Current.Dispatcher.Invoke(timeConsumingMethod, DispatcherPriority.Normal);
installing.Close();
这是窗口的xaml
<Window x:Class="Blabla.Views.InstallingWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:PatcherClient.Views"
mc:Ignorable="d"
Title="InstallingWindow" Height="150" Width="300"
WindowStartupLocation="CenterScreen">
<Grid>
<StackPanel Margin="10">
<ProgressBar Width="200" Height="20" Margin="10" Orientation="Horizontal" IsIndeterminate="True" />
<TextBlock HorizontalAlignment="Center" Name="StatusText" Margin="10" Height="50" Foreground="Black" Text="Installing ..."/>
</StackPanel>
</Grid>
在我的计算机上,进度条没有动画效果。如何解决?
答案 0 :(得分:3)
这将在调度程序线程上执行timeConsumingMethod
:
Application.Current.Dispatcher.Invoke(timeConsumingMethod, DispatcherPriority.Normal);
调度员不能同时执行您的方法并同时为ProgressBar
设置动画。
您想在后台主题上执行timeConsumingMethod
。最简单的方法是启动一个新的Task
,然后在任务完成后关闭窗口:
Views.InstallingWindow installing = new Views.InstallingWindow();
installing.Show();
System.Threading.Tasks.Task.Factory.StartNew(() =>
{
timeConsumingMethod();
}).ContinueWith(task =>
{
installing.Close();
}, System.Threading.CancellationToken.None, System.Threading.Tasks.TaskContinuationOptions.None,
System.Threading.Tasks.TaskScheduler.FromCurrentSynchronizationContext());
请注意,要使其生效,您无法访问UIElement
方法中的任何timeConsumingMethod()
。 UIElement
只能在最初创建它的UI线程上访问。
答案 1 :(得分:2)
Dispatcher.Invoke
在UI线程上执行您的timeConsumingMethod
委托,以便它被阻止。
请尝试使用async
方法:
installing.Show();
await Task.Run(() => timeConsumingMethod());
installing.Close();
如果您的timeConsumingMethod
访问任何UI组件(例如设置控件属性),那么您应该仅将这些访问包装到Dispatcher.Invoke
。