2016-01-07 1 views
0

Certes, je suis nouveau à wpf. Mais j'ai passé du temps à googler à ce sujet et je suis perplexe.Ma propriété ne se met pas à jour en utilisant [CallerMemberName]

Je veux essentiellement mettre à jour mon TextBlock dans mon interface utilisateur à l'aide de Binding chaque fois que mes valeurs de modèle changent.

Alors ceci est mon modèle:

using System.ComponentModel; 
using System.Runtime.CompilerServices; 

namespace WpfApplication1 
{ 
    public class MyModel : INotifyPropertyChanged 
    { 
     protected void OnPropertyChanged([CallerMemberName] string propertyName = null) 
     { 
      this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 

     protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null) 
     { 
      if (Equals(storage, value)) 
      { 
       return false; 
      } 

      storage = value; 
      this.OnPropertyChanged(propertyName); 
      return true; 
     } 

     public string MyField { get; set ; } 
    } 
} 

Ceci est mon interface utilisateur:

<Window x:Class="WpfApplication1.MainWindow" 
     xmlns:viewModels="clr-namespace:WpfApplication1" 
     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:local="clr-namespace:WpfApplication1" 
     d:DataContext="{d:DesignInstance viewModels:MyModel, IsDesignTimeCreatable=True}" 
     mc:Ignorable="d" 
     Title="MainWindow" Height="350" Width="525"> 
    <Window.DataContext> 
     <viewModels:MyModel></viewModels:MyModel> 
    </Window.DataContext> 
    <Grid> 
     <StackPanel Orientation="Vertical"> 
      <TextBlock Text="{Binding MyModel.MyField}"></TextBlock> 
      <Button Content="Click Me!" Click="Button_Click" /> 
     </StackPanel> 
    </Grid> 
</Window> 

Ceci est mon code derrière:

utilisant System.Windows;

namespace WpfApplication1 
{ 
    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
     } 
     public MyModel myModel = new MyModel(); 


     private void Button_Click(object sender, RoutedEventArgs e) 
     { 
      myModel.MyField = "has worked"; 
     } 
    } 
} 

Lorsque j'appuie sur le bouton, le texte ne change pas sur l'interface utilisateur ..?

Répondre

3

L'instance que vous créez dans le code derrière n'est pas la même que celle que vous avez assignée dans xaml.

Modifier l'événement click de bouton pour

private void Button_Click(object sender, RoutedEventArgs e) 
{ 
    var model = this.DataContext as MyModel; 
    model.MyField = "has worked"; 
} 

Et la liaison en XAML à

<TextBlock Text="{Binding MyField}"></TextBlock> 

Et dans votre viewmodel vous n'êtes pas appeler notify changé la propriété. Créez donc un champ privé et modifiez la propriété comme ci-dessous.

private string myField; 

public string MyField 
{ 
    get { return this.myField; } 
    set { this.SetProperty(ref this.myField, value); } 
} 
+0

merci beaucoup pour une réponse aussi claire et simple. Je peux accepter dans 3 minutes. Incidemment, le même peut-il être réalisé en utilisant une classe/propriété statique? –

+0

La classe statique ne peut pas implémenter l'interface INotifyPropertyChanged. Utilisez l'instance singleton pour lier "statiquement" avec {x: Static MyClass.Instance.Property}. –

+0

ta pour répondre. Je sais ce qu'est une classe Singleton mais je ne sais pas comment l'appliquer dans le contexte à cela? –