2014-04-03 2 views
0

MVVM 응용 프로그램 내에서 WPF 형식으로 편집 가능한 DataGrid가 있습니다.WPF MVVM - Datagrid가 하위 항목의 변경된 속성을 업데이트하지 않습니다.

사용자가이 페이지에서 취할 수있는 두 가지 가능한 조치로 인해 행 중 일부 데이터가 변경됩니다. 편집 가능한 필드 중 하나 - 요청 - 또 다른 속성이 변화의 원인, 그 값에 따라 스타일 트리거있을 수 있습니다

public bool OverRequested 
{ 
    get 
    { 
     if(this.Requested > this.Volume) 
     { 
      return true; 
     } 
     return false; 
    } 
} 

그리고 XAML에서 :

<DataGridTextColumn Header="Requested" Binding="{Binding Requested}"> 
    <DataGridTextColumn.CellStyle> 
     <Style TargetType="DataGridCell"> 
      <Style.Triggers> 
       <DataTrigger Binding="{Binding OverRequested}" Value="true"> 
        <Setter Property="Foreground" Value="Red"/> 
        <Setter Property="ToolTip" Value="The requested volume is greater than the available volume" /> 
       </DataTrigger> 
      </Style.Triggers> 
     </Style> 
    </DataGridTextColumn.CellStyle> 
</DataGridTextColumn> 

다른 것은 버튼입니다 행 뒤의 데이터 항목을 업데이트하고 항목의 값을 변경합니다.

DataGrid 자체는 변경에 반응하지만, 기본 ObservableCollection에서 행을 추가하거나 제거하면 UI에서 그에 따라 업데이트됩니다. 행 아래 항목의 이러한 속성에 대한 변경 사항은 업데이트되지 않습니다.

observableCollection 내부의 항목을 변경하면 불필요한 변화가 발생한다는 점을 고려하여 의도적으로 설계된 것으로 알고 있지만, 원하는대로 달성하는 방법을 찾기 위해 고심하고 있습니다.

내가 해봤 - 다른 제안 - ObservableCollection에에 CollectionChanged에 대한 이벤트 핸들러를 오버라이드 (override) 내부의 항목 알림 경고를 추가 :

private void ObservableCollection_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) 
{ 
    if (e.NewItems != null) 
    { 
     foreach (var item in e.NewItems) 
     { 
      (item as INotifyPropertyChanged).PropertyChanged += new PropertyChangedEventHandler(item_PropertyChanged); 
     } 
    } 
} 

그러나 항목은 내부에서 INotifyPropertyChanged 인터페이스를 구현하지 않습니다 - 그들은 ViewModel이 아닌 Entity Framework 객체. 그래서 캐스트가 실패합니다.

구현할 수있는 방법이 있습니까? 보기에는 두 가지 속성 만 있으면 기꺼이 수동으로 할 수 있습니다.하지만 ViewModel의 모든 속성을 업데이트하기 위해 OnPropertyChanged ("")를 호출해도 DataGrid 내부의 속성을 새로 고치지 않아도됩니다.

답변

1

아마도 변환기를 사용하면 다른 방법으로 시도해 볼 수 있습니다. 나는 그런 식으로 일하는 앱을 가지고있다.

public class OverRequestedForegroundMultiConverter : IMultiValueConverter 
{ 
    #region IValueConverter Members 

    public object Convert(object[] value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     if (value != null && value.Length == 2) 
     { 
      if (value[0] is int && value[1] is int) 
      { 
       int requested = (int)value[0]; 
       int volume = (int)value[1]; 
       if (requested > volume) 
        return Colors.Red; 
      } 
     } 
     return Colors.Gray; // Or whatever color you want 
    } 

    public object[] ConvertBack(object value, Type[] targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 

    #endregion 
} 

    public class OverRequestedTooltipMultiConverter : IMultiValueConverter 
    { 
     #region IValueConverter Members 

     public object Convert(object[] value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
     { 
      if (value != null && value.Length == 2) 
      { 
       if (value[0] is int && value[1] is int) 
       { 
        int requested = (int)value[0]; 
        int volume = (int)value[1]; 
        if (requested > volume) 
         return "The requested volume is greater than the available volume"; 
       } 
      } 
      return null; 
     } 

     public object[] ConvertBack(object value, Type[] targetType, object parameter, System.Globalization.CultureInfo culture) 
     { 
      throw new NotImplementedException(); 
     } 

     #endregion 
    } 

잊지 마세요 은을 추가 :

<DataGridTextColumn Header="Requested" Binding="{Binding Requested}"> 
<DataGridTextColumn.CellStyle> 
    <Style TargetType="DataGridCell"> 
     <Setter Property="Foreground"> 
       <Setter.Value> 
       <MultiBinding Converter="{StaticResource OverRequestedForegroundMultiConverter}"> 
        <Binding Path="Requested" /> 
        <Binding Path="Volume" /> 
       </MultiBinding> 
       </Setter.Value> 
     </Setter> 
     <Setter Property="ToolTip"> 
       <Setter.Value> 
       <MultiBinding Converter="{StaticResource OverRequestedTooltipMultiConverter}"> 
        <Binding Path="Requested" /> 
        <Binding Path="Volume" /> 
       </MultiBinding> 
       </Setter.Value> 
     </Setter> 
    </Style> 
</DataGridTextColumn.CellStyle> 

컨버터는 다음과 같이 보일 것이다 : 나는 보통이 물건이 바로 얻을 수 있지만,이 시도 테스트 응용 프로그램이 필요합니다 귀하의 app.xaml로 변환 :

<app:OverRequestedForegroundMultiConverter x:Key="OverRequestedForegroundMultiConverter" /> 
<app:OverRequestedTooltipMultiConverter x:Key="OverRequestedTooltipMultiConverter" /> 
+0

감사합니다. 흥미로운 접근 방식입니다. 그것은 내 OverRequested 속성에 대해 잘 작동하지만 비슷한 방식으로 예약 속성을 업데이트 할 때 발생하는 것 같지 않습니다. –

+0

FYI DataGrid 편집 후에도 OverRequested가 변경되지만 예약은 Button click 명령에서 변경됩니다. –

관련 문제