2012-02-21 3 views
1

아래 코드를 사용하여 잘못된 셀 항목을 트랩 할 수 있습니다. 식료품 쇼핑 목록의 간단한 예제에서 GroceryItem.Name을 입력하면됩니다.중복 항목을 방지하기위한 Datagrid 유효성 검사

내가 지금하고 싶은 것은 항목이 이미 존재하지 않음을 확인하는 기능을 추가하는 것입니다. 그것이 이미 존재한다면, 나는 똑같은 셀 엔트리를 강조하지만 적절한 메시지를 원합니다. 따라서 사용자가 "달걀"을 다시 입력하면 셀 오류 메시지는 "달걀이 이미 목록에 있음"이어야합니다.

항목보기 모델은 컨테이너보기 모델에 대해 알 필요가 없으므로 "이름"속성의 셀 유효성 검사에서 중복 항목을 확인할 수 있습니까? 컬렉션에서

enter image description here

항목

public class GroceryItem : ObservableObject, IDataErrorInfo 
{ 

    #region Properties 

    /// <summary>The name of the grocery item.</summary> 
    public string Name 
    { 
     get { return _name; } 

     set 
     { 
      _name = value; 
      RaisePropertyChangedEvent("Name"); 
     } 
    } 
    private string _name; 

    #endregion 

    #region Implementation of IDataErrorInfo 

    public string this[string columnName] { 
     get { 
      if (columnName == "Name") { 
       if (string.IsNullOrEmpty(Name)) 
        return "The name of the item to buy must be entered"; 
      } 

      return string.Empty; 
     } 
    } 

    public string Error { get { ... } } 

    #endregion 
} 

보기 모델 컬렉션 데이터 그리드에 대한 바인딩

public class MainWindowViewModel : ViewModelBase 
{ 

    /// <summary>A grocery list.</summary> 
    public ObservableCollection<GroceryItem> GroceryList 
    { 
     get { return _groceryList; } 

     set 
     { 
      _groceryList = value; 
      RaisePropertyChangedEvent("GroceryList"); 
     } 
    } 
    private ObservableCollection<GroceryItem> _groceryList; 

    /// <summary>The currently-selected grocery item.</summary> 
    public GroceryItem SelectedItem { get; [UsedImplicitly] set; } 

    void OnGroceryListChanged(object sender, NotifyCollectionChangedEventArgs e) 
    { 
     // doing non-validation stuff 
    } 
} 

보기를 들고

<DataGrid 
    x:Name="MainGrid" 
    ItemsSource="{Binding GroceryList}" 
    SelectedItem="{Binding SelectedItem}" 
    ...    
    > 
    <DataGrid.Resources> 
     <Style TargetType="{x:Type DataGridCell}"> 
      <Setter Property="TextBlock.ToolTip" 
      Value="{Binding Error}" /> 
     </Style> 
    </DataGrid.Resources> 

    <DataGrid.Columns> 
     ... 
     <DataGridTextColumn Header="Item" Width="*" Binding="{Binding Name, ValidatesOnDataErrors=True}" IsReadOnly="false" /> 
    </DataGrid.Columns> 
</DataGrid> 

답변

1

내가 돈 ' 내가 MVVM을 위반하는지 알지만, GroceryItem에 GroceryItem을 전달하고 GroceryItem의 private ObservableCollection groceryList에 저장합니다. GroceryList에 경의를 표하는 것만으로 많은 오버 헤드가 추가되지 않습니다.

public class GroceryItem : ObservableObject, IDataErrorInfo 
    { 
     private ObservableCollection<GroceryItem> groceryList; 

     public void GroceryItem(string Name, ObservableCollection<GroceryItem> GroceryList) 
     { 
       name = Name; 
       groceryList = GroceryList; 
       // now you can use groceryList in validation 
     } 
    } 
+0

GroceryItem에 기본 ctor가 필요하므로 DataGrid에서 자동으로 행을 추가하도록 할 수는 없을 것 같습니다. 컬렉션을 제어하는 ​​기본 뷰 모델에 AddCommand가 필요하지만 그래, 나는 이것이 확실한 가능성이라는 것에 동의한다. – Berryl

+0

당신의 생각은 MVVM에 관한 어떤 것도 위반하지 않습니다; 아마도 모든 알림이 이미 데이터 바인딩에서 왔을 것으로 생각했기 때문에 좀 더 느슨하게 결합 된 솔루션을 사용할 수있을 것 같았습니다. 건배 – Berryl

+0

기본적으로이 항목은 컬렉션의 구성원 인 느슨하게 결합 된 항목이 아닙니다. 컬렉션에 대한 참조를 전달하는 것은 내가 생각할 수있는 항목에서 컬렉션에 도달하는 가장 방해가되지 않는 방법이며 많은 것을 사용합니다. – Paparazzi

관련 문제