Cuando desarrollamos aplicaciones empresariales es importante marcar los errores a los usuarios según van introduciendo los datos, ya vimos algo de esto en el post Validation Rules en WPF donde definamos reglas de validación en la aplicación de WPF. A mi no es que me guste mucho porque si trabajamos con aplicaciones en capas, yo suelo poner este tipo de validaciones en la propia entidad ya que si es utilizada en diferentes pantallas o controles no tengo que replicar este control.
Si imaginamos la aplicación anterior, recordamos que teníamos un campo de entrada del rating que va de 1 a 5, peor no lo controlábamos. Vamos a controlar este error aplicando esta interfaz.
Para ello lo primero es que la clase Person implemente la interfaz IDataErrorInfo, esta interfaz nos obliga a implementar dos metodos
public string this[string columnName] { get { throw new NotImplementedException(); } } public string Error { get { throw new NotImplementedException(); } }
En el primer método controlaremos cada columna y devolveremos el string con el error, en nuestro caso
public string this[string columnName] { get { string result = string.Empty; if (columnName == "ImageRating") { if (ImageRating < 1 || ImageRating > 5) result = "El rating debe de estar entre 1 y 5"; } return result; } }
Ahora modificaríamos el binding del textbox de rating
<TextBox Height="30" FontSize="20" Foreground="Blue" Text="{Binding Path=ImageRating }" HorizontalAlignment="Left" > </TextBox>
Por el binding para que se produzca la validación del objeto cuando pierda el foco
<TextBox Height="30" FontSize="20" Foreground="Blue" HorizontalAlignment="Left" > <Binding UpdateSourceTrigger="LostFocus" Path="ImageRating" ValidatesOnDataErrors="True" /> </TextBox>
De esta manera se lanzara la validación en el objeto cuando el campo pierde el foco, como se muestra esto en la ventana. Si no ponemos nada como en este caso, el campo se pone rojo automáticamente de esta manera
Ahora es cuestión nuestra el mostrar el mensaje del error como queramos, un ejemplo sería lanzar el tooltip. Para ello definimos el estilo siguiente
<Style TargetType="{x:Type TextBox}"> <Style.Triggers> <Trigger Property="Validation.HasError" Value="true"> <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}"/> </Trigger> </Style.Triggers> </Style>
Antes de terminar este post me gustaría que os fijaseis en el XAML del estilo, en este caso no tiene una key que identifique el estilo, esto va ha hacer que se aplique este estilo a todos los textbox que no tengan un estilo asignado, de esta manera podemos hacer estilos por defectos a los controles.
Si nos fijamos en el binding la propiedad UpdateSourceTrigger vemos que tiene la propiedad LostFocus. UpdateSourceTrigger definirá de que manera los datos serán modificados en el objeto origen, para que esta propiedad tenga sentido es claro que el Mode deberá ser TwoWay o OneWayToSource, ya que son los casos que admiten la modificación de objeto origen.
Las opciones de UpdateSourceTrigger son:
- “Cuando el elemento pierde el foco” (LostFocus)
- “Cuando la propiedad cambia” (PropertyChanged)
- “Especificado vía código” (Explicit)
- “Valor definido por defecto en la dependency property” (Default
Si se utiliza la opción “Explicit” por ejemplo en el TexBox DNI de la siguiente forma:
<TextBox Margin="3" x:Name="txtNombre" Text="{Binding Nombre, UpdateSourceTrigger=Explicit}" />
Para lanzar el trigguer desde código
txtNombre.GetBindingExpression(TextBox.TextProperty).UpdateSource();
Cuando desarrollamos aplicaciones empresariales es importante marcar los errores a los usuarios según
Seria posible realizar el Style desde el código no xaml?