Datagrid验证以防止重复输入

时间:2012-02-21 16:20:55

标签: wpf validation mvvm datagrid

使用下面的代码我可以捕获无效的单元格条目。在这个杂货店购物清单的简单示例中,只需要填写GroceryItem.Name

我现在要做的是添加验证条目是否已存在的功能。如果它已经存在,那么我希望突出显示相同的单元格条目,但使用相应的消息。因此,如果用户输入" Eggs"再次,单元格错误消息应该是"鸡蛋已经在列表中#34;。

项目视图模型不应该知道它的容器视图模型,所以我在哪里可以检查重复的条目,同时仍然在"名称"属性?

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 个答案:

答案 0 :(得分:1)

我不知道这是否违反了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
         }
  }