BusyIndi​​cator控件WPF在后台线程 [英] WPF BusyIndicator on a background thread

查看:129
本文介绍了BusyIndi​​cator控件WPF在后台线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用WPF工具包忙指示符而后台操作发生在我的UI之上提供了一个覆盖。有一个在它被设置为不确定的,而我的后台任务是怎么回事这是很好的控制进度条。当后台任务完成后,用户界面需要更新这可能需要1-2秒。当然,这将导致进度条冻结,看起来很丑。



我的问题是,我怎么能旋转起来繁忙指示器在后台线程,这样的进度条进行在多达移动所有的方式,直到UI变得反应?我很开放给其他的解决方案,以及只要进度条不冻结



下面是一些示例代码:



<预类=郎咸平的XML prettyprint-覆盖> < xctk:BusyIndi​​cator控件IsBusy ={结合IsBusy}风格={StaticResource的BusyIndi​​catorStyle}>
< DockPanel中保证金=3>
< TextBlock的DockPanel.Dock =评出的风格={StaticResource的WorkspaceHeaderStyle}文本=用户管理/>
<网格和GT;
< Grid.RowDefinitions>
< RowDefinition高度=自动/>
< RowDefinition高度=*/>
< /Grid.RowDefinitions>
将;工具条Grid.Row =0>
<按钮内容=保存更改命令={结合SaveChangesCommand}/>
< /工具栏>
将;的TabControl Grid.Row =1>
< TabItem的标题=用户的DataContext ={结合UsersViewModel}>
<用户:UsersView />
< / TabItem的>
< TabItem的标题=角色的DataContext ={结合RolesViewModel}>
<角色:RolesView />
< / TabItem的>
< / TabControl的>
< /网格和GT;
< / DockPanel中>
< / xctk:BusyIndi​​cator控件>



<预类=郎-CS prettyprint-覆盖> 私人无效LoadDays()
{
ProgressIsBusy = TRUE;

VAR uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();

VAR loadDaysTask = GetLoadDaysTask(uiScheduler);

loadDaysTask.ContinueWith(前因=>
{
RaisePropertyChanged(()=> ForecastViewModel);
RaisePropertyChanged(()=> AverageHandleTimeViewModel);
RaisePropertyChanged(()=> GeneralOptionsViewModel);
RaisePropertyChanged(()=> ScheduledHoursViewModel);

IsUserEditing = TRUE;
ProgressIsBusy = FALSE;

},TaskScheduler.FromCurrentSynchronizationContext());

loadDaysTask.Start();
}


解决方案

我不相信你可以做到这一点。你不能从后台线程访问UI控件。此外,您可能会发现,它是UI线程繁忙渲染或通知,使进度条冻结。



我有一个大规模的WPF应用程序类似的设置而且从同样的问题困扰。繁忙指示器显示细腻,同时数据从数据库中获取的,但随后当应用程序开始呈现在UI中的数据,繁忙指示冻结。



我甚至使用GIF动画来解决这个问题的尝试,但他们当然不WPF应用程序动画(自己)。已经编写的代码,以动画GIF中的框架,我感到非常失望地发现,它也同样的问题受到影响。



好运气都一样。


I'm using the wpf toolkit busy indicator which provides an overlay on top of my UI while a background operation is taking place. There's a progress bar in the control which is set to indeterminate which is fine while my background task is going on. Once the background task is complete, the UI needs to update which can take 1-2 seconds. This of course causes the progress bar to freeze which looks ugly.

My question is, how can I spin up the busy indicator on a background thread so that the progress bar carries on moving all the way up until the UI becomes responsive? I'm open to other solutions as well as long as the progress bar doesn't freeze.

Here's some sample code:

<xctk:BusyIndicator IsBusy="{Binding IsBusy}" Style="{StaticResource BusyIndicatorStyle}">
    <DockPanel Margin="3">
        <TextBlock DockPanel.Dock="Top" Style="{StaticResource WorkspaceHeaderStyle}" Text="User Management"/>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <ToolBar Grid.Row="0">
                <Button Content="Save changes" Command="{Binding SaveChangesCommand}"/>
            </ToolBar>
            <TabControl Grid.Row="1">
                <TabItem Header="Users" DataContext="{Binding UsersViewModel}">
                    <users:UsersView />
                </TabItem>
                <TabItem Header="Roles" DataContext="{Binding RolesViewModel}">
                    <roles:RolesView />
                </TabItem>
            </TabControl>
        </Grid>
    </DockPanel>
</xctk:BusyIndicator>

private void LoadDays()
{
    ProgressIsBusy = true;

    var uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();

    var loadDaysTask = GetLoadDaysTask(uiScheduler);

    loadDaysTask.ContinueWith(antecedent =>
    {
        RaisePropertyChanged(() => ForecastViewModel);
        RaisePropertyChanged(() => AverageHandleTimeViewModel);
        RaisePropertyChanged(() => GeneralOptionsViewModel);
        RaisePropertyChanged(() => ScheduledHoursViewModel);        

        IsUserEditing = true;
        ProgressIsBusy = false;

    }, TaskScheduler.FromCurrentSynchronizationContext());

    loadDaysTask.Start();
}

解决方案

I don't believe that you can do that. You can't access UI controls from a background thread. Also, you may find that it is the UI thread that is busy rendering or notifying and making the progress bar freeze.

I have a similar setup in a large scale WPF application and it suffers from the same problem. The busy indicator displays fine while data is being fetched from the database, but then when the application starts to render the data in the UI, the busy indicator freezes.

I even tried using an animated Gif to get around this issue, but of course they don't animate (by themselves) in WPF applications. Having written the code to animate the frames in the Gif, I was very disappointed to find that it also suffered from the same problem.

Good luck all the same.

这篇关于BusyIndi​​cator控件WPF在后台线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