Отображение ошибок, контроль после перемещения вниз - PullRequest
2 голосов
/ 12 ноября 2010

Таким образом, я пытаюсь отобразить сообщение, когда ввод неверен, предположим, что я хочу что-то, кроме ToolTip, что-то, что остается до исправления ошибки.Я пытался получить ErrorTemplate

<Style TargetType="{x:Type TextBox}">
    <Setter Property="Validation.ErrorTemplate">
        <Setter.Value>
            <ControlTemplate>
                <StackPanel>
                    <Border BorderBrush="Red" BorderThickness="1">
                        <AdornedElementPlaceholder x:Name="adornedErrorElement" />
                    </Border>
                    <Label Background="Red" Foreground="White" FontSize="9" Content="{Binding ElementName=adornedErrorElement, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}" />
                </StackPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

<StackPanel Margin="20">
    <TextBlock Text="Name" />
    <TextBox Text="{Binding Name}" />

    <TextBlock Text="Email" />
    <TextBox Text="{Binding Path=Email, ValidatesOnDataErrors=True}" />

    <Button Content="Submit" />
</StackPanel>

Я получаю

alt text

, где метка накладывается на элементы после нее.Как сделать так, чтобы он работал так же, как другой элемент в панели стека?

ОБНОВЛЕНИЕ: Использование VSM

Теперь я хочу сделать еще один шаг и анимировать метку ошибки ивниз.Я рассматриваю VSM после ответа @robertos.Я попытался реализовать в Blend.Несколько проблем, с которыми я столкнулся.Я попытался

<ControlTemplate TargetType="{x:Type TextBox}">
    <StackPanel Orientation="Vertical">
        <Microsoft_Windows_Themes:ListBoxChrome ...>
        <VisualStateManager.VisualStateGroups>
                ...
        </VisualStateManager.VisualStateGroups>
        <ScrollViewer ... />
        </Microsoft_Windows_Themes:ListBoxChrome>
        <Label Content="Error Here" />
    </StackPanel>
</ControlTemplate>

Затем я потерял доступ к VisualStates в Blend.Затем я попытался

<Microsoft_Windows_Themes:ListBoxChrome>
    <StackPanel>
        <ScrollViewer x:Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Margin="2,0,-2,0"/>
    <TextBlock x:Name="textBlock" Background="Red" Foreground="White" FontWeight="Bold" Text="Hello" Visibility="Collapsed" />
    </StackPanel>
</Microsoft_Windows_Themes:ListBoxChrome>

Не идеально, так как StackPanel находится внутри границы.Также мои попытки анимации выглядят просто странно

http://screenr.com/byk

http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,115,0' width = '560' height = '345'> http://screenr.com/Content/assets/screenr_1116090935.swf'> http://screenr.com/Content/assets/screenr_1116090935.swf' flashvars = 'i = 130553'allowFullScreen =' true 'width =' 560 'height =' 345 'pluginspage =' http://www.macromedia.com/go/getflashplayer'>

1-й Я должен сделать метку скрытой, а не свернутую анимацию, просто прозрачность.Я хочу, чтобы ярлык отображался так, как будто он выходит из текстового поля

Ответы [ 2 ]

4 голосов
/ 12 ноября 2010

Элемент должен быть частью одной и той же StackPanel в VisualTree, что не относится к Validation.ErrorTemplate, как вы заметили. Один из способов сделать это состоит в том, чтобы заново создать шаблон TextBox и создать место для метки «Свернутая ошибка», которая станет видимой в Validation.HasError. Вам нужно будет добавить ссылку на PresentationFramework.Aero.

xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"

Xaml

<LinearGradientBrush x:Key="TextBoxBorder" EndPoint="0,20" StartPoint="0,0" MappingMode="Absolute">
    <GradientStop Color="#ABADB3" Offset="0.05"/>
    <GradientStop Color="#E2E3EA" Offset="0.07"/>
    <GradientStop Color="#E3E9EF" Offset="1"/>
</LinearGradientBrush>
<Style x:Key="LabelValidationTextBox" BasedOn="{x:Null}" TargetType="{x:Type TextBox}">
    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
    <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
    <Setter Property="BorderBrush" Value="{StaticResource TextBoxBorder}"/>
    <Setter Property="BorderThickness" Value="1"/>
    <Setter Property="Padding" Value="1"/>
    <Setter Property="AllowDrop" Value="true"/>
    <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
    <Setter Property="Validation.ErrorTemplate" Value="{x:Null}"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TextBox}">
                <StackPanel Orientation="Vertical">
                    <Microsoft_Windows_Themes:ListBoxChrome x:Name="Bd" SnapsToDevicePixels="true" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" RenderFocused="{TemplateBinding IsKeyboardFocusWithin}" RenderMouseOver="{TemplateBinding IsMouseOver}">
                        <ScrollViewer x:Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                    </Microsoft_Windows_Themes:ListBoxChrome>
                    <Label StackPanel.ZIndex="-1" Name="errorLabel" Height="22" Margin="0,-22,0,0" Background="Red" Foreground="White" FontSize="9" Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(Validation.Errors)[0].ErrorContent}" />
                </StackPanel>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsEnabled" Value="false">
                        <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
                        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                    </Trigger>
                    <Trigger Property="Validation.HasError" Value="True">
                        <Trigger.EnterActions>
                            <BeginStoryboard>
                                <Storyboard TargetName="errorLabel" TargetProperty="Margin">
                                    <ThicknessAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="Margin">
                                        <SplineThicknessKeyFrame KeyTime="0:0:0.0" Value="0,-22,0,0"/>
                                        <SplineThicknessKeyFrame KeyTime="0:0:0.5" Value="0,0,0,0"/>
                                    </ThicknessAnimationUsingKeyFrames>
                                </Storyboard>
                            </BeginStoryboard>
                        </Trigger.EnterActions>
                        <Trigger.ExitActions>
                            <BeginStoryboard>
                                <Storyboard TargetName="errorLabel" TargetProperty="Margin">
                                    <ThicknessAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="Margin">
                                        <SplineThicknessKeyFrame KeyTime="0:0:0.0" Value="0,0,0,0"/>
                                        <SplineThicknessKeyFrame KeyTime="0:0:0.5" Value="0,-22,0,0"/>
                                    </ThicknessAnimationUsingKeyFrames>
                                </Storyboard>
                            </BeginStoryboard>
                        </Trigger.ExitActions>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Обновление

Добавлена ​​анимация поля метки. Он будет «выдвигаться» из TextBox, когда Validation.HasError равен True, и «скользит обратно» в TextBox, когда Validation.HasError имеет значение False.

1 голос
/ 12 ноября 2010

Вместо использования ErrorTemplate вы могли бы использовать Visual State Manager и настроить Invalid State.Делая это, вы сможете не только интегрировать ваши изменения с фактическим элементом управления (который влияет на макет), но и легко анимировать изменения состояния.

Если вам нужно больше рекомендаций по визуальномуШтаты не стесняются спрашивать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...