等待对话框白色wpf工具箱图表加载图形
本文关键字:加载 图形 工具箱 对话框 白色 wpf 等待 | 更新日期: 2023-09-27 18:29:47
我想使用wpf工具箱图表将大量点集合显示为图表(至少30万点)。
我有以下XAML
<chartingToolkit:Chart Name="chartHistory">
<chartingToolkit:Chart.Axes>
<chartingToolkit:LinearAxis x:Name="horizontalAxis" Orientation="X" Title="Time [s]" ShowGridLines="True"/>
<chartingToolkit:LinearAxis x:Name="verticalAxis" Orientation="Y" Title="Value [mm]" ShowGridLines="True"/>
</chartingToolkit:Chart.Axes>
<chartingToolkit:AreaSeries x:Name="chartSeries" DataPointStyle="{StaticResource chartDataPoint}"
IndependentValuePath="TimeInSeconds"
DependentValuePath="Value">
</chartingToolkit:AreaSeries>
</chartingToolkit:Chart>
在代码背后:
public class PointData
{
public double TimeInSeconds { get; set; }
public double Value { get; set; }
}
private List<PointData> points;
private void Screen_Loaded(object sender, RoutedEventArgs e)
{
// this is a large collection of points (minimum 300 000)
points = LoadPointsFromFile();
// and it takes a lot of time to read from the file and load in the UI
chartSeries.ItemsSource = points;
// additional chart display properties (setting min/max on the axes etc.)
}
因此,我有两个耗时的操作阻塞了我的UI。我想要的是在进行耗时的操作时显示一个"请加载对话框",这样用户就知道应用程序仍在做一些事情。
耗时的操作包括:
- 从文件中读取点(这个操作可以在一个单独的线程上完成,但由于下一个操作(加载图表中的点)取决于它,并且是一个UI操作,所以我没有把它放在一个独立的线程中)
- 将点加载为图表中的ItemsSource-这是一个UI操作,应该在UI线程上完成。但是,由于我无法控制点的显示方式,我如何才能让应用程序做出响应——这是图表自己的逻辑
那么,有什么想法吗?你有类似的问题吗?非常感谢。Nadia
实际上,我所做的是创建一个单独的线程,在加载数据时显示不同的"加载对话框"。从对话框关闭到用户界面完全响应还有大约一秒钟的时间,但这仍然比看一个没有响应的用户界面5-10秒要好。
public class PointData
{
public double TimeInSeconds { get; set; }
public double Value { get; set; }
}
#region Wait Dialog Thread
private class MainWindowSize
{
public double Left;
public double Top;
public double Width;
public double Height;
}
private Thread newWindowThread = null;
private void ThreadStartingPoint(object obj)
{
// WaitDialog is a new window from your project - you can place a animation or message inside it
WaitDialog tempWindow = new WaitDialog();
// since we don't have an owner for the window, we need
// to compute the location of the popup dialog, so that
// its centered inside the main window
MainWindowSize wndSize = obj as MainWindowSize;
if (wndSize != null)
{
tempWindow.Left = wndSize.Left + wndSize.Width / 2 - tempWindow.Width / 2;
tempWindow.Top = wndSize.Top + wndSize.Height / 2 - tempWindow.Height / 2;
}
// it's very important not to set the owner of this dialog
// otherwise it won't work in a separate thread
tempWindow.Owner = null;
// it shouldn't be a modal dialog
tempWindow.Show();
tempWindow.Closed += (sender1, e1) => tempWindow.Dispatcher.InvokeShutdown();
System.Windows.Threading.Dispatcher.Run();
}
private void CreateAndStartWaitWindowThread()
{
// create a thread only if you don't have an active one
if (newWindowThread == null)
{
// use ParameterizedThreadStart instead of ThreadStart
// in order to send a parameter to the thread start method
newWindowThread = new Thread(new ParameterizedThreadStart(ThreadStartingPoint));
newWindowThread.SetApartmentState(ApartmentState.STA);
newWindowThread.IsBackground = true;
// get the properties of the window, in order to compute the location of the new dialog
Window mainWnd = App.CurrentApp.MainWindow;
MainWindowSize threadParams = new MainWindowSize { Left = mainWnd.Left, Top = mainWnd.Top, Width = mainWnd.ActualWidth, Height = mainWnd.ActualHeight };
// start thread with parameters
newWindowThread.Start(threadParams);
}
}
private void AbortAndDeleteWaitWindowThread()
{
// abort a thread only if you have an active one
if (newWindowThread != null)
{
newWindowThread.Abort();
newWindowThread = null;
}
}
#endregion
private List<PointData> points;
private void Screen_Loaded(object sender, RoutedEventArgs e)
{
try
{
// call this before long operation
this.Cursor = Cursors.Wait;
CreateAndStartWaitWindowThread();
// this is a large collection of points (minimum 300 000)
points = LoadPointsFromFile();
// and it takes a lot of time to read from the file and load in the UI
chartSeries.ItemsSource = points;
// additional chart display properties (setting min/max on the axes etc.)
}
catch(Exception ex)
{
// do something with the exception
}
finally
{
// call this after long operation - and make sure it's getting called
// so put it in the finally block - to call it even if an exception is raised
this.Cursor = Cursors.Arrow;
AbortAndDeleteWaitWindowThread();
}
}
来源:http://www.c-sharpcorner.com/uploadfile/suchit_84/creating-wpf-windows-on-dedicated-threads/