【发布时间】:2020-08-28 14:24:13
【问题描述】:
我在尝试将 INotifyPropertyChanged 与 WPF 中的验证一起使用时遇到了一点麻烦。基本上,我希望 TextBox 警告用户有关空字段并更新(使用绑定)XAML 后面代码中的值。
几乎一切工作都很好,唯一的问题是,例如,我在文本框中键入字符串“Hello World”,然后删除所有内容。后面的代码不会在删除的最后一个字符上更新,而是保留值“H”,而不是空字符串。
我的短代码如下:
UserControlClientes.xaml
<TextBox x:Name="NomeTextBox" CharacterCasing="Upper" HorizontalAlignment="Stretch" VerticalAlignment="Top">
<TextBox.Text>
<Binding Path="Nome" TargetNullValue="''" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<domain1:RequiredField ValidatesOnTargetUpdated="True" />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
(“domain1”已定义并引用RequiredField.cs所在的文件夹)
UserControlClientes.xaml.cs
public class Dados_Administrativos: INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string _Nome;
public string Nome
{
get { return _Nome; }
set
{
_Nome = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("Nome"));
}
}
}
}
public UserControlClientes()
{
InitializeComponent();
Cliente ClienteBind = new Cliente();
DataContext = ClienteBind;
}
RequiredField.cs
public class RequiredField: ValidationRule
{
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
return string.IsNullOrWhiteSpace((value ?? "").ToString())
? new ValidationResult(false, "Required field")
: ValidationResult.ValidResult;
}
}
我是 WPF 新手,所以我这样做的方式是否正确?我该如何解决这个问题?
【问题讨论】:
-
作为一般说明,UserControl 永远不应在其 DataContext 中拥有自己的私有视图模型。这种私有视图模型不能从控件外部访问,因此不能成为应用程序范围的视图模型结构的一部分。只是不要显式设置控件的 DataContext,而是传递一个“外部”视图模型对象,例如通过
<local:UserControlClientes DataContext="{Binding ClientsViewModel}"/>。或者通过类似地绑定在其 ContentTemplate 中具有控件的 ContentControl 的内容。 -
您对这种行为有何期望?它应该如何表现?您的验证规则确保文本不为空,因此当您逐个删除每个字符时,在框为空之前剩余的最后一个字符仍然有效。之后该框为空并且验证规则失败,因此不会更新源。从您显示的行为来看,它按预期工作。
-
@Clemens 谢谢你的提示,我会这样做的。
-
@thatguy 我期待即使验证规则失败,源也会更新(为空)。但是,按照你所说的,我想这不是验证的工作方式,对吧?无论如何我可以验证文本框是否为空(来自主代码)?
-
@Clemens 我在执行您所说的操作时遇到了问题。我只需要在父级(在我的情况下是一个窗口)上声明 DataContext,子级(UserControl)将收到相同的 DataContext?在 xaml 或构造函数中声明数据上下文的正确方法是什么?