WPF 控件模板中的嵌套绑定
我已经成功创建了一个文本框,该文本框根据其模型/虚拟机中设置的验证规则显示/折叠错误消息。例如,电子邮件的代码如下所示:
<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}" />
不幸的是,它不执行任何验证,因此绑定必须以某种方式被破坏...
请告知...
谢谢。
I have successfully created a textbox that displays / collapses an error message depending upon a validation rule set in its model / vm. The code goes like this for the email for ex.:
<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>
Since I have a bunch of these, I would have liked to put all of this in a control template and relocate this in a common resource file.
My template looks like this:
<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>
and I link to it like this:
<TextBox Grid.Row="3" Grid.Column="1" MaxLength="200" Template="{StaticResource FormTextBox}"
Text="{Binding Email, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" />
Unfortunately, it doesn't perform any validation so the binding must be broken somehow...
Please advise...
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您不需要模板 StackPanel 中的
Grid.Row
和Grid.Column
绑定,因为StackPanel
不会是无论如何,TemplateBinding 始终是
OneWay
绑定,因此模板化TextBox< 的
Text
属性/code> 永远不会更新。将其更改为使用RelativeSource
和TwoWay
的常规绑定将
ElementName=validableText
更改为RelativeSource={RelativeSource TemplatedParent}
ContentPresenter
的绑定,因为我们要对模板化TextBox
而不是模板内的TextBox
执行验证检查。顺便说一下,这里的另一种选择是使用您拥有的原始 Xaml 片段创建一个
UserControl
。您可以引入您的场景所需的依赖属性(文本等)。只需要进行一些小的更改。You won't need the
Grid.Row
andGrid.Column
bindings in the Template StackPanel since theStackPanel
won't be the direct child of aGrid
anyway,TemplateBinding
is always aOneWay
binding so theText
property for the TemplatedTextBox
will never get updated. Change it to a regular Binding withRelativeSource
andTwoWay
Change
ElementName=validableText
toRelativeSource={RelativeSource TemplatedParent}
in the bindings forContentPresenter
since we want to perform the validation check on the TemplatedTextBox
and not theTextBox
inside the Template.On a side note, another alternative that you have here is to create a
UserControl
with the original piece of Xaml that you had. You could introduce the Dependency Properties needed for your scenario (Text etc.). It would only require small changes.