2011-01-01 22 views
5

Hola Necesito validar algunos cuadros de texto en mi aplicación. Decidí usar la regla de validación "DataErrorValidationRule". Es por eso que en mi clase implementé la interfaz IDataErrorInfo y escribí las funciones aproperiate. En mi código XAML añadí fijaciones y reglas de validación a cuadros de textowpf - validación - cómo mostrar información sobre herramientas y desactivar el botón "ejecutar"

<TextBox x:Name="txtName" Grid.Column="3" Grid.Row="1" TextAlignment="Center" > 
         <TextBox.Text> 
          <Binding Path="Name" > 
           <Binding.ValidationRules> 
            <DataErrorValidationRule></DataErrorValidationRule> 
           </Binding.ValidationRules> 
          </Binding> 
         </TextBox.Text> 
        </TextBox> 

La validación de este cuadro de texto está bien - me refiero a que aparezca un marco rojo en la caja de texto si los datos es erróneo. Sin embargo, lo que tengo que hacer es mostrar información sobre herramientas en ese cuadro de texto, pero lo que es más importante, tengo que deshabilitar el botón "Ejecutar" si algún cuadro de texto tiene datos incorrectos. ¿Cuál es la mejor manera de hacerlo?

EDIT Primer problema fue resuelto, pero tengo otro. Necesito usar MultiBindings para validar mi Botón. Así que hice algo así

<Button x:Name="btnArrange" Grid.Column="0" Content="Rozmieść" Click="btnArrange_Click" > 
       <Button.Style> 
        <Style TargetType="Button"> 
         <Style.Triggers> 
          <DataTrigger Value="False"> 
           <DataTrigger.Binding> 
            <MultiBinding Converter="{StaticResource BindingConverter}"> 
             <Binding ElementName="txtName" Path="Validation.HasError" /> 
             <Binding ElementName="txtSurname" Path="Validation.HasError"/> 
             <Binding ElementName="txtAddress" Path="Validation.HasError"/> 

            </MultiBinding> 
           </DataTrigger.Binding> 
           <Setter Property="IsEnabled" Value="False"/> 

          </DataTrigger> 
         </Style.Triggers> 
        </Style>   
       </Button.Style> 

     </Button> 

Mi convertidor parece que

public class Converters : IMultiValueConverter 
{ 

    #region IMultiValueConverter Members 

    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     if(values !=null && values.Length > 0) 
     { 


      if (values.Cast<type>().Count(val => val) > 0) 
       return false; 
      return true; 
     } 
     return false; 
    } 

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture) 
    { 
     return null; 
    } 

    #endregion 
} 

Sin embargo me sale InvalidCastException en este convertidor. ¿Cuál es el modelo adecuado en ese caso? Creo que HasError es un bool, así que debería lanzar al bool.

+0

¿Qué significa "tipo"? Reemplazarlo por "if (values.Cast () .Any (val => val))" – vorrtex

Respuesta

2

Si crea un resumen de validación, puede vincular la propiedad IsEnabled de su botón "Ejecutar" a su propiedad HasErrors.

Deberá usar una propiedad intermedia o un convertidor, ya que el IsEnabled será cuando HasErrors sea falso (y viceversa).

+1

¿Cómo puedo crear un resumen de validación? – stylus

+0

@validator - hay uno aquí - http://codeblitz.wordpress.com/2009/05/12/wpf-validation-summary-control/ - Estaba confundido con Silverlight, lo siento. – ChrisF

6
<Window.Resources> 
    <Style x:Key="ElementInError" TargetType="{x:Type FrameworkElement}"> 
     <Style.Triggers> 
      <Trigger Property="Validation.HasError" Value="True"> 
       <Setter Property="ToolTip" 
        Value="{Binding (Validation.Errors)[0].ErrorContent, RelativeSource={x:Static RelativeSource.Self}}"/> 
      </Trigger> 
     </Style.Triggers> 
    </Style> 
</Window.Resources> 
<!-- ... --> 
<TextBox x:Name="txtName" Style="{StaticResource ElementInError}"> 
    <!-- ... -->   
</TextBox> 
<!-- ... --> 
     <Button x:Name="OkButton" Content="Ok" Margin="5" Click="OkButton_Click"> 
      <Button.Style> 
       <Style TargetType="Button"> 
        <Style.Triggers> 
         <DataTrigger Binding="{Binding ElementName=txtName,Path=(Validation.HasError)}" Value="True"> 
          <Setter Property="IsEnabled" Value="False" /> 
         </DataTrigger> 
        </Style.Triggers> 
       </Style> 
      </Button.Style> 
     </Button> 
+0

Gracias por la respuesta, ¿podría echar un vistazo de nuevo a mi pregunta? Lo edité – stylus

17

Para mostrar el mensaje de error en una punta de la herramienta poner esto en sus Application.Resources:

<Style x:Key="textBoxInError" TargetType="{x:Type TextBox}"> 
    <Style.Triggers> 
    <Trigger Property="Validation.HasError" Value="true"> 
     <Setter Property="ToolTip" 
     Value="{Binding RelativeSource={x:Static RelativeSource.Self}, 
         Path=(Validation.Errors)[0].ErrorContent}"/> 
    </Trigger> 
    </Style.Triggers> 
</Style> 

