【问题标题】:Datagrid validation to prevent duplicate entry数据网格验证以防止重复输入
【发布时间】:2012-03-11 23:20:18
【问题描述】:

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

我现在想做的是添加验证条目不存在的功能。如果它确实存在,那么我希望突出显示相同的单元格条目,但带有适当的消息。所以如果用户再次输入“Eggs”,单元格错误信息应该是“Eggs is already on the list”。

项目视图模型不应该知道它的容器视图模型,那么在“名称”属性的单元格验证期间我可以在哪里检查重复条目?

集合中的项目

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>

【问题讨论】:

    标签: wpf validation mvvm datagrid


    【解决方案1】:

    我不知道这是否违反了 MVVM,但我的做法是将 GroceryList 传递给另一个构造函数中的 GroceryItem 并将其保存在 GroceryItem 中的私有 ObservableCollectiongroceryList 中。这只是对 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
             }
      }
    

    【讨论】:

    • 我想我不能让 DataGrid 自动为我添加行,因为这需要 GroceryItem 上的默认 ctor。我需要在控制集合的主视图模型上添加一个命令,但是是的,我同意这是一个明确的可能性。
    • 你的想法并没有违反任何关于 MVVM 的内容;我想也许所有通知已经来自数据绑定,我可能有一个更松散耦合的解决方案可用,而我只是没有看到。干杯
    • 默认情况下,该项目甚至不知道它是集合的成员 - 松散耦合。传递对集合的引用是从我能想到的项目中获取集合的最简单的方法,我经常使用它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-03
    • 2022-11-08
    • 1970-01-01
    相关资源
    最近更新 更多