等待对话框白色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。我想要的是在进行耗时的操作时显示一个"请加载对话框",这样用户就知道应用程序仍在做一些事情。

耗时的操作包括:

  1. 从文件中读取点(这个操作可以在一个单独的线程上完成,但由于下一个操作(加载图表中的点)取决于它,并且是一个UI操作,所以我没有把它放在一个独立的线程中)
  2. 将点加载为图表中的ItemsSource-这是一个UI操作,应该在UI线程上完成。但是,由于我无法控制点的显示方式,我如何才能让应用程序做出响应——这是图表自己的逻辑

那么,有什么想法吗?你有类似的问题吗?非常感谢。Nadia

等待对话框白色wpf工具箱图表加载图形

实际上,我所做的是创建一个单独的线程,在加载数据时显示不同的"加载对话框"。从对话框关闭到用户界面完全响应还有大约一秒钟的时间,但这仍然比看一个没有响应的用户界面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/