(Ejemplo de http://msdn.microsoft.com/en-us/library/system.windows.controls.validation.errortemplate.aspx)

para activar/desactivar un botón que podría utilizar algo a lo largo de la línea de

<Button x:Name="btnOK" Content="OK" IsDefault="True" Click="btnOK_Click"> 
    <Button.Style> 
    <Style TargetType="{x:Type Button}"> 
     <Setter Property="IsEnabled" Value="false" /> 
     <Style.Triggers> 
     <MultiDataTrigger> 
      <MultiDataTrigger.Conditions> 
      <Condition Binding="{Binding ElementName=txt1, Path=(Validation.HasError)}" Value="false" /> 
      <Condition Binding="{Binding ElementName=txt2, Path=(Validation.HasError)}" Value="false" /> 
      </MultiDataTrigger.Conditions> 
      <Setter Property="IsEnabled" Value="true" /> 
     </MultiDataTrigger> 
     </Style.Triggers> 
    </Style> 
    </Button.Style> 
</Button> 

o puede implementar ICommand y usar comm y vinculante.

EDITAR

Aquí está un ejemplo completamente de trabajo. Muestra una ventana con dos cuadros de texto. El botón se activa si y solo si ambos cuadros de texto no están vacíos. Crear un proyecto llamado ValidationDemo y poner los siguientes archivos en ella:

MainWindow.xaml:

<Window x:Class="ValidationDemo.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="146" Width="223"> 
    <Window.Resources> 
    <Style TargetType="{x:Type TextBox}"> 
     <Style.Triggers> 
     <Trigger Property="Validation.HasError" Value="true"> 
      <Setter Property="ToolTip" Value="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(Validation.Errors)[0].ErrorContent}"/> 
     </Trigger> 
     </Style.Triggers> 
    </Style> 
    </Window.Resources> 
    <Grid> 
    <Label Content="A" Height="28" HorizontalAlignment="Left" Margin="46,7,0,0" Name="label1" VerticalAlignment="Top" /> 
    <TextBox Name="txtA" Text="{Binding Path=TextA, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, ValidatesOnExceptions=True}" Height="23" HorizontalAlignment="Left" Margin="69,12,0,0" VerticalAlignment="Top" Width="120" /> 
    <Label Content="B" Height="28" HorizontalAlignment="Left" Margin="46,39,0,0" Name="label2" VerticalAlignment="Top" /> 
    <TextBox Name="txtB" Text="{Binding Path=TextB, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, ValidatesOnExceptions=True}" Height="23" HorizontalAlignment="Left" Margin="69,41,0,0" VerticalAlignment="Top" Width="120" /> 
    <Button Name="btnOk" Content="OK" Height="23" HorizontalAlignment="Left" Margin="114,70,0,0" VerticalAlignment="Top" Width="75" Click="btnOk_Click"> 
     <Button.Style> 
     <Style TargetType="{x:Type Button}"> 
      <Setter Property="IsEnabled" Value="false" /> 
      <Style.Triggers> 
      <MultiDataTrigger> 
       <MultiDataTrigger.Conditions> 
       <Condition Binding="{Binding ElementName=txtA, Path=(Validation.HasError)}" Value="false" /> 
       <Condition Binding="{Binding ElementName=txtB, Path=(Validation.HasError)}" Value="false" /> 
       </MultiDataTrigger.Conditions> 
       <Setter Property="IsEnabled" Value="true" /> 
      </MultiDataTrigger> 
      </Style.Triggers> 
     </Style> 
     </Button.Style> 
    </Button> 
    </Grid> 
</Window> 

MainWindow.xaml.cs:

using System.Windows; 

namespace ValidationDemo 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window 
    { 

    private Model model = new Model(); 

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

    private void btnOk_Click(object sender, RoutedEventArgs e) 
    { 
     Application.Current.Shutdown(); 
    } 
    } 
} 

modelo.cs:

using System; 
using System.ComponentModel; 

namespace ValidationDemo 
{ 
    public class Model : INotifyPropertyChanged, IDataErrorInfo 
    { 
    public event PropertyChangedEventHandler PropertyChanged; 

    private string textA = string.Empty; 
    public string TextA 
    { 
     get 
     { 
     return this.textA; 
     } 
     set 
     { 
     if (this.textA != value) 
     { 
      this.textA = value; 
      this.OnPropertyChanged("TextA"); 
     } 
     } 
    } 

    private string textB = string.Empty; 
    public string TextB 
    { 
     get 
     { 
     return this.textB; 
     } 
     set 
     { 
     if (this.textB != value) 
     { 
      this.textB = value; 
      this.OnPropertyChanged("TextB"); 
     } 
     } 
    } 

    public string Error 
    { 
     get { throw new NotImplementedException(); } 
    } 

    public string this[string columnName] 
    { 
     get 
     { 
     string result = string.Empty; 
     switch (columnName) 
     { 
      case "TextA": 
      if (string.IsNullOrEmpty(this.textA)) 
      { 
       result = "'A' must not be empty"; 
      } 
      break; 
      case "TextB": 
      if (string.IsNullOrEmpty(this.textA)) 
      { 
       result = "'B' must not be empty"; 
      } 
      break; 
     } 
     return result; 
     } 
    } 

    protected virtual void OnPropertyChanged(string propertyName) 
    { 
     if (this.PropertyChanged != null) 
     { 
     this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

    } 

} 
+0

Desafortunadamente no está funcionando. A pesar de que uno de mis elementos de validación de mi cuadro de texto mi botón Ok todavía está habilitado, – stylus

+0

@validator: He añadido un ejemplo de trabajo. – TomBot

Cuestiones relacionadas