2014-01-14 38 views
0

我正在编写一个应用程序,它处理大量数据,然后在图形上将它们可视化。计算需要很长时间,所以我希望程序能够像这样工作:为什么ObservableCollection不能实现?

  1. 计算点。
  2. 添加计算点到图形
  3. 计算下一个点
  4. 添加计算点到图形 等

但是我的应用程序的工作方式不同:

  1. 计算所有点(取巨大的时间)
  2. 一次显示一切。

我不明白为什么会这样,因为我使用OnPropertyChanged方法后,将每个点添加到图形。

代码隐藏 - 图类:

public class graph : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 
    protected void OnPropertyChanged(string name) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(name)); 
     } 
    } 

    public class pnt 
    { 
     public double x { get; set; } 
     public double y { get; set; } 

     public pnt(double _x, double _y) { x = _x; y = _y; } 
    } 

    public double maxy { get; set; } 
    public double scale_y { get { return 200/maxy; } } 
    public double width { get; set; } 

    private ObservableCollection<double> values; 
    public ObservableCollection<punkt> pnts { get; set; } 

    public graph() 
    { 
     pnts = new ObservableCollection<punkt>(); 
     values = new ObservableCollection<double>(); 
    } 

    public void reset() 
    { 
     pnts.Clear(); 
     values.Clear(); 
    } 

    public void add_data(double y) 
    { 
     values.Add(y); 

     if (y > maxy) 
     { 
      maxy = y; OnPropertyChanged("maxy"); 
      OnPropertyChanged("scale_y"); 
     } 

     if (pnts.Count < width) 
     { 
      values.Add(y); 
      pnts.Add(new pnt(values.Count, y)); 
     } 
     else 
     { 
      values.Add(y); 
      shuffle(); 
     } 

     OnPropertyChanged("pnts"); 
    } 

    public void shuffle() 
    { 
     pnts = new ObservableCollection<pnt>(); 

     int s = (int)Math.Ceiling(values.Count/width); 

     for (int i = 0; i < values.Count; i++) 
      if (i % s == 0) 
       pnts.Add(new pnt(pnts.Count, values[i])); 

     OnPropertyChanged("pnts"); 
    } 

    public void change_width(double new_width) 
    { 
     width = new_width; 
     OnPropertyChanged("width"); 
    } 
} 

XAML代码:

      <Canvas HorizontalAlignment="Left" VerticalAlignment="Bottom"> 
           <Canvas.RenderTransform> 
            <ScaleTransform ScaleY="{Binding graph1.scale_y}"/> 
           </Canvas.RenderTransform> 
          </Canvas> 
         </ItemsPanelTemplate> 
        </ListView.ItemsPanel> 
        <ListView.ItemContainerStyle> 
         <Style TargetType="ListViewItem"> 
          <Setter Property="Canvas.Left" Value="{Binding x}" /> 
          <Setter Property="Canvas.Bottom" Value="0" /> 
          <Setter Property="Padding" Value="0" /> 
          <Setter Property="Margin" Value="0" /> 
         </Style> 
        </ListView.ItemContainerStyle> 
        <ListView.ItemTemplate> 
         <DataTemplate> 
          <Line X1="0" X2="0" Y1="0" Y2="{Binding y}" Style="{StaticResource styleGraph}"/> 
         </DataTemplate> 
        </ListView.ItemTemplate> 
       </ListView> 

回答

0

你只需要在每次更新数据,以便它可以更新UI时间控制返回到UI线程。您可以通过在UI线程Dispatcher上安排数据更新任务来执行此操作。你可以用这样的方法方便:

public object RunOnUiThread(Delegate method) 
{ 
    return Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Normal, method); 
} 

然后,您可以使用此方法您的循环内是这样的:

RunOnUiThread((Action)delegate 
{ 
    // this will run on the UI thread 
    // add your data here 
}); 
相关问题