我正在使用WPF。 。 。数据网格通过VisualStudio IDE拖放绑定到数据库,并找到了一种方法来使我的数据网格更新并使用RowEditEnding事件实时添加到数据库:
private void Update_WatchList(object sender, DataGridRowEditEndingEventArgs e)
{
UpdateWatchList();
}
private void UpdateWatchList()
{
dsDocControlTableAdapters.DocumentWatchListTableAdapter ta = new dsDocControlTableAdapters.DocumentWatchListTableAdapter();
try
{
DataRowView dr = (DataRowView)documentWatchListDataGrid.SelectedItem;
dsDocControl.DocumentWatchListRow dr1 = (dsDocControl.DocumentWatchListRow)dr.Row;
dr1.EndEdit();
if (dr1.RowState == DataRowState.Detached)
dsDocControl.DocumentWatchList.AddDocumentWatchListRow(dr1);
ta.Update(dr1);
}
catch (Exception ex)
{
MessageBox.Show("Error UpdateWatchList:\n" + ex.Message);
}
}
这是多次尝试和错误的结果(在此期间我错过了,重新安排并再次错过了牙科预约)但不知何故偶然发现需要在行上调用EndEdit()以便将RowState更新为Modified或分离。这是一个看似非常正常的用例的预期操作顺序,还是有更好的方法来做到这一点?
我已经开始为添加的行添加CollectionChanged事件处理程序,但无法使其工作,可能是因为我没有正确使用ObservableCollection:
private void documentWatchListDataGrid_Loaded(object sender, RoutedEventArgs e)
{
var dg = (DataGrid)sender;
if(dg==null || dg.ItemsSource == null) return;
var sourceCollection = dg.ItemsSource as ObservableCollection<DataRow>;
if (sourceCollection == null) return;
//sourceCollection.CollectionChanged += new NotifyCollectionChangedEventHandler(Update_WatchList); // never gets called
}
添加处理程序的行被注释掉了,因为我使用了处理程序作为RowEditEnding(在第一个代码块中),但不管它到底是什么,因为sourceCollection始终为null。
我的问题是,做这个看似简单的事情的最佳实践方法是什么:在WPF数据网格控件中更改或添加每一行时实时更新?
答案 0 :(得分:2)
这是一个看似非常正常的用例的预期操作顺序,还是有更好的方法来做到这一点?
不,这不是在WPF中使用DataGrids的常规方法。看起来WinForms可能是正常的,但不是WPF。 :)
绑定DataGrid.ItemsSouce
的典型方法是构建一个继承INotifyPropertyChanged
的类来表示每一行数据,并将DataGrid.ItemsSource
绑定到该类的ObservableCollection<T>
例如,您可能有类似
的内容public class WatchListModel : INotifyPropertyChanged
{
// Whatever properties here
public string Id { get; set; }
public string Name { get; set; }
}
这个类应该实现INotifyPropertyChanged,属性应该引发更改通知,但是我为了简单起见而将其遗漏了。如果您需要示例,请查看here。
然后你有一个ObservableCollection<WatchListModel>
,你也会绑定你的DataGrid.ItemsSource
public ObservableCollection<WatchListModel> WatchListCollection { get; set; }
和
<DataGrid ItemsSource="{Binding WatchListCollection}" ... />
如果您想要实时更新,您需要为WatchListCollection
添加一个集合更改事件处理程序来处理添加/删除,并为每个项目添加一个属性更改处理程序以处理其修改后的< / p>
public MyViewModel()
{
WatchListCollection = new ObservableCollection<WatchListModel>();
// Hook up initial changed handler. Could also be done in setter
WatchListCollection.CollectionChanged += WatchListCollection_CollectionChanged;
}
void WatchListCollection_CollectionChanged(object sender, CollectionChangedEventArgs e)
{
// if new itmes get added, attach change handlers to them
if (e.NewItems != null)
foreach(WatchListModel item in e.NewItems)
item.PropertyChanged += WatchListModel_PropertyChanged;
// if items got removed, detach change handlers
if (e.OldItems != null)
foreach(WatchListModel item in e.OldItems)
item.PropertyChanged -= WatchListModel_PropertyChanged;
// Process Add/Remove here
}
void WatchListModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
// Process Update here
}
这将是正确的WPF方式:)