不确定进度条不动画

时间:2017-06-27 12:31:38

标签: c# wpf xaml

以下是实例化具有不确定进度条的窗口的代码,此代码在某个视图的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>

在我的计算机上,进度条没有动画效果。如何解决?

2 个答案:

答案 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