WPF嵌套绑定在controltemplate中

kar*_*ins 4 wpf xaml binding templates templatebinding

我已经成功创建了一个文本框,根据模型/ 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>
Run Code Online (Sandbox Code Playgroud)

由于我有很多这些,我本来希望将所有这些放在一个控制模板中,并将其重新定位在一个公共资源文件中.

我的模板看起来像这样:

<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>
Run Code Online (Sandbox Code Playgroud)

我这样链接到它:

    <TextBox Grid.Row="3" Grid.Column="1" MaxLength="200" Template="{StaticResource FormTextBox}"
             Text="{Binding Email, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" />
Run Code Online (Sandbox Code Playgroud)

不幸的是,它没有执行任何验证,因此必须以某种方式破坏绑定...

请指教...

谢谢.

Fre*_*lad 5

你不需要模板StackPanel中的Grid.RowGrid.Column绑定,因为它StackPanel不会是一个直接的孩子Grid,

TemplateBinding始终是一个OneWay绑定,因此Text模板化的属性TextBox永远不会更新.使用RelativeSource和将其更改为常规绑定TwoWay

更改ElementName=validableTextRelativeSource={RelativeSource TemplatedParent}绑定,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>
Run Code Online (Sandbox Code Playgroud)

在旁注中,您在此处拥有的另一个选择是使用您拥有UserControl的原始Xaml 创建一个.您可以引入场景所需的依赖项属性(文本等).它只需要很小的改变.