2012-09-19 25 views
8

Sembra che ho letto un'altra domanda/risposta su questo sito su questo problema, ma non riesco a ricordare quale fosse la risposta e ora non riesco a trovare il post originale.Progettazione modello di errore

Non sono un fan del modello di errore predefinito in WPF. Capisco come cambiare questo modello di errore. Tuttavia, se aggiungo del contenuto alla fine di, ad esempio, una casella di testo, la dimensione della casella di testo non cambia e il contenuto aggiunto (potenzialmente) verrà troncato. Come posso modificare la casella di testo (credo che la termonologia corretta sia elemento adornato) in questo scenario in modo che nulla venga troncato?

Ecco il codice XAML per il modello di errore:

<Style TargetType="{x:Type TextBox}"> 
    <Setter Property="Validation.ErrorTemplate"> 
    <Setter.Value> 
     <ControlTemplate> 
     <StackPanel> 
      <AdornedElementPlaceholder /> 
      <TextBlock Foreground="Red" Text="Error..." /> 
     </StackPanel> 
     </ControlTemplate> 
    </Setter.Value> 
    </Setter> 
</Style> 

Ecco il codice XAML per un paio di caselle di testo nella forma:

<StackPanel> 
    <TextBox Text="{Binding...}" /> 
    <TextBox /> 
</StackPanel> 
+2

Si prega di aggiungere il relativo XAM Codice L alla domanda – Spontifixus

+0

Ho aggiunto XAML che potrebbe essere utilizzato. XAML è molto più semplice di quello che userei ma dimostra correttamente il problema. Qualsiasi messaggio di errore verrebbe effettivamente visualizzato sulla seconda casella di testo. Vorrei che la seconda casella di testo * si spostasse automaticamente verso il basso quando viene visualizzato un messaggio di errore per la prima casella di testo (e si sposta indietro quando il messaggio di errore scompare). –

risposta

10

due settimane fa, stavo affrontando lo stesso problema .

Ho trovato una soluzione, dopo aver visto questo blog di Josh Smith.

http://joshsmithonwpf.wordpress.com/2008/10/08/binding-to-validationerrors0-without-creating-debug-spew/

Il trucco è quello di definire un DataTemplate per rendere l'oggetto ValidationError e quindi utilizzare un ContentPresenter per visualizzare il messaggio di errore. Se non ci sono errori, il ContentPresenter non verrà visualizzato.

Di seguito, ho condiviso il codice dell'app campione che ho creato.

Without errorsWith errors

Ecco il codice XAML:

<Window x:Class="WpfApplication1.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     SizeToContent="WidthAndHeight" 
     Title="MainWindow"> 
    <StackPanel Margin="5"> 
     <StackPanel.Resources> 
      <DataTemplate DataType="{x:Type ValidationError}"> 
       <TextBlock Text="{Binding ErrorContent}" Foreground="White" Background="Red" VerticalAlignment="Center" FontWeight="Bold"/> 
      </DataTemplate> 
     </StackPanel.Resources> 
     <TextBox Name="TextBox1" Text="{Binding Text1, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}"/> 
     <ContentPresenter Content="{Binding ElementName= TextBox1, Path=(Validation.Errors).CurrentItem}" HorizontalAlignment="Left"/> 

     <TextBox Name="TextBox2" Text="{Binding Text2, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}"/> 
     <ContentPresenter Content="{Binding ElementName= TextBox2, Path=(Validation.Errors).CurrentItem}" HorizontalAlignment="Left"/> 
     <Button Content="Validate" Click="Button_Click"/> 
    </StackPanel> 
</Window> 

Il codice al file:

namespace WpfApplication1 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window 
    { 
     private ViewModel _ViewModel = null; 

     public MainWindow() 
     { 
      InitializeComponent(); 
      _ViewModel = new ViewModel(); 
      DataContext = _ViewModel; 
     } 

     private void Button_Click(object sender, RoutedEventArgs e) 
     { 
      _ViewModel.Validate = true; 
      _ViewModel.OnPropertyChanged("Text1"); 
      _ViewModel.OnPropertyChanged("Text2"); 
     } 
    } 
} 

Il ViewModel:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.ComponentModel; 

namespace WpfApplication1 
{ 
    public class ViewModel : INotifyPropertyChanged, IDataErrorInfo 
    { 
     private string _Text1; 
     public string Text1 
     { 
      get { return _Text1; } 
      set 
      { 
       _Text1 = value; 
       OnPropertyChanged("Text1"); 
      } 
     } 

     private string _Text2; 
     public string Text2 
     { 
      get { return _Text2; } 
      set 
      { 
       _Text2 = value; 
       OnPropertyChanged("Text2"); 
      } 
     } 

     public bool Validate { get; set; } 

     #region INotifyPropertyChanged Implemenation 
     public event PropertyChangedEventHandler PropertyChanged; 

     public void OnPropertyChanged(string propertyName) 
     { 
      if (PropertyChanged != null) 
       PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
     #endregion 

     #region IDataErrorInfo Implementation 
     public string Error 
     { 
      get { return null; } 
     } 

     public string this[string columnName] 
     { 
      get 
      { 
       string errorMessage = string.Empty; 
       if (Validate) 
       { 
        switch (columnName) 
        { 
         case "Text1": 
          if (Text1 == null) 
           errorMessage = "Text1 is mandatory."; 
          else if (Text1.Trim() == string.Empty) 
           errorMessage = "Text1 is not valid."; 
          break; 
         case "Text2": 
          if (Text2 == null) 
           errorMessage = "Text2 is mandatory."; 
          else if (Text2.Trim() == string.Empty) 
           errorMessage = "Text2 is not valid."; 
          break; 
        } 
       } 
       return errorMessage; 
      } 
     } 
     #endregion 
    } 
} 
+0

Grazie per la risposta. Mi ero dimenticato di controllare se ci fossero delle risposte. L'esempio che hai fornito ha fatto esattamente quello che stavo cercando di realizzare. –

+0

Grazie per quel pezzo di gioiello. Esattamente quello che stavo cercando. Non trovi nessun buon esempio +1 – Andez

Problemi correlati