wpf中有validateRule类, 用于界面元素的验证, 如何后台去控制validateRule呢?
1. UI层要binding写好的ValidateRule,分为Binding和MultiBinding, 如下面分别实现了Combobox的SelectedValuePropperty的Binding
和TextBox的TextProperty的MultiBinding。其中都有ValidationRule。
<ComboBox x:Name="cmbAgeType" Margin="3"
SelectionChanged="cmbAgeType_SelectionChanged" Background="#00000000" BorderBrush="Black" Grid.Row="4" MinWidth="0" Grid.Column="2" IsTabStop="False" SelectedIndex="0" d:LayoutOverrides="GridBox" Tag="PatientAge"
Visibility="{Binding DataContext, ElementName=window, Converter={StaticResource KeyToVisibilityConverter}, ConverterParameter=PatientAge}">
<ComboBox.SelectedValue>
<Binding Path="PatientAge" Converter="{StaticResource AgeMeasureConverter}" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<McsfPAFEContainee_ValidationRules:EmptyValidationRule ValidatesOnTargetUpdated="True" ValidationStep="ConvertedProposedValue"/>
</Binding.ValidationRules>
</Binding>
</ComboBox.SelectedValue>
<!--<Binding Path="PatientAge" Converter="" UpdateSourceTrigger="PropertyChanged"/>-->
</ComboBox>
<TextBox x:Name="txtPatientWeight" TextWrapping="Wrap" Margin="3" MaxLength="10" TabIndex="6" BorderBrush="Black" Grid.Row="5" Grid.Column="1" Height="22" MinWidth="42" Tag="PatientWeight"
Visibility="{Binding DataContext, ElementName=window, Converter={StaticResource KeyToVisibilityConverter}, ConverterParameter=PatientWeight}">
<TextBox.Text>
<MultiBinding Mode="TwoWay" Converter="{StaticResource WeightConverter}" UpdateSourceTrigger="PropertyChanged">
<MultiBinding.ValidationRules>
<McsfPAFEContainee_ValidationRules:WeightValidationRule ValidatesOnTargetUpdated="True" ValidationStep="ConvertedProposedValue"/>
</MultiBinding.ValidationRules>
<Binding Path="PatientWeight"/>
<Binding Path="IsChecked" ElementName="rdoKg"/>
</MultiBinding>
</TextBox.Text>
<i:Interaction.Behaviors>
<McsfPAFEContainee_Behaviors:NumericTextBoxBehavior MinValue="0" MaxValue="300" />
</i:Interaction.Behaviors>
</TextBox>
2. 后台主动触发ValidationRule的验证。 以下方法根据上面的Binding, 分别去取Binding和MultiBinding, 然后调用UpdateSource。
private bool ValidateInput(object child, PRCfgViewModel vm, bool isUpdateSource, bool isEmergency)
{
BindingExpression be = null;
MultiBindingExpression mbe = null;
if (child is TextBox)
{
be = (child as TextBox).GetBindingExpression(TextBox.TextProperty);
if (null == be)
{
mbe = BindingOperations.GetMultiBindingExpression((child as TextBox), TextBox.TextProperty);
}
}
else if (child is DatePicker)
{
be = (child as DatePicker).GetBindingExpression(DatePicker.TextProperty);
if (null == be)
{
mbe = BindingOperations.GetMultiBindingExpression((child as DatePicker), DatePicker.TextProperty);
}
}
else if (child is ComboBox)
{
be = (child as ComboBox).GetBindingExpression(ComboBox.SelectedValueProperty);
if (null == be)
{
mbe = BindingOperations.GetMultiBindingExpression((child as ComboBox), ComboBox.SelectedValueProperty);
}
}
if (null == be && null == mbe)
{
return false;
}
ValidationRule vr = null;
if (null != be && be.ParentBinding.ValidationRules.Count > 0)
{
vr = be.ParentBinding.ValidationRules[0];
}
else if (null != mbe && mbe.ParentMultiBinding.ValidationRules.Count > 0)
{
vr = mbe.ParentMultiBinding.ValidationRules[0];
}
else
{
return false;
}
string bindingPath = "";
if (null != be)
{
bindingPath = be.ParentBinding.Path.Path;
}
else if (null != mbe)
{
Binding bd = mbe.ParentMultiBinding.Bindings[0] as Binding;
bindingPath = bd.Path.Path;
}
bindingPath = bindingPath.Replace(".", "_");
if (vm.Setting.CfgInfo[bindingPath] != null)
{
(vr as BaseValidationRule).IsActive = !isEmergency;
if ((vr as BaseValidationRule).IsActive)
{
(vr as BaseValidationRule).IsAllowEmpty = !(vm.Setting.CfgInfo[bindingPath].IsKeyword);
}
else
{
if (isUpdateSource)
{
if (null != be)
{
be.UpdateSource();
}
else if (null != mbe)
{
mbe.UpdateSource();
}
}
return true;
}
}
else
{
(vr as BaseValidationRule).IsAllowEmpty = true;
}
if (isUpdateSource)
{
if (null != be)
{
be.UpdateSource();
}
else if (null != mbe)
{
mbe.UpdateSource();
}
}
return true;
}