2010-07-09 7 views
1

다소 복잡한 동작을하는 ChildViewModels의 ObservableCollection이 있습니다.DataGrid - 편집 동작 변경

DataGrid가 '편집 모드'로 들어가면 행이 커밋 될 때까지 현재 셀 외부의 UI 알림을 효과적으로 사용할 수 없게됩니다.이 동작이 더 중요하게 변경 될 수 있습니까?

예 :

public class ViewModel 
{ 
    public ViewModel() 
    { 
     Childs = new ObservableCollection<ChildViewModel> {new ChildViewModel()}; 
    } 
    public ObservableCollection<ChildViewModel> Childs { get; private set; } 
} 
public class ChildViewModel : INotifyPropertyChanged 
{ 
    private string _firstProperty; 
    public string FirstProperty 
    { 
     get { return _firstProperty; } 
     set 
     { 
      _firstProperty = value; 
      _secondProperty = value; 
      OnPropetyChanged("FirstProperty"); 
      OnPropetyChanged("SecondProperty"); 
     } 
    } 

    private string _secondProperty; 
    public string SecondProperty 
    { 
     get { return _secondProperty; } 
     set 
     { 
      _secondProperty = value; 
      OnPropetyChanged("SecondProperty"); 
     } 
    } 

    private void OnPropetyChanged(string property) 
    { 
     if (PropertyChanged != null) 
      PropertyChanged(this, new PropertyChangedEventArgs(property)); 
    } 
    public event PropertyChangedEventHandler PropertyChanged; 
} 

그리고보기

:

<Window.Resources> 
    <local:ViewModel x:Key="Data"/> 
</Window.Resources> 
<DataGrid DataContext="{Binding Source={StaticResource Data}}" ItemsSource="{Binding Childs}"/> 

공지 사항 어떻게 행을 떠날 때까지 첫 번째 열을 편집하는 것은 숨겨진 두 번째 통지.

편집 : 구현 IEditableObject 아무것도하지 않습니다 :

public class ChildViewModel : INotifyPropertyChanged,IEditableObject 
{ 
    ... 
    private ChildViewModel _localCopy; 

    public void BeginEdit() 
    { 
     _localCopy = new ChildViewModel {FirstProperty = FirstProperty, SecondProperty = SecondProperty}; 
    } 

    public void EndEdit() 
    { 
     _localCopy = null; 
    } 

    public void CancelEdit() 
    { 
     SecondProperty = _localCopy.SecondProperty; 
     FirstProperty = _localCopy.FirstProperty; 
    } 
} 

답변

7

이 동작은 BindingGroup을 사용하여 DataGrid에서 구현됩니다. DataGrid는 모든 행에 BindingGroup을 적용하기 위해 ItemsControl.ItemBindingGroup을 설정합니다. 그것은 MeasureOverride이 초기화, 그래서 당신은 MeasureOverride을 무시하고 그들을 지울 수 있습니다

public class NoBindingGroupGrid 
    : DataGrid 
{ 
    protected override Size MeasureOverride(Size availableSize) 
    { 
     var desiredSize = base.MeasureOverride(availableSize); 
     ClearBindingGroup(); 
     return desiredSize; 
    } 

    private void ClearBindingGroup() 
    { 
     // Clear ItemBindingGroup so it isn't applied to new rows 
     ItemBindingGroup = null; 
     // Clear BindingGroup on already created rows 
     foreach (var item in Items) 
     { 
      var row = ItemContainerGenerator.ContainerFromItem(item) as FrameworkElement; 
      row.BindingGroup = null; 
     } 
    } 
} 
+0

놀라운! 너무 감사합니다!이것은 내가 소수의 손으로 머리카락을 찢어 버릴 수있게했다. 가능한 한 빨리 현상금을 수여 할 것이다. – Goblin

0

좋아, 그래서, 여기에 문제가 있습니다. Observable Collection은 그것이 변경된 것을 객체에 알리지 않습니다. 그것은 단지 추가/제거/등을 통지합니다. 컬렉션을 업데이트하는 작업은 자체 작업입니다.

이 문제가있어서 직접 열을 데이터 격자에 추가 한 다음 열 개체에 바인딩 항목을 설정해야했습니다. 그래서 그것은 내 내용에 묶일 것입니다.

또한 내 ICollectionView에있는 개체를 IEditableObject에서 파생 시켰으므로 "업데이트 된"그리드가 자체적으로 새로 고침됩니다.

이것은 엿 같지만, 그것이 작동하려면 무엇을해야만하는지.

선택적으로, 항목을 수락하고 제거 할 때 속성이 변경된 핸들러를 첨부하거나 분리하는 ObservableCollection을 만들 수 있습니다.

+0

예 -하지만 컬렉션의 하위 항목은 INotifyPropertyChanged를 구현할 때이를 알립니다. 아 - 너무 빠르다. – Goblin

+0

오케이 - IEditable 인터페이스를 추가 한 것은 아무 것도하지 않았습니다. 문제의 개체가 이미 컬렉션에 있음을 알 수 있습니다. 행을 커밋하기 전에 다른 속성에 대한 알림이 실행되지 않는 속성을 편집 할 때입니다. – Goblin

+0

IEditableObject bc를 사용했습니다. 내 컬렉션은 ICollectionView였습니다. 컬렉션을 변경하지 않으면 속성 변경 이벤트를 컬렉션의 항목에 첨부해야합니다. 또한, 나는 자동 gen'd 열이 바인딩을 추가하는지 모르겠다. –

4

이것은 아주 오래된 질문이지만, 하위 클래스의 데이터 그리드를 필요로하지 않는 훨씬 더 나은 솔루션이 존재한다. CellEditEnding 이벤트에서 CommitEdit()를 호출하면됩니다.

bool manualCommit = false; 

private void MyDataGrid_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e) 
{ 
    if (!manualCommit) 
    { 
     manualCommit = true; 
     MyDataGrid.CommitEdit(DataGridEditingUnit.Row, true); 
     manualCommit = false; 
    } 
} 
+0

MVVM이 아니지만 간단한 접근 방식이 좋습니다. – user2190035

+1

@ user2190035 - MVVM과 호환됩니다. 코드에서 뷰 모델을 조작 할 필요가 없습니다. 코드는 뷰와 순전히 관련이 있으며 적절합니다. – user3690202