为什么ObservableCollection没有实现?

时间:2014-01-14 10:37:07

标签: c# wpf data-binding

我正在编写一个应用程序,它可以处理大量数据,然后在图形上显示它们。计算需要很长时间,所以我希望programm能够像这样工作:

  1. 计算点。
  2. 将计算点添加到图表
  3. 计算下一点
  4. 将计算点添加到图表中 等
  5. 但是我的应用程序的工作方式不同:

    1. 计算所有点数(花费大量时间)
    2. 一次显示所有内容。
    3. 我不明白为什么会这样,因为我在将每个点添加到图表后使用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>
      

2 个答案:

答案 0 :(得分:0)

ObservableCollection和OnPropertyChanged与线程或Async无关,它们有助于DataBinding和View / ViewModel编码。您的所有工作仍在一个UI线程中完成,因此在完成工作之前,您不会看到对ObservableCollection的更改。

你需要看的是像BackgroundWorker类...... http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker(v=vs.110).aspx

答案 1 :(得分: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
});