【问题标题】:WPF DataGrid with textbox in template column not firing property changed模板列中带有文本框的 WPF DataGrid 未触发属性已更改
【发布时间】:2011-06-14 15:57:47
【问题描述】:

我有一个带有模板列的数据网格,该模板中有一个文本框。它绑定到构成 itemssource 的集合中对象的“数量”属性。数量是一个整数。当我将一个项目添加到数据网格时,我正在向该项目的 PropertyChanged 事件添加一个事件处理程序:

EnteredPart.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(p_PropertyChanged);

当用户在文本框中输入一个整数时,这可以正常工作...... p_PropertyChanged 处理程序会触发,我可以禁用按钮并根据需要更改数量。当用户输入一个非整数时,处理程序不会被调用,我只是在文本框周围得到一个红色轮廓。因此,我无法在需要时禁用必要的按钮(它们应该被禁用,数量不合法。)有什么办法可以解决这个问题吗?

编辑: 我尝试将 Quantity 属性更改为字符串,这导致在输入非整数值时调用属性更改处理程序。但是,我随后向文本框添加了验证以检查这一点,如果 Validate 方法返回 false,则再次停止命中属性更改处理程序。有没有办法同时获得验证和属性更改通知??

编辑 2: 这是我在另一个位置遇到的这个问题的另一个实例。我有一个用于添加/编辑电话号码的表格。电话号码文本框如下所示:

  <TextBox >
       <TextBox.Text>
           <Binding Path="Phone.Number">
               <Binding.ValidationRules>
                   <local:PhoneValidationRule />
               </Binding.ValidationRules>
           </Binding>
       </TextBox.Text>
   </TextBox>

点击保存按钮后,我需要检查我的视图模型是否有效,因为如果不是,我不想运行保存命令。但是,似乎没有任何方法可以做到这一点,因为如果验证失败,那么 Phone.Number 属性的值为 null,我无法检查是否应该运行 save 命令。我要么需要访问错误状态(我认为它可以通过 Validation.GetErrors 工作,但没有),要么需要访问文本框中的实际文本,这在视图模型中不可用。

【问题讨论】:

  • 您的 ItemsSourceObservableCollection 吗?如果您想在DataGrid 中使用PropertyChanged,您需要绑定到实现INotifyCollectionChanged 的集合,即。例如ObservableCollection
  • 是的,它是一个可观察的集合。正如我所说,当输入整数时,属性更改处理程序会正确触发。当我在绑定到整数属性的文本框中输入非整数时,它不会触发。验证错误模板出现,但“数量”属性没有改变。
  • 好吧,我想说这是完全正常的行为。您正在尝试将非 int 放入 int 字段中。如果验证失败,属性不会改变,只有在验证允许的情况下才会设置!
  • 那么可能让它像这样工作的唯一方法就是实现 IDataErrorInfo,对吧?真烦人。
  • 我无法真正理解您的问题。为这个确切的目的定义了验证规则:它们阻止您使用错误数据更新模型(即,如果您不允许更改属性,它们不会让您触发任何 PropertyChanged)。为什么你需要这个 PropertyChanged 被解雇?

标签: wpf validation datagrid propertychanged


【解决方案1】:

仅作记录,如果您在 MVVM 架构中,在 View 部分中的验证有很多缺点。

您可以尝试在视图中检查模型的内容:因此,您会通过在视图中调用模型来破坏 MVVM 的架构。

使用IDataErrorInfo 将帮助您实现 MVVM 的主要目标(即明确区分三个部分)。

只是一个例子:

我认为您在这里只是执行了一个非常小的验证(只需检查它是否为 int)。 但是在不同的环境中,假设您的模型要复杂得多,需要更深入的验证。使用IDataErrorInfo 将帮助您深入检查模型,而无需从视图中调用它。 事实上,根据我的个人经验,由于我经常处理大型且高度相关的数据集,我什至无法在没有IDataErrorInfo 的情况下使用验证,因为在所有提供的数据中进行调查并发现潜力会花费我太多成本错误

【讨论】:

  • 我想你是对的。 WPF 让我烦恼的是,我觉得我所做的一切都太过分了……因为它需要额外的 45 分钟的编码才能做任何事情。仅检查“文本是否为 int 且大于 0”涉及实现接口、连接 XAML 代码中的绑定更改以及向视图模型添加检查逻辑。去年我会在代码隐藏中添加一个 textbox.text 检查并在 10 分钟内完成。感觉就像是向后移动。也许真正的问题是带有 MVVM 的 WPF 不是我的应用程序的正确选择,我不知道。
  • 自从我知道,我一直对 WPF 有一种感觉:它通常使非常困难的事情变得非常容易,而非常简单的事情变得非常棘手。例如,DataGrid 非常棒,使用绑定列表并让 WPF 处理所有显示过程更容易!但是,正如您所说,我遇到了一些非常琐碎的问题,最终花了一整天的时间来解决它们……有时我看到人们为非常基本的操作实现了大量的代码(即一个常见问题:为...鼠标双击。杀了我。)
  • 也许我对 WPF 有点不公平……也许是 MVVM 模式有问题。例如,就我而言,WPF 中没有任何东西可以阻止我在代码隐藏中添加我需要的检查。如果我这样做,就会破坏 MVVM 模式。它只是强化了我的想法,即很大一部分设计模式是在浪费时间,而“时间”实际上就是它的全部含义。我根本不相信这可能为我节省的维护时间会接近我在开发中花费的时间。甚至没有关闭。
  • 好吧,我认为你可能错了。 MVVM 中唯一禁止的事情是在代码隐藏中处理数据操作。感谢绑定,您可以在 ViewModel 中处理它们,就像在代码隐藏中一样容易。因此,它通常与经典的代码隐藏方法一样简单,而且更加清晰(我最近不得不重新创建一个完整的 GUI……花了我 30 分钟才使它工作。)说到重构,我认真地认为没有比 MVVM 更好的处理方式了,它可以帮助你只重构需要的部分而不影响其他部分
  • 我明白你对代码隐藏的看法,但我的意思是,如果我想在代码隐藏中验证某些内容,除非我也在视图模型中执行某些操作,否则它是没有用的。这不是世界末日,但绝对没有那么容易。我当然会争辩说它不太清楚,老实说,我看不出 MVVM 重构比旧的 n 层重构更好。我认为我在修改被分成几层的面向对象代码时从来没有遇到过问题。我感觉好像我正在尝试修复一些从未损坏过的东西,只是为了使用新的“设计模式”。
猜你喜欢
  • 2012-11-04
  • 1970-01-01
  • 1970-01-01
  • 2013-06-04
  • 1970-01-01
  • 2018-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多