2017-01-18 1 views
0

Ich habe zwei TextBoxes in meiner Ansicht, auf denen ich versuche, eine einfache Validierung mit MVVM Design Pattern zu implementieren. Das Problem ist auch wenn meine ViewModel implementiert Inotification Changed Schnittstelle und die Eigenschaft ist an die Text-Eigenschaft der TextBox gebunden, bei der Eingabe text textureChange-Ereignis nie feuert.Ich weiß nicht, wo ich falsch gelaufen bin. Bitte help.Schlagt mich seit einer ganzen Weile."PropertyChange" wird nicht ausgelöst, wenn Text in Textbox in meiner Ansicht geändert oder eingefügt wird

Ansichtsmodell:

class TextBoxValidationViewModel : ViewModelBase, IDataErrorInfo 
    { 
     private readonly TextBoxValidationModel _textbxValModel; 
     private Dictionary<string, bool> validProperties; 
     private bool allPropertiesValid = false; 

     private DelegateCommand exitCommand; 
     private DelegateCommand saveCommand; 

     public TextBoxValidationViewModel(TextBoxValidationModel newTextBoxValObj) 
     { 
      this._textbxValModel = newTextBoxValObj; 
      this.validProperties = new Dictionary<string, bool>(); 
      this.validProperties.Add("BuyTh", false); 
      this.validProperties.Add("SellTh", false); 


     } 


     public string BuyTh 
     { 
      get { return _textbxValModel.BuyTh; } 
      set 
      { 
       if (_textbxValModel.BuyTh != value) 
       { 
        _textbxValModel.BuyTh = value; 
        base.OnPropertyChanged("BuyTh"); 
       } 
      } 
     } 

     public string SellTh 
     { 
      get { return _textbxValModel.SellTh; } 
      set 
      { 
       if (_textbxValModel.SellTh != value) 
       { 
        _textbxValModel.SellTh = value; 
        base.OnPropertyChanged("SellTh"); 
       } 
      } 
     } 



     public bool AllPropertiesValid 
     { 
      get { return allPropertiesValid; } 
      set 
      { 
       if (allPropertiesValid != value) 
       { 
        allPropertiesValid = value; 
        base.OnPropertyChanged("AllPropertiesValid"); 
       } 
      } 
     } 


     public string this[string propertyName] 
     { 
      get 
      { 
       string error = (_textbxValModel as IDataErrorInfo)[propertyName]; 
       validProperties[propertyName] = String.IsNullOrEmpty(error) ? true : false; 
       ValidateProperties(); 
       CommandManager.InvalidateRequerySuggested(); 
       return error; 
      } 
     } 

     public string Error 
     { 
      get 
      { 
       return (_textbxValModel as IDataErrorInfo).Error; 
      } 
     } 

     public ICommand ExitCommand 
     { 
      get 
      { 
       if (exitCommand == null) 
       { 
        exitCommand = new DelegateCommand(Exit); 
       } 
       return exitCommand; 
      } 
     } 

     public ICommand SaveCommand 
     { 
      get 
      { 
       if (saveCommand == null) 
       { 
        saveCommand = new DelegateCommand(Save); 
       } 
       return saveCommand; 
      } 
     } 



     #region private helpers 

     private void ValidateProperties() 
     { 
      foreach (bool isValid in validProperties.Values) 
      { 
       if (!isValid) 
       { 
        this.AllPropertiesValid = false; 
        return; 
       } 
      } 
      this.AllPropertiesValid = true; 
     } 

     private void Exit() 
     { 
      Application.Current.Shutdown(); 
     } 


     private void Save() 
     { 
      _textbxValModel.Save(); 
     } 

    } 

} 
#endregion 

Modell:

class TextBoxValidationModel : IDataErrorInfo 
    { 

     public string BuyTh { get; set; } 
     public string SellTh { get; set; } 

     public void Save() 
     { 
      //Insert code to save new Product to database etc 
     } 

     public string this[string propertyName] 
     { 
      get 
      { 
       string validationResult = null; 
       switch (propertyName) 
       { 
        case "BuyTh": 
         validationResult = ValidateName(); 
         break; 
        case "SellTh": 
         validationResult = ValidateName(); 
         break; 

        default: 
         throw new ApplicationException("Unknown Property being validated on Product."); 
       } 
       return validationResult; 
      } 
     } 

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


     private string ValidateName() 
     { 

      return "Entered in validation Function"; 
     } 
    } 
} 

ViewModelBase abstrakte Klasse:

