【问题标题】:How to validate a property of a ListViewItem when the property is changed, if the ListView is binded to a ReadOnlyObservableCollection?如果 ListView 绑定到 ReadOnlyObservableCollection,如何在属性更改时验证 ListViewItem 的属性?
【发布时间】:2018-01-27 04:15:20
【问题描述】:

我有以下 VM 类:

public class SubModuleVM:INotifyPropertyChanged
{
       public event PropertyChangedEventHandler PropertyChanged;
       public string _name;
        public string Name
        {
            get { return_name; }
            set {
            _name = value; 
             PropertyChanged?.(this, new PropertyChangedEventArgs(nameof(Name)));
           }
        }
}


public class ProjectViewVM:INotifyPropertyChanged
{
   public ReadOnlyObservableCollection<SubModuleVM> SubModules
   {get;set;}
   public ProjectViewVM()
   {
           SubModules=LoadFromDatabase();  //loads from database
   }
   // snip irrelevant details
}

以及ProjectViewVM对应的XAML类:

  <ListView ItemsSource="{Binding SubModules}" SelectedItem="{Binding CurrentModule}" SelectionMode="Single">

        <ListView.ItemTemplate>
            <DataTemplate>
                <Grid>


                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="150" />
                    </Grid.ColumnDefinitions>
                    <TextBox Text="{Binding Name}" Grid.Column="0" Margin="0,0,5,0"/>                                                 
                </Grid>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

注意集合是ReadOnlyObservableCollection,不确定这是否会导致绑定问题

当用户在 UI 中从 ListView 更改 Name 时,我想验证以便 ProjectViewVM 内的所有 SubModuleVM.Name 都是唯一的。换句话说,我不允许在 SubModules 集合中重复 SubModuleVM.Name。如果用户将其重命名为已经存在的值,那么我希望触发验证事件(在 UI 级别)并通知用户这是不允许的,然后名称将恢复为旧名称。

我认为 ListView 应该有这样一个可用于捕获的验证事件,但到目前为止我找不到。

如何实现我的要求?

【问题讨论】:

  • 删除 ListView 中已使用的项目是否满足您在 UI 端的要求?此外,您可能需要考虑将非重复名称要求作为SubModules CRUD 操作的一部分。
  • @ShaiCohen,考虑将非重复名称要求作为子模块的一部分实现--你能说明如何做到吗?
  • 当然。我可以把一些伪代码放在一起。但是,如果您可以将当前的 CRUD 代码添加到您的问题中,我希望可以提供更相关的答案。
  • @ShaiCohen,我使用的是简单的ObservableCollection 列表,没有涉及数据库。无需去数据层面检查重名;如果可能,我想在 UI 级别进行检查。

标签: c# wpf xaml listview


【解决方案1】:

如您所述,在更新或编辑列表视图中的名称期间调用名称属性集时,请尝试调用类似于以下 sn-p 的逻辑:

private void Validate()
        {
            var query = SubModules.GroupBy(s => s.Name)
                                  .Select(s => new { Key = s.Key, Count = s.Count() });

            if(query.Any(a => a.Count > 1))
            {
                /* raise notification with some error message or use RasiePropertyChanged("InValid") 
                 * where InValid property in VM is bing to your XAML for indicating error*/
            }
        }

【讨论】:

  • 我应该把这个Validate方法放在哪里?
  • 不过,我并不太关注您的 VM 结构。验证可以在 ProjectViewVM 类中。所以准确地说,SubModule 应该有事件说 NameChanged。 ProjectViewVM 应该能够使用 Validate 方法注册此事件(例如在加载或初始化期间)。每当更改 name 属性时,您应该能够触发此事件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多