Por defecto, el Validation.ErrorTemplate en WPF es sólo un pequeño borde rojo sin ningún ToolTip.

En Silverlight 4, el error de validación está muy bien de estilo out-of-the-box.

Aquí está una comparación de un error de validación que ocurren en 4 de Silverlight y WPF

Silverlight 4

Error de validación de Estilo en WPF, similar a la de Silverlight

WPF

Error de validación de Estilo en WPF, similar a la de Silverlight

Aviso a los que realmente plana, aburrida mirada de WPF versión en comparación con el, en mi opinión, gran aspecto en Silverlight.

¿Alguno similar validación de los estilos/plantillas existentes en el Marco de trabajo WPF o nadie ha creado bien de estilo de validación de plantillas como la Silverlight versión anterior? O voy a tener que crearlas desde cero?

Si alguien quiere probarlo, la validación de error anterior puede ser reproducida con el siguiente código, funciona para Silverlight y WPF

MainWindow/MainPage.xaml

<StackPanel Orientation="Horizontal" Margin="10" VerticalAlignment="Top">
    <TextBox Text="{Binding Path=TextProperty, Mode=TwoWay, ValidatesOnExceptions=True}"/>
    <Button Content="Tab To Me..." Margin="20,0,0,0"/>
</StackPanel>

MainWindow/MainPage.xaml.cs

public MainWindow/MainPage()
{
    InitializeComponent();
    this.DataContext = this;
}

private string _textProperty;
public string TextProperty
{
    get { return _textProperty; }
    set
    {
        if (value.Length > 5)
        {
            throw new Exception("Too many characters");
        }
        _textProperty = value;
    }
}
  • Quiero desesperadamente corregir el error de gramática en «A muchos de los personajes», pero dentro de una imagen! Maldiciones! 😛
  • Ouch, «demasiado» muchos errores de gramática aquí 🙂 voy a solucionarlo

