自定义ErrorTemplate关闭屏幕显示错误

时间:2016-09-27 21:42:22

标签: c# wpf xaml

我正在研究WPF应用程序,并且我已经为所有文本框添加了自定义错误模板。我的应用程序以全屏模式运行。该错误显示在停靠在控件右侧的DockPanel(AdornedElementPlaceholder)中。但是,如果控件已经位于屏幕的右侧,则会导致错误显示在应用程序的边界之外。

我正在寻找一种方法来检查ErrorBorder的最右上角/下角是否超出了应用程序的范围。如果是,则从右向左更改对接。我正在考虑在ErrorBorder控件上使用各种转换器。这是我的ErrorTemplate代码。

错误模板:

<ControlTemplate x:Key="CustomErrorTemplate">
    <DockPanel>
        <!--ERROR-->
        <Border x:Name="ErrorBorder"
                Background="Red"
                BorderBrush="Black"
                BorderThickness="1"
                DockPanel.Dock="Right"
                Margin="5 0"
                Height="{Binding ActualHeight,
                                 ElementName=ErrorAdorner}">
            <TextBlock Background="Red"
                       Foreground="White"
                       VerticalAlignment="Center"
                       FontSize="{Binding ActualHeight,
                                          Converter={StaticResource FontSizeConverter},
                                          RelativeSource={RelativeSource AncestorType={x:Type Border},
                                                                         Mode=FindAncestor}}"
                       Text="{Binding ElementName=ErrorAdorner,
                                      Path=AdornedElement.(Validation.Errors).CurrentItem.ErrorContent}"/>
        </Border>
        <!--CONTENT-->
        <AdornedElementPlaceholder x:Name="ErrorAdorner" />
    </DockPanel>
    <ControlTemplate.Triggers>
        <DataTrigger Value="True">
            <DataTrigger.Binding>
                <MultiBinding Converter="{StaticResource BooleanToOrConverter}">
                    <Binding ElementName="ErrorAdorner" Path="AdornedElement.IsKeyboardFocused" />
                    <Binding ElementName="ErrorAdorner" Path="AdornedElement.IsMouseOver" />
                </MultiBinding>
            </DataTrigger.Binding>
            <DataTrigger.EnterActions>
                <BeginStoryboard x:Name="FadeInStoryboard">
                    <Storyboard>
                        <DoubleAnimation Duration="00:00:00.15"
                                         Storyboard.TargetName="ErrorBorder"
                                         Storyboard.TargetProperty="Opacity"
                                         To="1" />
                        <ThicknessAnimation Duration="00:00:00.15"
                                            Storyboard.TargetName="ErrorBorder"
                                            Storyboard.TargetProperty="Margin"
                                            FillBehavior="HoldEnd"
                                            From="1,0,0,0"
                                            To="5,0,0,0">
                            <ThicknessAnimation.EasingFunction>
                                <BackEase EasingMode="EaseOut" Amplitude="2"/>
                            </ThicknessAnimation.EasingFunction>
                        </ThicknessAnimation>
                    </Storyboard>
                </BeginStoryboard>
            </DataTrigger.EnterActions>
            <DataTrigger.ExitActions>
                <StopStoryboard BeginStoryboardName="FadeInStoryboard"/>
                <BeginStoryboard x:Name="FadeOutStoryBoard">
                    <Storyboard>
                        <DoubleAnimation Duration="00:00:00"
                                         Storyboard.TargetName="ErrorBorder"
                                         Storyboard.TargetProperty="Opacity"
                                         To="0"/>
                    </Storyboard>
                </BeginStoryboard>
            </DataTrigger.ExitActions>
        </DataTrigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

注意:我正在为我的应用程序中的各种控件使用相同的错误模板。所以我的目标需要与“任何”控制一起工作。

此外,这是我如何为所有TextBox控件实现我的错误模板。

TextBox样式:

<Style TargetType="{x:Type TextBox}">
<Setter Property="Validation.ErrorTemplate" Value="{StaticResource CustomErrorTemplate}" />
<Style.Triggers>
    <Trigger Property="Validation.HasError" Value="True">
        <Setter Property="BorderBrush" Value="Red" />
        <Setter Property="BorderThickness" Value="2" />
        <Setter Property="Background">
            <Setter.Value>
                <SolidColorBrush Color="Pink" />
            </Setter.Value>
        </Setter>
    </Trigger>
</Style.Triggers>

非常感谢任何指导。

1 个答案:

答案 0 :(得分:1)

简单方法

对于这个特殊情况

在其DockPanel.Dock = Left中设置ErrorBorder,再创建一个ErrorTemplate。在MinWidth=200。{/ p>中设置一些DockPanel

处理Validation.Error="Tb_Error_1"中的TextBox,并在NotifyOnValidationError="True"中设置Binding

    private void Tb_Error_1(object sender, ValidationErrorEventArgs e)
    {
        ControlTemplate template = this.Resources["LeftCustomErrorTemplate"] as ControlTemplate;
        double minWidth = 200; // This we set in DockPanel in ControlTemplate

        Vector tbofset = VisualTreeHelper.GetOffset(sender as TextBox);

        if (tbofset.Length + minWidth > this.ActualWidth - tbofset.X)
            Validation.SetErrorTemplate(Tb, this.Resources["LeftCustomErrorTemplate"] as ControlTemplate);
        else
            Validation.SetErrorTemplate(Tb, this.Resources["CustomErrorTemplate"] as ControlTemplate);
    }

最好使用ToolTip

使用ToolTip。这是因为CustomPopupPlacementCallback,它允许您指定各种展示位置数组,框架决定哪一个为您的ToolTip提供最佳可见性。

ToolTip重新调整自身,始终始终显示完全可见。

How to: Specify a Custom Popup Position ?