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
;
}