渲染时Progressbar / Busyindicator的最佳方式

时间:2015-03-19 12:43:43

标签: c# render busyindicator

我在渲染时需要一个Progressbar / Busyindicator,因为在GUI上有很多TextBoxes和不同的Controls。由于具有CellTemplate Selector的动态Columns,无法虚拟化DataGrid。

所以我真的需要一个Progressbar / Busyindicator,以便应用程序似乎不会被冻结。 我的方法是在STA-Thread中设置一个新窗口,当我知道GUI将呈现并在之后关闭它。 问题是,我无法设置Window-Owner。因此,如果应用程序未被冻结(无渲染,只是一个任务),则用户可以将窗口置于前景之后。设置Window Topmost似乎不是一个很好的解决方案。

在应用程序渲染时获取Progressbar / Busyindicator的任何其他想法?

我的解决方案代码:

线程启动/停止Busywindow:

private void ShowBusyWindow(bool show)
    {
        if (show)
        {
            if (BusyThread == null || !BusyThread.IsAlive)
            {
                BusyThread = new Thread(new ThreadStart(() =>
                {
                    // Create our context, and install it:
                    SynchronizationContext.SetSynchronizationContext(
                        new DispatcherSynchronizationContext(
                            Dispatcher.CurrentDispatcher));

                    BusyWindow window = new BusyWindow();

                    // When the window closes, shut down the dispatcher
                    window.Closed += (s, e) =>
                       Dispatcher.CurrentDispatcher.BeginInvokeShutdown(DispatcherPriority.Background);
                    window.ShowInTaskbar = true;
                    window.Show();
                    // Start the Dispatcher Processing
                    System.Windows.Threading.Dispatcher.Run();
                }));
                BusyThread.SetApartmentState(ApartmentState.STA);
                // Make the thread a background thread
                BusyThread.IsBackground = true;

                BusyThread.Start();
            }
        }
        else
        {
            if (BusyThread != null && BusyThread.IsAlive)
                BusyThread.Abort();
        }
    }

Busywindow:

<Window x:Class="MEval.Wpf.View.BusyWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
    Title="BusyWindow" SizeToContent="WidthAndHeight"
    WindowStyle="None"
    ResizeMode="NoResize"
    WindowStartupLocation="CenterScreen"

    >
<Grid>
    <xctk:BusyIndicator IsBusy="True">
    </xctk:BusyIndicator>
</Grid>

在渲染操作之前和之后调用线程:

    private DataTable _SelectedMeasurementData;
    public DataTable SelectedMeasurementData
    {
        get { return _SelectedMeasurementData; }
        set {

            if (value != null)
            {
                Messenger.Default.Send<BusyWindowMessage>(new BusyWindowMessage(true));
            }
            _SelectedMeasurementData = value;
            RaisePropertyChanged("SelectedMeasurementData");

            this.dispatcherProvider.CurrentDispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Loaded, new Action(() =>
            {
                Messenger.Default.Send<BusyWindowMessage>(new BusyWindowMessage(false));
            }));
    }
}

0 个答案:

没有答案