2012-04-25 2 views
2

사용자가 WPF DataGrid에서 데이터를 수정할 때마다 알고 싶습니다.사용자가 DataGrid에서 데이터를 변경했는지 확인하는 가장 좋은 방법은 무엇입니까?

내가 할 수있는 이벤트가 하나 있습니까? 또는 전체 데이터 변경 (행 추가, 행 삭제, 행 수정 등)에 사용할 수있는 최소한의 이벤트 집합은 무엇입니까?

+0

MVVM 또는 MVC와 같은 디자인 패턴을 사용하고 있습니까? 아니면 뒤에서 똑바로 코드를 작성하고 있습니까? – Josh

+0

mvvm을 사용하고 있습니다. 데이터를 저장할 시간을 알려주기 위해 이것을 사용하고 싶습니다. –

+0

http://msdn.microsoft.com/en-us/library/system.windows.controls.datagrid.selectedcellschanged.aspx – Habib

답변

1

일반적으로 MVVM을 사용하는 경우 마스터 목록을 ObservableCollection에 바인딩 한 다음 선택한 항목을 특정 인스턴스에 바인딩합니다. 당신의 세터 내부에서 이벤트를 제기 할 수 있습니다. 이것은 데이터 목록에 업데이트/추가/삭제를 캡처하는 가장 논리적 인 (읽은 가장 일반적인 방법입니다). 이것은 내가이 사람 (그냥 POCO) 예에 따라 서식을 일부 복잡한 DataGridCell에 사용되는 것입니다

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. 
     } 
    } 
} 

, 속성 이름 및 속성 값.

그러나 데이터를 저장할 시점을 알고 MVVM을 사용하려면보기 모델/모델의 모든 편집 가능한 속성에 대해 원래 값과 현재 값을 갖는 것이 가장 좋습니다. 데이터가로드되면 원래 값과 현재 값이 같고 DataGrid 또는 다른 방법으로 속성이 변경되면 현재 값만 업데이트됩니다. 데이터를 저장해야하는 경우 항목에 원래 값과 현재 값이 다른 속성이 있는지 확인하십시오. 대답이 '예'인 경우 데이터는 마지막로드/저장 이후 변경 되었기 때문에 저장해야합니다. 그렇지 않으면 데이터가로드 될 때와 동일하므로 새로운 저장이 필요하지 않습니다. 또한 저장시 마지막 값과 같은 저장된 데이터와 다시 동일하므로 현재 값을 원래 값으로 복사해야합니다.

3

나는 이것이 아마도 당신이 요구하는 것 이상이라는 것을 알고 있지만 일단 그것을하면 되돌릴 수 없다. 바인딩하는 항목에 관계없이 List에 IEditableObject를 구현하도록합니다. 그런 식으로 제어 /보기 구현, 이벤트 ets에 대해 걱정할 필요가 없습니다. 항목이 변경되면 DataGrid 및 많은 .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 링크가 작동하지 않습니다. –

+0

링크가 수정되었습니다. – Sentry

0

당신은 당신이 알 필요가 없습니다 MVVM 사용하는 경우 때 " 사용자가 데이터 그리드에서 데이터를 수정하면 "기본 컬렉션 변경.

그래서 당신이 datatable (HasChanges/RejectChanges ...)을 사용한다면 당신은 모두 내장되어 있습니다. poco 콜렉션을 사용한다면 여러분의 아이템은 적어도 INotifyPropertyChanged를 구현해야합니다. 어쩌면 IEditable은 거부 변경 등을위한 좋은 방법 일 수도 있습니다.

관련 문제