public abstract class ViewModelBase : INotifyPropertyChanged 
    { 
     public event PropertyChangedEventHandler PropertyChanged; 

     protected void OnPropertyChanged(string propertyName) 
     { 
      PropertyChangedEventHandler handler = PropertyChanged; 

      if (handler != null) 
      { 
       handler(this, new PropertyChangedEventArgs(propertyName)); 
      } 
     } 
    } 
} 

Anwendung Starten Ereigniscode:

private void Application_Startup(object sender, StartupEventArgs e) 
     { 
      textboxvalwpf.Model.TextBoxValidationModel newTextBoxValObj = new Model.TextBoxValidationModel(); 
      TextBoxValidation _txtBoxValView = new TextBoxValidation(); 
      _txtBoxValView.DataContext = new textboxvalwpf.ViewModel.TextBoxValidationViewModel(newTextBoxValObj); 
     //  _txtBoxValView.Show(); 

     } 
    } 

Ansicht XAML-Code:

<Window x:Class="textboxvalwpf.TextBoxValidation" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:c="clr-namespace:textboxvalwpf.Commands" 
     xmlns:local="clr-namespace:textboxvalwpf" 
     mc:Ignorable="d" 
     Title="TextBoxValidation" Height="300" Width="300"> 
    <Grid> 
     <TextBox x:Name="textBox" HorizontalAlignment="Left" Height="23" Margin="86,44,0,0" TextWrapping="Wrap" Text="{Binding Path=BuyTh, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Width="120"/> 
     <TextBox x:Name="textBox1" HorizontalAlignment="Left" Height="23" Margin="88,121,0,0" TextWrapping="Wrap" Text="{Binding Path=SellTh,ValidatesOnDataErrors=True,UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Width="120"/> 
     <Label x:Name="label_BuyTh" Content="Buy Th" HorizontalAlignment="Left" Margin="10,44,0,0" VerticalAlignment="Top" Width="71"/> 
     <Label x:Name="label_SellTh" Content="Sell Th" HorizontalAlignment="Left" Margin="10,117,0,0" VerticalAlignment="Top" Width="71"/> 

    </Grid> 
</Window> 
+0

Wenn jemand schnell würde einen Blick auf diesen Code blocks.That haben könnte sehr geschätzt werden. – AlphaWarrior

+0

Sie haben die Zeile, in der Sie das Fenster anzeigen, auskommentiert. Ist das so, weil zwei Fenster angezeigt wurden? –

+0

@EdPlunkett: Ja tatsächlich. – AlphaWarrior

Antwort

0

In App.xaml finden Sie eine StartupUri Attribut finden. Standardmäßig sieht es dies wie:

<Application x:Class="WPFTest.App" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:local="clr-namespace:WPFTest" 
      StartupUri="MainWindow.xaml"> 

Wenn Sie MainWindow.xaml zu TextBoxValidation.xaml umbenannt, wie ich glaube, du hast, wird es wie folgt aussehen:

   StartupUri="TextBoxValidation.xaml"> 

Ihre Bewerbung wird automatisch Erstellen Sie eine Instanz dieses StartupUri Fensters und zeigen Sie es an. Das wird das Hauptfenster der Anwendung sein, also wird die Anwendung geschlossen, wenn sie geschlossen wird.

Diese Instanz wird kein Viewmodel haben, weil nichts in Ihrem Code einen gibt. Sie erstellen Ihre eigene Instanz des Fensters, geben ihr ein Ansichtsmodell und tun dann nichts damit, weil eine andere Instanz angezeigt wird. Ich kann mir vorstellen, dass du dachtest, dass das Erstellen des Fensters genug war, um es zu zeigen, aber das ist überhaupt nicht so. Bevor Sie den Aufruf Show() auskommentiert haben, hatten Sie ein Fenster mit einem funktionierenden ViewModel, das die Validierung durchgeführt und die ViewModel-Eigenschaften aktualisiert hat.

Lassen Sie die App das Fenster so erstellen, wie es möchte.

Eine schnelle, einfache Lösung ist, dass Startup Event-Handler von App zu löschen und Ihre Viewmodel Erstellungscode in TextBoxValidation ‚s Konstruktor verschieben:

public TextBoxValidation() 
{ 
    InitializeComponent(); 

    textboxvalwpf.Model.TextBoxValidationModel newTextBoxValObj = new Model.TextBoxValidationModel(); 

    this.DataContext = new textboxvalwpf.ViewModel.TextBoxValidationViewModel(newTextBoxValObj); 
} 
+0

Danke Ed. Das ist jetzt behoben. Ich akzeptiere dies als Antwort für die bessere Erklärung. – AlphaWarrior

Verwandte Themen