模板列中文本框未触发的WPF DataGrid属性已更改

模板列中文本框未触发的WPF DataGrid属性已更改,wpf,validation,datagrid,propertychanged,Wpf,Validation,Datagrid,Propertychanged,我有一个带有模板列的datagrid,该模板中有一个文本框。它绑定到组成itemssource的集合中对象的“Quantity”属性。数量是一个整数。将项添加到datagrid时,我正在将事件处理程序添加到该项的PropertyChanged事件: EnteredPart.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(p_PropertyChanged); 当用户在文本框中输入一个整数时,此操作

我有一个带有模板列的datagrid,该模板中有一个文本框。它绑定到组成itemssource的集合中对象的“Quantity”属性。数量是一个整数。将项添加到datagrid时,我正在将事件处理程序添加到该项的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>

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

请注意,如果您在MVVM体系结构中,视图部分的验证有许多缺点

您可以尝试在视图中检查模型的内容:因此,您可以通过在视图中调用模型来打破MVVM的体系结构

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

举个例子:

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

您的项目是否可供观察?如果要在数据网格中使用PropertyChanged,则需要绑定到实现INotifyCollectionChanged的集合,例如,ObservableCollectionYes,它是一个observablecollection。正如我所说的,当输入整数时,属性更改处理程序将正确激发。当我在绑定到integer属性的文本框中输入一个非整数时,它不会触发。验证错误模板出现了,但是quantity属性没有改变。我认为这是完全正常的行为。您试图在int字段中放入非int。如果验证失败,属性将不会更改,只有在验证允许的情况下才会设置它!那么让它像这样工作的唯一方法就是实现IDataErrorInfo,对吗?真烦人。我真的不明白你这里的问题。验证规则的定义正是为了这个目的:它们阻止您使用坏数据更新模型,即,如果不允许您更改属性,它们将不允许您触发任何PropertyChanged。你到底为什么要把这房子换了才被解雇?我想你是对的。WPF让我恼火的是,我觉得我做的每件事都过于劳累。。。因为做任何事情都需要额外45分钟的编码时间。仅检查“text为int且大于0”就需要实现一个接口,连接XAML代码中的绑定更改,并向viewmodel添加检查逻辑。去年我会在codebehind中添加一个textbox.text检查,并在10分钟内完成。感觉像是向后移动。也许真正的问题是,带MVVM的WPF不是我的应用程序的正确选择,我不知道。只要我知道,我对WPF总是有一种感觉:它通常使非常困难的事情变得非常容易,而非常简单的事情变得非常棘手。例如,DataGrid非常棒,使用绑定列表并让WPF处理所有显示过程非常容易!然而正如你所说,我有一些非常重要的想法
最后花了一整天的时间来解决这些问题。。。有时我看到人们为非常基本的操作实现了数量惊人的代码,也就是说,一个常见的问题是:为。。。鼠舔。杀了我,也许我对WPF有点不公平。。。也许是MVVM模式的错。例如,在我的例子中,WPF中的任何内容都不能阻止我在codebehind中添加所需的检查。如果我这样做,MVVM模式就会崩溃。它只是强化了我的观点,即很大一部分设计模式都是浪费时间,而“时间”实际上就是一切归结起来的原因。我只是不相信这可能为我节省的维护时间可以接近我在开发中花费的时间。甚至不接近。好吧,我认为你可能错了。MVVM中唯一禁止的事情是在代码隐藏中处理数据操作。由于绑定,您可以在ViewModel中轻松地处理它们,就像在代码隐藏中一样。因此,它通常和经典的代码隐藏方法一样简单,而且更清楚的是,我最近不得不重新创建一个完整的GUI。。。我花了30分钟才完成。说到重构,我认真地认为没有比MVVM更好的处理方法了,它可以帮助您只重构所需的部分而不影响其他部分。我明白您对代码隐藏的看法,但我的观点是,如果我想在代码隐藏中验证某些内容,除非我在viewmodel中也做了一些操作,否则它是无用的。这不是世界末日,但绝对不是那么容易。我当然会说,这还不太清楚,而且我真的不知道MVVM重构如何比旧的n层重构更好。我认为我从来没有遇到过修改分为层的面向对象代码的问题。我觉得好像我在试图修复一些从未损坏过的东西,只是为了使用新的设计模式。