2012-04-25 47 views
2

我想知道每次用戶修改WPF DataGrid中的數據。知道用戶是否更改了DataGrid中的數據的最佳方法是什麼?

有沒有一個我可以用來做的事件?或者,我可以用來覆蓋整套數據更改(添加行,刪除行,修改行等)的最小事件集是什麼?

+0

你使用的設計模式,如MVVM或MVC,或者你只是在後面直接執行代碼? – Josh 2012-04-25 18:48:54

+0

我正在使用mvvm。我想用這個來告訴我什麼時候需要保存數據 – 2012-04-25 18:50:55

+0

http://msdn.microsoft.com/en-us/library/system.windows.controls.datagrid.selectedcellschanged.aspx – Habib 2012-04-25 18:52:16

回答

1

通常,當您使用MVVM時,您將主列表綁定到ObservableCollection,然後將選定項綁定到特定實例。在你的製片人內部,你可以舉辦活動。這將是最合理的(閱讀:我見過的最常用的方法)捕獲更新/添加/刪除到數據列表。

0

MainWindow.xaml

<Window x:Class="WpfApplication.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:WpfApplication" 
     Title="MainWindow" Height="350" Width="525"> 
    <DataGrid x:Name="dataGrid" AutoGeneratingColumn="OnAutoGeneratingColumn"> 
     <DataGrid.Resources> 
      <Style TargetType="DataGridCell"> 
       <EventSetter Event="Binding.SourceUpdated" Handler="OnDataGridCellSourceUpdated"/> 
       <EventSetter Event="Binding.TargetUpdated" Handler="OnDataGridCellTargetUpdated"/> 
      </Style> 
     </DataGrid.Resources> 
    </DataGrid> 
</Window> 

MainWindow.xaml.cs

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 

     this.dataGrid.ItemsSource = new ObservableCollection<Person>() 
     { 
      new Person() { Name = "John", Surname = "Doe" }, 
      new Person() { Name = "Jane", Surname = "Doe" } 
     }; 
    } 

    private void OnAutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e) 
    { 
     var dataGridBoundColumn = e.Column as DataGridBoundColumn; 
     if (dataGridBoundColumn != null) 
     { 
      var binding = dataGridBoundColumn.Binding as Binding; 
      if (binding != null) 
      { 
       binding.NotifyOnSourceUpdated = true; 
       binding.NotifyOnTargetUpdated = true; 
      } 
     } 
    } 

    private void OnDataGridCellSourceUpdated(object sender, DataTransferEventArgs e) 
    { 
     this.OnDataGridCellChanged((DataGridCell)sender); 
    } 

    private void OnDataGridCellTargetUpdated(object sender, DataTransferEventArgs e) 
    { 
     this.OnDataGridCellChanged((DataGridCell)sender); 
    } 

    private void OnDataGridCellChanged(DataGridCell dataGridCell) 
    { 
     // DataContext is MS.Internal.NamedObject for NewItemPlaceholder row. 
     var person = dataGridCell.DataContext as Person; 
     if (person != null) 
     { 
      var propertyName = ((Binding)((DataGridBoundColumn)dataGridCell.Column).Binding).Path.Path; 
      var propertyValue = TypeDescriptor.GetProperties(person)[propertyName].GetValue(person); 
      // TODO: do some logic here. 
     } 
    } 
} 

這是我用了一段複雜的DataGridCell格式化基於個人(只是一些POCO)實例,屬性名稱和屬性值。

但是,如果您希望能夠知道何時保存數據並使用MVVM,那麼最好的方法是獲得視圖模型/模型中每個可編輯屬性的原始值和當前值。加載數據時,原始值和當前值相等,如果通過DataGrid或其他方式更改屬性,則只更新當前值。當需要保存數據時,只需檢查任何項目是否有任何具有不同原始值和當前值的屬性。如果答案是肯定的,那麼應該保存數據,因爲它自上次加載/保存後已經被更改,否則數據與加載時相同,因此不需要新的保存。此外,保存時,當前值必須複製到原始值,因爲數據再次等於保存的數據,就像上次加載時一樣。

3

我知道這可能比你要求的要多,但一旦你做到了,就很難再回頭了。無論你綁定到什麼List,都有該項目實現IEditableObject。 這樣你就不必擔心任何控制/視圖實現,事件ets。 更改項目時,數據網格以及過多的.NET控件都會將IsDirty對象設置爲true。

這些不是超級好的鏈接,但他們會讓你開始考慮維護isDirty標誌。

https://msdn.microsoft.com/en-us/library/system.componentmodel.ieditableobject(v=vs.110).aspx

object editing and isDirty() flag

http://bltoolkit.net/doc/EditableObjects/EditableObject.htm

這更是我所用:

https://stackoverflow.com/a/805695/452941

+0

您的MSDN鏈接已死亡。 – 2012-04-26 00:39:08

+0

我修復了這個鏈接 – Sentry 2016-10-01 16:27:51

0

如果你使用MVVM你不需要知道什麼時候「用戶修改數據網格中的數據「您必須知道何時潛在收集變更

所以如果你使用數據表(HasChanges/RejectChanges ...),你已經內置了所有的內存。如果你使用poco集合,那麼你的項目至少必須實現INotifyPropertyChanged - 如果它引發用戶修改數據。也許IEditable也是一個很好的拒絕更改等等。

相關問題