2009-10-15 7 views
2

Dans l'exemple suivant, la propriété Message se lie correctement mais les propriétés Prénom, Nom et Âge de l'objet Client sont vides. Pourquoi donc?Comment lier un objet personnalisé dans code-behind à une grille dans XAML?

XAML:

<Window x:Class="TestBinding9922.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="Window1" Height="300" Width="300"> 
    <StackPanel> 

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

     <Grid DataContext="{Binding Customer}" > 
      <Grid.RowDefinitions> 
       <RowDefinition Height="Auto" /> 
       <RowDefinition Height="Auto" /> 
       <RowDefinition Height="Auto" /> 
      </Grid.RowDefinitions> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition Width="Auto" /> 
       <ColumnDefinition Width="Auto" /> 
      </Grid.ColumnDefinitions> 

      <Label Grid.Column="0" Grid.Row="0" Content="First Name:" /> 
      <Label Grid.Column="0" Grid.Row="1" Content="Last Name:" /> 
      <Label Grid.Column="0" Grid.Row="2" Content="Age:" /> 

      <TextBox Grid.Column="1" Grid.Row="0" Text="{Binding FirstName}" /> 
      <TextBox Grid.Column="1" Grid.Row="1" Text="{Binding LastName}" /> 
      <TextBox Grid.Column="1" Grid.Row="2" Text="{Binding Age}" /> 

     </Grid> 

    </StackPanel> 
</Window> 

code-behind:

using System.Windows; 
using System.ComponentModel; 

namespace TestBinding9922 
{ 
    public partial class Window1 : Window, INotifyPropertyChanged 
    { 
     public string Message { get; set; } 
     public Customer Customer { get; set; } 

     public Window1() 
     { 
      InitializeComponent(); 
      DataContext = this; 

      Message = "this works"; 

      Customer customer = new Customer() { FirstName = "Jim", LastName = "Smith", Age = 45 }; 
     } 
    } 

    public class Customer 
    { 
     public string FirstName { get; set; } 
     public string LastName { get; set; } 
     public int Age { get; set; } 
    } 
} 

Addendum:

Même quand j'utilise INotifyPropertyChanged, les zones de texte sont toujours vide:

using System.Windows; 
using System.ComponentModel; 

namespace TestBinding9922 
{ 
    public partial class Window1 : Window, INotifyPropertyChanged 
    { 
     #region ViewModelProperty: Message 
     private string _message; 
     public string Message 
     { 
      get 
      { 
       return _message; 
      } 

      set 
      { 
       _message = value; 
       OnPropertyChanged("Message"); 
      } 
     } 
     #endregion 

     #region ViewModelProperty: Customer 
     private Customer _customer; 
     public Customer Customer 
     { 
      get 
      { 
       return _customer; 
      } 

      set 
      { 
       _customer = value; 
       OnPropertyChanged("Customer"); 
      } 
     } 
     #endregion 

     public Window1() 
     { 
      InitializeComponent(); 
      DataContext = this; 

      Message = "this works"; 

      Customer customer = new Customer() { FirstName = "Jim", LastName = "Smith", Age = 45 }; 
     } 

     #region INotifiedProperty Block 
     public event PropertyChangedEventHandler PropertyChanged; 

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

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

    } 

    public class Customer 
    { 
     public string FirstName { get; set; } 
     public string LastName { get; set; } 
     public int Age { get; set; } 
    } 

} 

Répondre

3

Votre classe Customer doit implémenter INotifyPropertyChanged et, par conséquent, les propriétés en cours de modification doivent être notifiées lorsqu'elles sont modifiées.

Vous pouvez trouver un exemple de ceci here, entre autres.

De même, vous n'instanciez pas la propriété de votre client, vous créez une variable locale; Il devrait être:

Customer = new Customer() 
    { FirstName = "Jim", LastName = "Smith", Age = 45 }; 
+0

Je ne peux pas croire que l'auteur de l'entrée de blog que vous avez lié à considère sa solution simple et élégante. Si WPF simplifiait vraiment le développement, je serais un fan, mais après l'avoir utilisé un peu, je pense qu'il ne fait que pousser la douleur vers des zones nouvelles et non documentées. – PeterAllenWebb

+0

merci, j'ai supervisé que je définissais une variable locale, cela fonctionne maintenant, même sans le INotifyPropertyChanged –

+0

@Peter Oui liaison de données n'est pas une jolie chose en ce moment. Je ne suis même pas sûr que tu en aies besoin tout le temps. Je suis assez sûr que vous aurez besoin d'implémenter un schéma INotifyPropertyChanged si vous faites une liaison bidirectionnelle. – Joseph

2

Il semble que vous affectiez la nouvelle instance client à une variable locale "client" au lieu de la propriété de votre fenêtre.

0

Vous pouvez supprimer le réglage de la DataContext pour la grille dans le XAML, puis lier les zones de texte à Client.Prénom, etc.

Ou, vous pouvez supprimer le réglage du DataContext pour la grille dans la XAML, comme précédemment, mais donnez un nom à la grille, puis définissez son DataContext dans le code-behind, comme vous l'avez fait pour la fenêtre.

Questions connexes