CodeGo.net>在WPF中同时验证多个控件
作者:互联网
我有一个包含两个密码字段的表单-一个用户输入密码的字段,另一个用户必须重新输入密码进行确认的表单.验证用于确认两个密码是否匹配-如果匹配,则启用按钮以允许用户继续:
<PasswordBox Name="P1Box" src:PasswordBoxAssistant.BindPassword="True">
<src:PasswordBoxAssistant.BoundPassword>
<Binding Source="{StaticResource mybinding}" Path="Password.P1" UpdateSourceTrigger="PropertyChanged" Mode="TwoWay">
<Binding.ValidationRules>
<DataErrorValidationRule ValidatesOnTargetUpdated="True"/>
</Binding.ValidationRules>
</Binding>
</src:PasswordBoxAssistant.BoundPassword>
</PasswordBox>
按钮样式:
<Setter Property="IsEnabled" Value="False"/>
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding ElementName=P1Box, Path=(Validation.HasError)}" Value="false"/>
</MultiDataTrigger.Conditions>
<Setter Property="IsEnabled" Value="true"/>
</MultiDataTrigger>
</Style.Triggers>
我的问题是用户可以更改第一个密码框中的密码,而不会强制第二个密码框中重新进行验证.例如,如果第一个密码输入为“ password”,而用户在第二个框中输入“ password”,则验证通过并启用按钮.如果用户然后将原始密码框更改为“ PASSWORD”,则两个框都保持有效状态-原始框是因为对非空密码没有任何限制,第二个原因是没有任何内容强制更新验证.
我的密码框使用概述的属性here允许绑定到密码.因此,我找不到以this solution.中表示的方式在代码隐藏中访问它的方法(因为PasswordBox.Password本身不是依赖项属性),或者也许它不适用于附加属性-以下代码没有执行任何操作:
P2Box.GetBindingExpression(PasswordBoxAssistant.BoundPassword).UpdateSource();
我有一个自定义类,该类继承了IDataErrorInfo以允许在两个控件之间进行验证-绑定是一个PasswordData对象,并且密码框设置为PasswordData.P1和PasswordData.P2:
public class PasswordData : IDataErrorInfo
{
public string P1 { get; set; }
public string P2 { get; set; }
public string Error { get { return string.Empty; } }
public string this[string propertyName]
{
get
{
string ret;
if (propertyName == "P1")
{
if (P1 == null || P1 == "")
ret = "Password cannot be null or empty.";
else
ret = "";
}
else if (propertyName == "P2")
{
if (P2 == null || P2 == "")
ret = "Password cannot be null or empty.";
else if (P2 != P1)
ret = "The passwords do not match.";
else
ret = "";
}
return ret;
}
}
}
我尝试在PasswordChanged事件期间跳入,创建新的PasswordData,然后重新分配绑定.这解决了验证问题,但是密码框中的插入符号始终处于最开始,从而破坏了输入的任何数据.
我想要一个仅xaml的解决方案,但是后面的代码是完全可以接受的.我正在使用.Net 4.0,如果那很重要的话.
编辑:
OK,事实证明我在xaml中输入了错误的事件处理程序,该解决方案实际上有效:
private void PasswordChanged(object sender, RoutedEventArgs e)
{
binding.Pass.P1 = ((PasswordBox)sender).Password;
P2Box.GetBindingExpression(PasswordBoxAssistant.BoundPassword).UpdateSource();
}
我必须手动更新绑定,因为在绑定更新之前会触发该事件.
我很好奇是否存在使用验证规则,IDataErrorInfo或其他某种方法在控件之间进行绑定而无需陷入事件并手动更新的正确,仅XAML方式.
解决方法:
对于更复杂的验证,通常有必要将验证推入ViewModel甚至在很多情况下都推入Model中. IDataErrorInfo是一个好的开始.
这是有关该主题的出色文章的链接:
http://msdn.microsoft.com/en-us/magazine/ff714593.aspx
标签:validation,passwords,wpf,c,mvvm 来源: https://codeday.me/bug/20191201/2078356.html