2012-02-21 127 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中

<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

我不t知道這是否違反MVVM,但我會這樣做的方式是將GroceryList傳遞給另一個構造函數中的GroceryItem,並將其保存在GroceryItem中的私有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

我想我不會讓DataGrid自動爲我添加行,因爲這需要GroceryItem上的默認ctor。我需要一個控制集合的主視圖模型上的AddCommand,但是,我同意這是一個確定的可能性。 – Berryl 2012-02-21 17:15:58

+0

你的想法沒有違反MVVM的任何內容;我想也許所有的通知都來自數據綁定,我可能有一個更鬆散耦合的解決方案,我只是沒有看到。乾杯 – Berryl 2012-02-21 17:31:08

+0

默認情況下,該項目並沒有真正意識到它是一個集合的成員 - 鬆散耦合。傳遞對集合的引用是從我能想到的項目到達集合的最不容易的方式,並且我使用它很多。 – Paparazzi 2012-02-21 19:41:17