GUI には多くの TextBoxes とさまざまなコントロールがあるため、レンダリング中に Progressbar/Busyindicator が必要です。CellTemplate セレクターを使用した動的列のため、DataGrid を仮想化できません。
したがって、アプリケーションがフリーズしていないように見えるように、Progressbar/Busyindicator が本当に必要です。私のアプローチは、GUIがレンダリングされてから閉じることがわかっているときに、STAスレッドに新しいウィンドウを設定することでした。問題は、Window-Owner を設定できないことです。したがって、アプリケーションがフリーズしていない場合 (レンダリングなし、タスクのみ)、ユーザーはウィンドウをフォアグラウンドに戻すことができます。ウィンドウを一番上に設定することは、良い解決策ではないようです。
アプリケーションのレンダリング中に 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();
}
}
ビジーウィンドウ:
<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 アクションの前後にスレッドを呼び出します。
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));
}));
}
}