繁体   English   中英

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

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

所以我的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>

当出现错误时,我希望文本框显示红色背景,并在其下方显示错误消息。 我已经设置了一个触发器来在出现错误时更改文本框的背景,但似乎因为我覆盖了文本框的普通模板以便我可以显示错误消息,所以文本框本身的背景不会改变(它保持灰色的)。 我意识到这是因为我使用了 ScrollViewer 来恢复文本框的外观,但现在我怎么能从我的触发器中以某种方式引用这个 ScrollViewer?

更多是出于学习目的。

您需要更好地使用 ControlTemplate。 可能的例子:

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

但现在我怎么能以某种方式从我的触发器中引用这个 ScrollViewer 呢?

将触发器从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