2013-09-02 2 views
0

wpf 툴킷 차트를 사용하여 많은 수의 포인트를 차트 (최소 300,000 포인트)로 표시하려고합니다.Waiting Dialog 흰색 wpf 툴킷 차트가 그래프를로드합니다.

나는 다음과 같은 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를 차단 2 개 시간이 소요되는 작업을해야합니다. 내가 원하는 것은 시간이 많이 걸리는 작업이 진행되는 동안 "대화 상자를로드하십시오"를 표시하여 사용자가 응용 프로그램이 여전히 뭔가를하고 있음을 알 수 있도록하는 것입니다.

시간이 소요되는 작업은 다음과 같습니다

  1. (이 작업은 별도의 스레드에서 수행하지만 다음 작업 때문에 (차트의 포인트를로드 할 수 있습니다) 파일에서 포인트를 읽고 그것에 따라 달라집니다 UI 작업입니다. 별도의 스레드에 넣지 않았습니다.)
  2. 차트에서 ItemsSource로 포인트를로드합니다. 이는 UI 작업이므로 UI ​​스레드에서 수행해야합니다. 하지만 어떻게 포인트가 표시되는지에 대한 컨트롤이 없기 때문에 어플리케이션을 반응 적으로 만들 수 있습니까? 이것이 차트 자체의 로직입니까?

그래서 어떤 아이디어입니까? 비슷한 문제가 있습니까? 고맙습니다, Nadia

답변

0

실제로 제가 한 것은 데이터가로드되는 동안 나타나는 다른 "로드 중 대화"를 표시하는 별도의 스레드를 만드는 것입니다. UI가 완전히 반응 할 때까지 대화 상자가 닫힌 순간부터 약 1 초가 걸리지 만 응답하지 않는 UI를 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/