2011-08-17 107 views
4

我已成功创建了一个文本框,显示/折叠错误消息,具体取决于模型/ vm中设置的验证规则。该代码是这样的电子邮件例: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}" /> 

不幸的是,它不执行任何验证所以必须以某种方式打破了绑定..

请指教...

谢谢。

回答

5

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

TemplateBinding总是OneWay为模板化的结合使Text财产TextBox将永远不会更新。因为我们要在模板化TextBox而不是TextBox在模板中进行验证检查它RelativeSourceTwoWay

变化在绑定ContentPresenterElementName=validableTextRelativeSource={RelativeSource TemplatedParent}更改为普通约束力。

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

在一个侧面说明,另一种选择,你在这里是创建一个UserControl与原片的XAML你了。您可以引入您的方案所需的依赖项属性(文本等)。它只需要很小的改动。

+0

非常感谢!有一个小小的边界pb,就像你的代码一样,adorner将围绕整个stackpanel,但是我能够理解绑定是如何工作的,并且能够让我的验证完美工作! – karlipoppins