0

渲染时我需要一个进度条/忙碌指示符,因为在 GUI 上有很多文本框和不同的控件。由于具有 CellTemplate 选择器的动态列,无法虚拟化 DataGrid。

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

在应用程序呈现时获取进度条/忙碌指示符的任何其他想法?

我的解决方案代码:

线程启动/停止 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();
        }
    }

忙窗:

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

在 Render-action 之前和之后调用 Thread:

    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));
            }));
    }
}
4

0 回答 0