我已经成功创建了一个文本框,根据模型/ vm中设置的验证规则显示/折叠错误消息。对于例如:
的电子邮件,代码如下所示 <StackPanel Grid.Row="3" Grid.Column="1">
<TextBox MaxLength="200" x:Name="mailTextBox"
Style="{StaticResource SectionEditPropertyTextBox}"
Text="{Binding Email, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" />
<ContentPresenter Visibility="{Binding ElementName=mailTextBox, Path=(Validation.HasError), Converter={StaticResource BooleanToVisibilityConverter}, ConverterParameter=True }"
Content="{Binding ElementName=mailTextBox, Path=(Validation.Errors).CurrentItem}"
HorizontalAlignment="Left">
<ContentPresenter.ContentTemplate>
<DataTemplate>
<Label Style="{StaticResource SectionEditErrorLabel}" Content="{Binding Path=ErrorContent}"/>
</DataTemplate>
</ContentPresenter.ContentTemplate>
</ContentPresenter>
</StackPanel>
由于我有很多这些,我本来希望将所有这些放在一个控制模板中,并将其重新定位在一个公共资源文件中。
我的模板如下所示:
<ControlTemplate x:Key="FormTextBox" TargetType="{x:Type TextBox}">
<StackPanel Grid.Row="{TemplateBinding Grid.Row}" Grid.Column="{TemplateBinding Grid.Column}">
<TextBox x:Name="validableText" MaxLength="{TemplateBinding MaxLength}"
Style="{StaticResource SectionEditPropertyTextBox}"
Text="{TemplateBinding Text}" />
<ContentPresenter Visibility="{Binding ElementName=validableText, Path=(Validation.HasError), Converter={StaticResource BooleanToVisibilityConverter}, ConverterParameter=True }"
Content="{Binding ElementName=validableText, Path=(Validation.Errors).CurrentItem}"
HorizontalAlignment="Left">
<ContentPresenter.ContentTemplate>
<DataTemplate>
<Label Style="{StaticResource SectionEditErrorLabel}" Content="{Binding Path=ErrorContent}"/>
</DataTemplate>
</ContentPresenter.ContentTemplate>
</ContentPresenter>
</StackPanel>
</ControlTemplate>
我这样链接到它:
<TextBox Grid.Row="3" Grid.Column="1" MaxLength="200" Template="{StaticResource FormTextBox}"
Text="{Binding Email, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" />
不幸的是,它没有执行任何验证,因此必须以某种方式破坏绑定......
请告知......
感谢。
答案 0 :(得分:5)
您不需要模板StackPanel中的Grid.Row
和Grid.Column
绑定,因为StackPanel
不会是Grid
的直接子节点,
TemplateBinding
始终是OneWay
绑定,因此模板化Text
的{{1}}属性永远不会更新。使用TextBox
和RelativeSource
在TwoWay
的绑定中将ElementName=validableText
更改为RelativeSource={RelativeSource TemplatedParent}
,因为我们要对Templated ContentPresenter
而不是TextBox
内的TextBox
执行验证检查模板。
<ControlTemplate x:Key="FormTextBox" TargetType="{x:Type TextBox}">
<StackPanel>
<TextBox x:Name="validableText"
MaxLength="{TemplateBinding MaxLength}"
Style="{StaticResource SectionEditPropertyTextBox}"
Text="{Binding RelativeSource={RelativeSource TemplatedParent},
Path=Text,
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}" />
<ContentPresenter Visibility="{Binding RelativeSource={RelativeSource TemplatedParent},
Path=(Validation.HasError),
Converter={StaticResource BooleanToVisibilityConverter}
ConverterParameter=True}"
Content="{Binding RelativeSource={RelativeSource TemplatedParent},
Path=(Validation.Errors).CurrentItem}"
HorizontalAlignment="Left">
<ContentPresenter.ContentTemplate>
<DataTemplate>
<Label Style="{StaticResource SectionEditErrorLabel}" Content="{Binding Path=ErrorContent}"/>
</DataTemplate>
</ContentPresenter.ContentTemplate>
</ContentPresenter>
</StackPanel>
</ControlTemplate>
在旁注中,您在此处拥有的另一个选择是使用您拥有的原始Xaml创建UserControl
。您可以引入场景所需的依赖项属性(文本等)。它只需要很小的改动。