简体   繁体   English

WPF 在验证时使用触发器 XAML 标记覆盖自定义模板

[英]WPF override custom template using trigger XAML tag on validation

So I have a style for my TextBox as shown所以我的TextBox有一个样式,如图所示

        <Style TargetType="TextBox">
            <Setter Property="FontSize" Value="20">
            </Setter>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="TextBox">
                        <StackPanel>
                            <!-- ScrollViewer to restore the default textbox template that is gone because of 
                                us now overriding it -->
                            <Border CornerRadius="2" Padding="2" Background="White" BorderBrush="Black" BorderThickness="1">
                                <ScrollViewer Margin="0" x:Name="PART_ContentHost" Background="Gray" />
                            </Border>
                            <ItemsControl FontSize="10" ItemsSource="{TemplateBinding Validation.Errors}">
                                <ItemsControl.ItemTemplate>
                                    <DataTemplate>
                                        <TextBlock Foreground="Red" Text="{Binding Path=ErrorContent}"/>
                                    </DataTemplate>
                                </ItemsControl.ItemTemplate>
                            </ItemsControl>
                        </StackPanel>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <Style.Triggers>
                <Trigger Property="Validation.HasError" Value="True">
                    <Setter Property="Background" Value="Red"/>
                    <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self},
                        Path=(Validation.Errors)[0].ErrorContent}"/>
                </Trigger>
            </Style.Triggers>
        </Style>

When there is an error, I'd like the text box to show a red background, with the error messages appearing underneath it.当出现错误时,我希望文本框显示红色背景,并在其下方显示错误消息。 I've set up a trigger to change the TextBox's background when there's an error, but it seems that since I override the TextBox's normal template so that I can show the error messages, the background of the textbox itself doesn't change (it stays gray).我已经设置了一个触发器来在出现错误时更改文本框的背景,但似乎因为我覆盖了文本框的普通模板以便我可以显示错误消息,所以文本框本身的背景不会改变(它保持灰色的)。 I realize that this is because I used a ScrollViewer to restore the textbox appearance, but now how can I somehow refer to this ScrollViewer from my trigger?我意识到这是因为我使用了 ScrollViewer 来恢复文本框的外观,但现在我怎么能从我的触发器中以某种方式引用这个 ScrollViewer?

It's more for learning purposes.更多是出于学习目的。

You need to better use ControlTemplate.您需要更好地使用 ControlTemplate。 Possible example:可能的例子:

<Style TargetType="TextBox">
    <Setter Property="FontSize" Value="20"/>
    <Setter Property="Background" Value="Gray"/>
    <Setter Property="BorderBrush" Value="Black"/>
    <Setter Property="BorderThickness" Value="1"/>
    <Setter Property="Padding" Value="2"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="TextBox">
                <StackPanel>
                    <!-- ScrollViewer to restore the default textbox template that is gone because of 
                        us now overriding it -->
                    <Border x:Name="PART_Border" CornerRadius="2"
                            Padding="{TemplateBinding Padding}"
                            Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}">
                        <ScrollViewer Margin="0" x:Name="PART_ContentHost"/>
                    </Border>
                    <ItemsControl FontSize="10" ItemsSource="{TemplateBinding Validation.Errors}">
                        <ItemsControl.ItemTemplate>
                            <DataTemplate>
                                <TextBlock Foreground="Red" Text="{Binding Path=ErrorContent}"/>
                            </DataTemplate>
                        </ItemsControl.ItemTemplate>
                    </ItemsControl>
                </StackPanel>
                <ControlTemplate.Triggers>
                    <Trigger Property="Validation.HasError" Value="True">
                        <Setter TargetName="PART_Border" Property="Background" Value="Red"/>
                        <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self},
                            Path=(Validation.Errors)[0].ErrorContent}"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

but now how can I somehow refer to this ScrollViewer from my trigger?但现在我怎么能以某种方式从我的触发器中引用这个 ScrollViewer 呢?

Move the trigger from the Style to the ControlTemplate and use the TargetName property of the Setter to refer to the ScrollViewer or the parent Border element inside the template, eg:将触发器从Style移动到ControlTemplate并使用SetterTargetName属性来引用ScrollViewer或模板内的父Border元素,例如:

<ControlTemplate TargetType="TextBox">
    <StackPanel>
        <Border ...>
            <ScrollViewer Margin="0" x:Name="PART_ContentHost" Background="Gray" />
        </Border>
        <ItemsControl ... />
    </StackPanel>
    <ControlTemplate.Triggers>
        <Trigger Property="Validation.HasError" Value="True">
            <Setter TargetName="PART_ContentHost" Property="Background" Value="Red"/>
            ...
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM