2015-11-10 8 views
7

Hallo Guten Tag, ich bin nur neu mit WPF und MVVM Design-Muster und ich habe viel gelernt von den Blogs und Videos von Sir BRIAN LAGUNAS in PRISM .. aber möchte nur eine noob Frage stellen ..hats falsch mit meinem Code es funktioniert für mich ... jede Hilfe ist sehr dankbar, danke. hier ist mein Code:Prism 6 DelegateCommand ObservesProperty Code

MY VIEW MODEL

public class Person : BindableBase 
{ 
    private myPErson _MyPerson; 
    public myPErson MyPerson 
    { 
     get { return _MyPerson; } 
     set 
     { 
      SetProperty(ref _MyPerson, value); 
     } 
    } 

    public Person() 
    { 
     _MyPerson = new myPErson(); 
     updateCommand = new DelegateCommand(Execute, CanExecute).ObservesProperty(() => MyPerson.FirstName).ObservesProperty(() => MyPerson.Lastname); 

    // updateCommand = new DelegateCommand(Execute).ObservesCanExecute((p) => CanExecute); /// JUST WANNA TRY THIS BUT DUNNO HOW 
    } 

    private bool CanExecute() 
    { 
     return !String.IsNullOrWhiteSpace(MyPerson.FirstName) && !String.IsNullOrWhiteSpace(MyPerson.Lastname); 
    } 

    private void Execute() 
    { 
     MessageBox.Show("HOLA"); 
    } 

    public DelegateCommand updateCommand { get; set; } 
} 

MyModel

auf eine andere Klasse Datei erklärt

public class myPErson : BindableBase 
{ 
    private string _firstName; 
    public string FirstName 
    { 
     get { return _firstName; } 
     set 
     { 
      SetProperty(ref _firstName, value); 
     } 
    } 

    private string _lastname; 
    public string Lastname 
    { 
     get { return _lastname; } 
     set 
     { 
      SetProperty(ref _lastname, value); 
     } 
    } 
} 

Ansicht XAML Co de

<Window x:Class="Prism6Test.Views.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:myVM="clr-namespace:Prism6Test.ViewModel" 
     Title="MainWindow" Height="350" Width="525"> 
    <Window.Resources> 
     <myVM:Person x:Key="mainVM"/> 
    </Window.Resources> 
<Grid DataContext="{StaticResource mainVM}"> 
     <TextBox HorizontalAlignment="Left" Height="23" Margin="217,103,0,0" TextWrapping="Wrap" Text="{Binding MyPerson.FirstName,UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Width="120"/> 
     <TextBox HorizontalAlignment="Left" Height="23" Margin="217,131,0,0" TextWrapping="Wrap" Text="{Binding MyPerson.Lastname,UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Width="120"/> 
     <Button Content="Button" Command="{Binding updateCommand}" HorizontalAlignment="Left" Margin="242,159,0,0" VerticalAlignment="Top" Width="75"/> 

    </Grid> 
</Window> 

Ich habe schon diese Zeilen lesen, aber es funktioniert nicht für mich arbeiten .. und kann nicht verstehen, wie kann ich es richtig codieren .. bitte helfen Sie mir ragarding diese Angelegenheit ..HOPE für jede Antwort soon..thx

ObservesProperty method isn't observing model's properties at Prism 6

+0

Was ist der Knopf zu tun? – Jens

+0

Poste ein Nachrichtenfeld "HOLA". – Neil

+0

Okay. Jetzt sehe ich es. Was ist das Problem des Codes? Sie sehen etwas in den TextBoxen nicht? – Jens

Antwort

4

