2011-01-01 11 views
5

Hi Ho bisogno di validare alcune delle caselle di testo nella mia applicazione. Ho decied usare regola di convalida "DataErrorValidationRule". Ecco perché nella mia classe ho implementato l'interfaccia IDataErrorInfo e ho scritto le funzioni di aproperia. Nel mio codice XAML ho aggiunto attacchi e le regole di convalida per le caselle di testoWPF - convalida - come mostrare i suggerimenti e disattivare "run" pulsante

<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 liquidazione di questo campo testo è OK - voglio dire appare cornice rossa su testo se i dati è sbagliato. Tuttavia ciò che devo fare è quello di mostrare tooltip su quel testo, ma ciò che è più importante devo disabilitare il pulsante "Esegui" se tutte le caselle di testo hanno dati sbagliati. Qual è il modo migliore per fare ??

EDIT primo problema è stato risolto, ma ho un altro. Devo usare MultiBindings per convalidare il mio pulsante. Così ho fatto sth così

<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> 

mio convertitore sembra che

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 
} 

Tuttavia ottengo InvalidCastException in questo convertitore. Che cast è appropriato in quel caso? Io parlo come se HasError fosse un tipo bool, quindi dovrei scritturare per bool.

+0

Che cosa vuol dire "tipo"? Sostituirlo con "if (values.Cast (). Any (val => val))" – vorrtex

risposta

2

Se si crea un riepilogo di convalida, è possibile associare la proprietà del pulsante "Esegui" alla proprietà HasErrors.

È necessario utilizzare una proprietà o un convertitore intermedio come si desidera che IsEnabled sia true quando HasErrors è falso (e viceversa).

+1

Come posso creare un riepilogo di convalida ?? – stylus

+0

@validator - ce n'è uno qui - http://codeblitz.wordpress.com/2009/05/12/wpf-validation-summary-control/ - Mi stavo confondendo con Silverlight, mi dispiace. – 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

Grazie per la risposta, potresti dare di nuovo un'occhiata alla mia domanda: l'ho modificata – stylus

17

Per mostrare il messaggio di errore in un tool tip mettere questo nelle vostre 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> 

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

per abilitare/disabilitare un tasto si potrebbe usare qualcosa lungo la linea

<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> 

oppure è possibile implementare ICommand e utilizzare comm e vincolante.

EDIT

Ecco un esempio completamente funzionante. Visualizza una finestra con due TextBox. Il pulsante è abilitato se e solo se entrambi i TextBox non sono vuoti. Creare un progetto denominato ValidationDemo e mettere i seguenti file in essa contenuti:

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(); 
    } 
    } 
} 

modello.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

sfortunatamente non funziona. Nonostante il fatto che una convalida della mia casella di testo non sia riuscita, il mio pulsante Ok è ancora abilitato – stylus

+0

@validator: ho aggiunto un esempio funzionante. – TomBot

Problemi correlati