4 Comentarios

  1. 104

    Estudié la Silverlight versión de el Error de Validación de la Plantilla y crea un WPF versión de lo que parece a esto

    Error de validación de Estilo en WPF, similar a la de Silverlight

    Añadido un GIF animado en la parte inferior del post, pero después de que terminé me di cuenta de que podría ser molesto, porque de el ratón que se mueve en ella. Déjame saber si debo quitar.. 🙂

    He utilizado un MultiBinding con un BooleanOrConverter para mostrar la «descripción de error» cuando el TextBox tiene el foco del Teclado o el Ratón sobre la esquina superior derecha. Para la animación de fade-in he utilizado un DoubleAnimation para la Opacity y un ThicknessAnimation con un BackEase/EaseOut EasingFunction para la Margin

    Utilizable como este

    <TextBox Validation.ErrorTemplate="{StaticResource errorTemplateSilverlightStyle}" />

    errorTemplateSilverlightStyle

    <ControlTemplate x:Key="errorTemplateSilverlightStyle">
    <StackPanel Orientation="Horizontal">
    <Border BorderThickness="1" BorderBrush="#FFdc000c" CornerRadius="0.7"
    VerticalAlignment="Top">
    <Grid>
    <Polygon x:Name="toolTipCorner"
    Grid.ZIndex="2"
    Margin="-1"
    Points="6,6 6,0 0,0" 
    Fill="#FFdc000c" 
    HorizontalAlignment="Right" 
    VerticalAlignment="Top"
    IsHitTestVisible="True"/>
    <Polyline Grid.ZIndex="3"
    Points="7,7 0,0" Margin="-1" HorizontalAlignment="Right" 
    StrokeThickness="1.5"
    StrokeEndLineCap="Round"
    StrokeStartLineCap="Round"
    Stroke="White"
    VerticalAlignment="Top"
    IsHitTestVisible="True"/>
    <AdornedElementPlaceholder x:Name="adorner"/>
    </Grid>
    </Border>
    <Border x:Name="errorBorder" Background="#FFdc000c" Margin="1,0,0,0"
    Opacity="0" CornerRadius="1.5"
    IsHitTestVisible="False"
    MinHeight="24" MaxWidth="267">
    <Border.Effect>
    <DropShadowEffect ShadowDepth="2.25" 
    Color="Black" 
    Opacity="0.4"
    Direction="315"
    BlurRadius="4"/>
    </Border.Effect>
    <TextBlock Text="{Binding ElementName=adorner,
    Path=AdornedElement.(Validation.Errors)[0].ErrorContent}"
    Foreground="White" Margin="8,3,8,3" TextWrapping="Wrap"/>
    </Border>
    </StackPanel>
    <ControlTemplate.Triggers>
    <DataTrigger Value="True">
    <DataTrigger.Binding>
    <MultiBinding Converter="{StaticResource BooleanOrConverter}">
    <Binding ElementName="adorner" Path="AdornedElement.IsKeyboardFocused" />
    <Binding ElementName="toolTipCorner" Path="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>

    BooleanOrConverter

    public class BooleanOrConverter : IMultiValueConverter
    {
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
    foreach (object value in values)
    {
    if ((bool)value == true)
    {
    return true;
    }
    }
    return false;
    }
    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
    throw new NotSupportedException();
    }
    }

    Error de validación de Estilo en WPF, similar a la de Silverlight

    • +1 Buen Trabajo! Terminé poniendo esto en un estilo así que podría ser utilizado a través de la junta directiva en todos mis controles.
    • Una cosa a tener en cuenta es que el errorBorder la Visibilidad es siempre Visibles y no se vino abajo cuando el ratón no está sobre o el teclado no está centrado. Yo tenía un botón a la derecha del cuadro de texto y nunca haga clic en él cuando hay un error en la validación, aunque el errorBorder la opacidad se ha establecido en 0. Para solucionar esto he añadido el siguiente en el comentario de abajo:
    • <ObjectAnimationUsingKeyFrames Duración=»00:00:00″ Storyboard.TargetName=»errorBorder» Storyboard.TargetProperty=»Visibilidad»> <DiscreteObjectKeyFrame KeyTime=»00:00:00″ Value=»{x:Estática Visibilidad.Se derrumbó}»/> </ObjectAnimationUsingKeyFrames>
    • Cierto, nunca he notado a mí mismo, pero fue lo suficientemente fácil como para reproducir 🙂 lo resuelto por la adición de IsHitTestVisible="False" a la errorBorder pero su adición funcionará así. Gracias por la actualización
    • Tengo otra oportunidad… si el control está en el borde de la ventana, el error de validación se corta. ¿Tiene alguna sugerencia sobre cómo hacer este respecto la ventana y mostrar el error de validación bajo el control en lugar de a la derecha cuando no hay suficiente espacio entre el control y el borde de la ventana?
    • Lo mismo ha estado molestando. En lugar de mostrar a continuación me gustaría mostrar en el exterior de la ventana. Yo no he tenido tiempo para buscar en él todavía, pero cuando lo hago, voy a actualizar aquí. Como para mostrar a continuación, pruebe a cambiar la StackPanels orientación de Horizontal a Vertical. No he probado a mí mismo aunque
    • Si eres purista y quieren evitar la unión de las excepciones etc utilice esta opción para evitar cojo errores Text=»{Binding ElementName=adorner, Path=AdornedElement.(Validación.Los errores).CurrentItem.ErrorContent}»
    • impresionante trabajo, estoy utilizando esta plantilla en mi aplicación, pero debo señalar, sin embargo, que ha provocado una excepción en el BooleanOrConverter quejándose de que no todos los valores son realmente bools cuando la he usado dentro de mi cuadrícula de datos. todavía estoy seguimiento de la causa.
    • Justo lo que estaba buscando para deshacerse de las excepciones. Muchas gracias.
    • El BooleanOrConverter producirá una excepción si cualquiera de los valores pasados no es convertible a bool, por ejemplo, el valor pasado es DependencyProperty.UnsetValue. Esto va a hacer el truco, aunque; público objeto de Convertir(object[] valores, Tipo de targetType, «parámetros de objeto», CultureInfo cultura) { return valores.OfType<bool>().Cualquier(valor => valor); }
    • Podría ser mejorada mediante el uso de un emergente : <Popup x:Name=»errorPopup» PopupAnimation=»Fade» AllowsTransparency=»True» Colocación=»Derecho»> y un gatillo para abrir la ventana emergente cuando el usuario tiene el ratón sobre la descripción. <Setter TargetName=»errorPopup» Property=»IsOpen» Value=»True»/>
    • me sale una advertencia el uso de este Sistema de plantillas.Windows.La Advertencia de datos: 4 : No se puede encontrar la fuente para el enlace con la referencia ‘ElementName=adorner’. BindingExpression:Path=AdornedElement.IsKeyboardFocused; DataItem=null; elemento de destino es el ‘Control’ (Nombre=»); propiedad de destino es «NoTarget’ (tipo ‘Object’), Es esta advertencia ACEPTAR o estoy teniendo algún problema en el código?
    • muy bonito, pero el mensaje de error que a veces aparecen fuera del área visible cuando el control está en la extrema derecha. Cómo controlar que también desde dentro de la plantilla de control, mostrando un mensaje de error de fondo en este caso sólo?
    • Sólo tiene un pequeño problema que los cuadros de color rojo son todavía visibles cuando hay alguna ventana emergente sobre él. Es lo descrito aquí: stackoverflow.com/questions/1471451/…, Pero es posible tratar de alguna manera en que errorTemplateSilverlightStyle estilo?
    • Un trabajo impresionante, muy bonito, solo una pregunta, cuando se escribe algo en el cuadro de texto es tan lento. Es eso normal ?

  2. 36

    Esta respuesta solo se expande en Fredrik Hedblad‘s una excelente respuesta. Siendo nuevo en WPF y XAML, Fredrik la respuesta que le sirvió de trampolín para la definición de cómo quería que los errores de validación que se muestra en mi aplicación. Mientras que el XAML de abajo funciona para mí, es un trabajo en progreso. No he probado completamente, y no tengo inconveniente en admitir que no puedo explicar completamente cada etiqueta. Con esas advertencias, espero que esto sea de utilidad para los demás.

    Mientras que el animado TextBlock es un buen método, que tiene dos defectos que quería tratar.

    1. En primer lugar, como Brent‘s comentario señalado, el texto está restringido por el propietario de la ventana de las fronteras de tal forma que si el control no válido está en el borde de la ventana, el texto se corta. Fredrik la solución que se sugiere es que se muestra «fuera de la ventana.» Eso tiene sentido para mí.
    2. Segundo, mostrando la TextBlock a la derecha del control no válido no es siempre óptima. Por ejemplo, dicen que el TextBlock se utiliza para especificar un archivo para abrir y que hay un botón Examinar, a su derecha. Si el usuario escribe en un archivo que no existe, el error TextBlock cubrirá el botón Examinar y prevenir que el usuario de clic en él para corregir el error. Lo que tiene sentido para mí es tener el mensaje de error que aparece en forma diagonal hacia arriba y a la derecha del control no válido. De esta forma se logran dos cosas. En primer lugar, se evita la ocultación de cualquier compañero de controles a la derecha del control no válido. También tiene el efecto visual de que el toolTipCorner es apuntando hacia el mensaje de error.

    Aquí es el diálogo alrededor de la cual he hecho mi desarrollo.

    Error de validación de Estilo en WPF, similar a la de Silverlight

    Como usted puede ver, hay dos Cuadro de texto controles que deben ser validados. Ambos están relativamente cerca del borde derecho de la ventana, siempre y mensajes de error probablemente sería recortada. Y observe que el segundo Cuadro de texto tiene un botón de Examinar que no quiero que se oculta en el evento de un error.

    Así que aquí está lo que un error de validación se ve como el uso de mi aplicación.

    Error de validación de Estilo en WPF, similar a la de Silverlight

    Funcionalmente, es muy similar a Fredrik implementación de la misma. Si el Cuadro de texto tiene el foco, el error será visible. Una vez que se pierde el foco, el error desaparece. Si el usuario pasa el ratón por encima de la toolTipCorner, aparecerá el error independientemente de si el Cuadro de texto tiene el foco o no. Hay un par de cambios estéticos, así como la toolTipCorner es un 50% más grande (9 píxeles frente a 6 píxeles).

    La diferencia obvia, por supuesto, es que mi aplicación usa un Popup para mostrar el error. Esto resuelve el primer inconveniente a causa de la Popup muestra su contenido en su propia ventana, por lo que no está limitado por el diálogo de las fronteras. Sin embargo, el uso de un Popup hizo un par de retos a superar.

    1. Se desprende de las pruebas y debates en línea que el Popup se considera una ventana de nivel superior. Así que incluso cuando mi solicitud fue escondida por otra aplicación, la Popup era todavía visible. Este fue el menos deseable de comportamiento.
    2. El otro problema era que si el usuario que sucedió para mover o cambiar el tamaño del cuadro de diálogo, mientras que el Popup era visible, la Popup no reposicionarse para mantener su posición en relación con el control no válido.

    Afortunadamente, estos problemas han sido abordados.

    Aquí está el código. Comentarios y correcciones son bienvenidos!


    • De Archivo: ErrorTemplateSilverlightStyle.xaml
    • Espacio De Nombres: MyApp.Aplicación.La interfaz de usuario.Plantillas de
    • De La Asamblea: MyApp.Application.UI.dll

    <ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
    xmlns:behaviors="clr-namespace:MyApp.Application.UI.Behaviors">
    <ControlTemplate x:Key="ErrorTemplateSilverlightStyle">
    <StackPanel Orientation="Horizontal">
    <!-- Defines TextBox outline border and the ToolTipCorner -->
    <Border x:Name="border" BorderThickness="1.25"
    BorderBrush="#FFDC000C">
    <Grid>
    <Polygon x:Name="toolTipCorner"
    Grid.ZIndex="2"
    Margin="-1"
    Points="9,9 9,0 0,0"
    Fill="#FFDC000C"
    HorizontalAlignment="Right"
    VerticalAlignment="Top"
    IsHitTestVisible="True"/>
    <Polyline Grid.ZIndex="3"
    Points="10,10 0,0"
    Margin="-1"
    HorizontalAlignment="Right"
    StrokeThickness="1.5"
    StrokeEndLineCap="Round"
    StrokeStartLineCap="Round"
    Stroke="White"
    VerticalAlignment="Top"
    IsHitTestVisible="True"/>
    <AdornedElementPlaceholder x:Name="adorner"/>
    </Grid>
    </Border>
    <!-- Defines the Popup -->
    <Popup x:Name="placard"
    AllowsTransparency="True"
    PopupAnimation="Fade"
    Placement="Top"
    PlacementTarget="{Binding ElementName=toolTipCorner}"
    PlacementRectangle="10,-1,0,0">
    <!-- Used to reposition Popup when dialog moves or resizes -->
    <i:Interaction.Behaviors>
    <behaviors:RepositionPopupBehavior/>
    </i:Interaction.Behaviors>
    <Popup.Style>
    <Style TargetType="{x:Type Popup}">
    <Style.Triggers>
    <!-- Shows Popup when TextBox has focus -->
    <DataTrigger Binding="{Binding ElementName=adorner, Path=AdornedElement.IsFocused}"
    Value="True">
    <Setter Property="IsOpen" Value="True"/>
    </DataTrigger>
    <!-- Shows Popup when mouse hovers over ToolTipCorner -->
    <DataTrigger Binding="{Binding ElementName=toolTipCorner, Path=IsMouseOver}"
    Value="True">
    <Setter Property="IsOpen" Value="True"/>
    </DataTrigger>
    <!-- Hides Popup when window is no longer active -->
    <DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=IsActive}"
    Value="False">
    <Setter Property="IsOpen" Value="False"/>
    </DataTrigger>
    </Style.Triggers>
    </Style>
    </Popup.Style>
    <Border x:Name="errorBorder"
    Background="#FFDC000C"
    Margin="0,0,8,8"
    Opacity="1"
    CornerRadius="4"
    IsHitTestVisible="False"
    MinHeight="24"
    MaxWidth="267">
    <Border.Effect>
    <DropShadowEffect ShadowDepth="4"
    Color="Black"
    Opacity="0.6"
    Direction="315"
    BlurRadius="4"/>
    </Border.Effect>
    <TextBlock Text="{Binding ElementName=adorner, Path=AdornedElement.(Validation.Errors).CurrentItem.ErrorContent}"
    Foreground="White"
    Margin="8,3,8,3"
    TextWrapping="Wrap"/>
    </Border>
    </Popup>
    </StackPanel>
    </ControlTemplate>
    </ResourceDictionary>


    • De Archivo: RepositionPopupBehavior.cs
    • Espacio De Nombres: MyApp.Aplicación.La interfaz de usuario.Comportamientos
    • De La Asamblea: MyApp.Application.UI.dll

    (NOTA: ESTO REQUIERE EL EXPRESSION BLEND 4 del Sistema.Windows.La interactividad de la ASAMBLEA)

    using System;
    using System.Windows;
    using System.Windows.Controls.Primitives;
    using System.Windows.Interactivity;
    namespace MyApp.Application.UI.Behaviors
    {
    ///<summary>
    ///Defines the reposition behavior of a <see cref="Popup"/> control when the window to which it is attached is moved or resized.
    ///</summary>
    ///<remarks>
    ///This solution was influenced by the answers provided by <see href="https://stackoverflow.com/users/262204/nathanaw">NathanAW</see> and
    ///<see href="https://stackoverflow.com/users/718325/jason">Jason</see> to
    ///<see href="https://stackoverflow.com/questions/1600218/how-can-i-move-a-wpf-popup-when-its-anchor-element-moves">this</see> question.
    ///</remarks>
    public class RepositionPopupBehavior : Behavior<Popup>
    {
    #region Protected Methods
    ///<summary>
    ///Called after the behavior is attached to an <see cref="Behavior.AssociatedObject"/>.
    ///</summary>
    protected override void OnAttached()
    {
    base.OnAttached();
    var window = Window.GetWindow(AssociatedObject.PlacementTarget);
    if (window == null) { return; }
    window.LocationChanged += OnLocationChanged;
    window.SizeChanged     += OnSizeChanged;
    AssociatedObject.Loaded += AssociatedObject_Loaded;
    }
    void AssociatedObject_Loaded(object sender, RoutedEventArgs e)
    {
    //AssociatedObject.HorizontalOffset = 7;
    //AssociatedObject.VerticalOffset = -AssociatedObject.Height;
    }
    ///<summary>
    ///Called when the behavior is being detached from its <see cref="Behavior.AssociatedObject"/>, but before it has actually occurred.
    ///</summary>
    protected override void OnDetaching()
    {
    base.OnDetaching();
    var window = Window.GetWindow(AssociatedObject.PlacementTarget);
    if (window == null) { return; }
    window.LocationChanged -= OnLocationChanged;
    window.SizeChanged     -= OnSizeChanged;
    AssociatedObject.Loaded -= AssociatedObject_Loaded;
    }
    #endregion Protected Methods
    #region Private Methods
    ///<summary>
    ///Handles the <see cref="Window.LocationChanged"/> routed event which occurs when the window's location changes.
    ///</summary>
    ///<param name="sender">
    ///The source of the event.
    ///</param>
    ///<param name="e">
    ///An object that contains the event data.
    ///</param>
    private void OnLocationChanged(object sender, EventArgs e)
    {
    var offset = AssociatedObject.HorizontalOffset;
    AssociatedObject.HorizontalOffset = offset + 1;
    AssociatedObject.HorizontalOffset = offset;
    }
    ///<summary>
    ///Handles the <see cref="Window.SizeChanged"/> routed event which occurs when either then <see cref="Window.ActualHeight"/> or the
    ///<see cref="Window.ActualWidth"/> properties change value.
    ///</summary>
    ///<param name="sender">
    ///The source of the event.
    ///</param>
    ///<param name="e">
    ///An object that contains the event data.
    ///</param>
    private void OnSizeChanged(object sender, SizeChangedEventArgs e)
    {
    var offset = AssociatedObject.HorizontalOffset;
    AssociatedObject.HorizontalOffset = offset + 1;
    AssociatedObject.HorizontalOffset = offset;
    }
    #endregion Private Methods
    }
    }


    • De Archivo: ResourceLibrary.xaml
    • Espacio De Nombres: MyApp.Aplicación.Interfaz de usuario
    • De La Asamblea: MyApp.Application.UI.dll

    <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <ResourceDictionary.MergedDictionaries>
    <!-- Styles -->
    ...
    <!-- Templates -->
    <ResourceDictionary Source="Templates/ErrorTemplateSilverlightStyle.xaml"/>
    </ResourceDictionary.MergedDictionaries>
    <!-- Converters -->
    ...
    </ResourceDictionary>


    • De Archivo: App.xaml
    • Espacio De Nombres: MyApp.Aplicación
    • De La Asamblea: MyApp.exe

    <Application x:Class="MyApp.Application.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    StartupUri="Views\MainWindowView.xaml">
    <Application.Resources>
    <ResourceDictionary>
    <ResourceDictionary.MergedDictionaries>
    <ResourceDictionary Source="/MyApp.Application.UI;component/ResourceLibrary.xaml"/>
    </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
    </Application.Resources>
    </Application>


    • De Archivo: NewProjectView.xaml
    • Espacio De Nombres: MyApp.Aplicación.Vistas
    • De La Asamblea: MyApp.exe

    <Window x:Class="MyApp.Application.Views.NewProjectView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:views="clr-namespace:MyApp.Application.Views"
    xmlns:viewModels="clr-namespace:MyApp.Application.ViewModels"
    Title="New Project" Width="740" Height="480"
    WindowStartupLocation="CenterOwner">
    <!-- DATA CONTEXT -->
    <Window.DataContext>
    <viewModels:NewProjectViewModel/>
    </Window.DataContext>
    <!-- WINDOW GRID -->
    ...
    <Label x:Name="ProjectNameLabel"
    Grid.Column="0"
    Content="_Name:"
    Target="{Binding ElementName=ProjectNameTextBox}"/>
    <TextBox x:Name="ProjectNameTextBox"
    Grid.Column="2"
    Text="{Binding ProjectName,
    Mode=TwoWay,
    UpdateSourceTrigger=PropertyChanged,
    ValidatesOnDataErrors=True}"
    Validation.ErrorTemplate="{StaticResource ErrorTemplateSilverlightStyle}"/>
    ...
    </Window>
    • Me gusta este, pero el RepositionPopupBehavior no trabajar con la ventana de los cambios de estado (Maximizar/Restaurar). Pensé que la adición de otro controlador de eventos en la misma forma que para el LocationChanged y SizeChanged eventos de arreglar esto, pero que no funciona bien :/
    • Alguien ha tenido una experiencia de «por un» error al cambiar el valor en el cuadro de texto? Decir que tengo cero y ese es el error de validación del cuadro de error no ir hasta que me escriba «11» (1, 1) en lugar de «1».
  3. 3

    He creado mi error personalizado adorner en uno de los proyectos para mostrar el error de adorner justo debajo de mi cuadro de texto con el mensaje de error en ella. Sólo se necesita establecer la propiedad «Validación.ErrorTemplate» en el cuadro de texto el estilo por defecto que se puede guardar en la aplicación de recursos de manera que se aplica a todos los cuadros de texto en su aplicación.

    Nota: he utilizado algunos pinceles aquí, reemplaza con su propio conjunto de pinceles que usted quiere para su adorner messgae. Puede ser que esto puede ser de alguna ayuda :

    <Setter Property="Validation.ErrorTemplate">
    <Setter.Value>
    <ControlTemplate>
    <StackPanel>
    <!--TextBox Error template-->
    <Canvas Panel.ZIndex="1099">
    <DockPanel>
    <Border BorderBrush="{DynamicResource HighlightRedBackgroundBrush}" BorderThickness="2" Padding="1" CornerRadius="3">
    <AdornedElementPlaceholder x:Name="ErrorAdorner" />
    </Border>
    </DockPanel>
    <Popup IsOpen="True" AllowsTransparency="True" Placement="Bottom" PlacementTarget="{Binding ElementName=ErrorAdorner}" StaysOpen="False">
    <Border Canvas.Bottom="4"
    Canvas.Left="{Binding Path=AdornedElement.ActualWidth, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Adorner}}}"
    BorderBrush="{DynamicResource HighlightRedBackgroundBrush}"
    BorderThickness="1"
    Padding="4"
    CornerRadius="5"
    Background="{DynamicResource ErrorBackgroundBrush}">
    <StackPanel Orientation="Horizontal">
    <ContentPresenter Width="24" Height="24" Content="{DynamicResource ExclamationIcon}" />
    <TextBlock TextWrapping="Wrap"
    Margin="4"
    MaxWidth="250"
    Text="{Binding Path=AdornedElement.(Validation.Errors)[0].ErrorContent, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Adorner}}}" />
    </StackPanel>
    </Border>
    </Popup>
    </Canvas>
    </StackPanel>
    </ControlTemplate>
    </Setter.Value>
    </Setter>
    • Nuestro equipo ha gustado mucho el Silverlight versión de el error de la plantilla así que me recreado para WPF. Gracias de todos modos!
    • Ok. Fresco. Eso fue sólo una muestra de la plantilla, de acuerdo a nuestras necesidades de su proyecto.
    • Le gustaba su animación en la plantilla. 🙂 +1 por tu post.. sugiero esto para mi proyecto..
    • Cuando el textbox pierde el foco, a continuación, volver a obtener el foco de nuevo, la ventana emergente no se muestran.
  4. 0

    Me encontré con un problema con este cuando se trata de aplicarlo a un proyecto de wpf en el que estoy trabajando. Si usted está teniendo el siguiente problema al intentar ejecutar el proyecto:

    «Una excepción de tipo ‘System.Windows.El marcado.XamlParseException’ se ha producido en PresentationFramework.dll pero no fue manejado en el código de usuario»

    Necesita crear una instancia de la booleanOrConverter clase en sus recursos (dentro de la aplicación.xaml):

    <validators:BooleanOrConverter x:Key="myConverter" />

    También no se olvide de agregar el espacio de nombres en la parte superior del archivo (en la aplicación de la etiqueta):

    xmlns:validadores=»clr-namespace:ParcelRatesViewModel.Validadores;montaje=ParcelRatesViewModel»

Dejar respuesta

Please enter your comment!
Please enter your name here