1) `t Sie komplexe Datenmodell verwenden, wie Sie wollen, so versuchen Sie es

private myPErson _MyPerson; 
    public myPErson MyPerson 
    { 
     get { return _MyPerson; } 
     set 
     { 
      if (_MyPerson != null) 
       _MyPerson.PropertyChanged -= MyPersonOnPropertyChanged; 

      SetProperty(ref _MyPerson, value); 


      if (_MyPerson != null) 
       _MyPerson.PropertyChanged += MyPersonOnPropertyChanged; 
     } 
    } 

    private void MyPersonOnPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs) 
    { 
     updateCommand.RaiseCanExecuteChanged(); 
    } 

2) ändern Sie Ihren Konstruktor

public Person() 
    { 
     MyPerson = new myPErson(); 
     updateCommand = new DelegateCommand(Execute, CanExecute); 
    } 
+0

danke .. !!! es funktioniert für mich jetzt sir @ galakt .. – Neil

+0

@Neil Markieren Sie diese Antwort als Lösung bitte, wenn es Ihnen geholfen – galakt

3

Zuerst muss ich etwas über Ihre Benennung sagen. Nennen Sie Ihre Klassen klar. Rufen Sie Ihr ViewModel z. PersonViewModel oder nur ViewModel wenn Ihre Anwendung ist nicht so groß und nicht Person, weil Person ist offensichtlich die Modell. Außerdem ist ein sehr schlechter Name, weil er Ihrer anderen Person Klasse sehr ähnlich ist und Sie sollten Ihre Klassennamen PascalCase haben.

Jetzt zu Ihrem Code. Ich weiß nichts über Prism, also hängt mein Code auf dem MVVM Muster nur ohne die Unterstützung der Prism Bibliotheken ab.

Zuerst möchte ich die ModellPerson ändern. Die Klasse in meinem Code sehr einfach aussieht (nur verwendet Auto Eigenschaften):

public class Person 
{ 
    public string FirstName { get; set; } 

    public string LastName { get; set; } 

    public Person() 
    { 
     this.LastName = string.Empty; 
     this.FirstName = string.Empty; 
    } 
} 

Die PersonViewModel ist ein littlebit komplexer, weil es die INotifyPropertyChanged-Schnittstelle implementiert. Ich verwende auch die sehr häufige RelayCommand, die Sie im Link unter der angenommenen Antwort finden können.

public class PersonViewModel : INotifyPropertyChanged 
{ 
    private Person person; 

    private ICommand updateCommand; 

    public PersonViewModel() 
    { 
     this.Person = new Person(); 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    public Person Person 
    { 
     get 
     { 
      return this.person; 
     } 

     set 
     { 
      this.person = value; 

      // if you use VS 2015 or/and C# 6 you also could use 
      // this.OnPropertyChanged(nameof(Person)); 
      this.OnPropertyChanged("Person"); 
     } 
    } 

    public ICommand UpdateCommand 
    { 
     get 
     { 
      if (this.updateCommand == null) 
      { 
       this.updateCommand = new RelayCommand<Person>(this.OpenMessageBox, this.OpenMessageBoxCanExe); 
      } 

      return this.updateCommand; 
     } 
    } 

    [NotifyPropertyChangedInvocator] 
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) 
    { 
     PropertyChangedEventHandler handler = this.PropertyChanged; 
     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

    private void OpenMessageBox(Person person) 
    { 
     MessageBox.Show("Hola"); 
    } 

    private bool OpenMessageBoxCanExe(Person person) 
    { 
     if (person == null) 
     { 
      return false; 
     } 

     if (string.IsNullOrWhiteSpace(person.FirstName) || string.IsNullOrWhiteSpace(person.LastName)) 
     { 
      return false; 
     } 

     return true; 
    } 
} 

Ich habe Ihr View ein wenig aufgeklärt, weil es jetzt viel kürzer ist. aber alles in allem ist alles gleich geblieben. i umbenannt nur die Eigenschaften und Sachen:

<Window ...> 
    <Window.Resources> 
     <wpfTesst:PersonViewModel x:Key="ViewModel" /> 
    </Window.Resources> 
    <Grid DataContext="{StaticResource ViewModel}"> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="Auto"/> 
      <RowDefinition Height="Auto"/> 
      <RowDefinition Height="Auto"/> 
     </Grid.RowDefinitions> 
     <TextBox Grid.Row="0" TextWrapping="Wrap" Text="{Binding Person.FirstName, UpdateSourceTrigger=PropertyChanged}" /> 
     <TextBox Grid.Row="1" TextWrapping="Wrap" Text="{Binding Person.LastName, UpdateSourceTrigger=PropertyChanged}" /> 
     <Button Grid.Row="2" Content="Button" Command="{Binding UpdateCommand}" CommandParameter="{Binding Person}"/> 
    </Grid> 
</Window> 

Alles in allem ich Ihnen empfehlen würde das gemeinsame MVVM Muster ohne die Prism-Bibliothek zu verwenden.Wenn Sie MVVM gut verstanden haben, können Sie sich für Prism entscheiden. Hoffe es hilft.

+0

danke für Ihren Vorschlag sir @Jens Horstmann..und das wird mir helfen, meine Codierung zu verbessern..aus Neugier gerade Willst du die PRISM-Bibliothek benutzen und darin studieren? Kann ich von dir einen Link für meine Referenz anfordern? für zukünftige studie ... bitte bitte ... thx sehr viel – Neil

+0

@ Neil tun was du willst mit deinen links = P – Jens

+0

haha ​​.. irgendeinen vorgeschlagenen link von dir sir^_^.... für meine zukünftige reference sir..i Studieren ... bitte bitte ... @Jens Horstmann – Neil

0

anzeigen XAML-Code

<Window x:Class="Prism6Test.Views.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:myVM="clr-namespace:Prism6Test.ViewModel" 
    Title="MainWindow" Height="350" Width="525"> 

Sie vermissen die ViewModelLocator

xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms" 
    prism:ViewModelLocator.AutowireViewModel="True"