WPF DataGrid RowEditEnding调用Update的事件

时间:2014-10-28 23:49:48

标签: c# wpf datagrid

我正在使用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数据网格控件中更改或添加每一行时实时更新?

1 个答案:

答案 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方式:)