2012-12-07 79 views
1

我遇到了designpattern MVVM的问题。 在我看来,我得到了一个Datagrid绑定到我的viewmodel中的数据表。如何通过多线程将DataRow添加到ViewModel中的DataTable

 <WPF:BADataGrid Grid.Column="1" x:Name="dgStapelliste" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ItemsSource="{Binding Stapelliste, Mode=OneWay}"/> 

在我的viewmodel的构造函数中,我加载了ItemsSource。

 this.StapelListe = this._stapel.Get(); 

如果我通过一个按钮在运行时添加一些额外的行一切工作正常。 但我不想推按钮来刷新数据网格,我希望它自动发生在线程或后台工作。

Here's一些测试例子:

 BackgroundWorker worker = new BackgroundWorker(); 
     worker.DoWork += delegate(object s, DoWorkEventArgs args) 
     { 
      while (true) 
      { 
       Thread.Sleep(5000); 

       DataRow row = this.StapelListe.NewRow(); 
       row["StapelNr"] = 123456; 
       this.StapelListe.Rows.Add(row); 
      } 
     }; 

本不需额外的工作...和我不知道为什么...行DataTable中“StapelListe”添加,但数据网格是不打算刷新自己...

如果我在它的工作原理线程更改现有行中的数据表!它不适用于添加或删除集合中的行。

有人知道为什么发生这种情况和/或如何解决它?

亲切的问候...

回答

1

由于MEGAMIND写道,查看需要知道事情已经改变。如果您将新的行添加到现有的DataTable中,则View从不会收到有关已添加内容的通知。所以你应该使用一个为此制作的集合:ObservableCollection<T>

+0

是的ObservableCollection肯定会工作,但他有一个数据表,使用可观察的集合,他需要遍历整个数据表,并获得所需的集合,我猜大开销。 – MegaMind

+0

@MegaMind是的,他必须将DataTable转换为ObservableCollection。但我认为这不会是一个很大的开销。相反,这就是ViewModel的用途:将Model数据(在本例中为DataTable)转换为View正确理解的内容(在本例中为ObservableCollection)。 –

+0

完全同意你的观点,或者他必须使用可观察的集合,或者需要更改列表的引用,以防他想要坚持列表。在List的情况下,他必须实现INotifyPropertyChanged,通过可观察的集合,他可以很好地完成该接口。 – MegaMind

2

你犯了数据绑定的经典错误。你应该如何更新屏幕,如果你永远不会让你的GUI知道有什么变化。要做到这一点,你需要使用NotifyPropertyChanged接口。

实现从INotifyPropertyChanged接口的视图模型。

这是一个可以把你在工作中

您不必使用线程来完成这项工作的代码片段,很少会就好了,只要你叫更新收集后NotifyProperyChanged。

如果你不使用的ObservableCollection,你必须更新列表中,这将是有点痛苦到你的应用程序的参考;表现

 BackgroundWorker worker = new BackgroundWorker(); 
     worker.DoWork += delegate(object s, DoWorkEventArgs args) 
     { 
      while (true) 
      { 
       Thread.Sleep(5000); 
       DataRow row = this.StapelListe.NewRow(); 
       row["StapelNr"] = 123456; 
       this.StapelListe.Rows.Add(row); 
       Datatable dt=new datatable(); //new reference 
       foreach (DataRow dr in StapelListe.Rows) 
       {  
       dt.Rows.Add(dr.ItemArray); 
       } 

       StapelList=dt; //updating the reference of property 
       // when the above line executes your property setter fires 
       // and calls notifyproperty changed and then all done 
     }; 
+0

只有在您替换列表时才会更新。 –

+0

是的...我试着在线程中提出propertychanged事件...但是那也不管用。给出了相同的结果 –

+0

这种方法的问题是,如果您为底层DataTable调用PropertyChanged,则意味着View将不得不重做整个DataTable数据的显示。如果使用ObservableCollection,它只需要更新实际更改的数据。 –

相关问题