2010-04-01 4 views
1

Pour les besoins du raisonnement, voici une classe simple personneComment puis-je lier à une propriété d'aide dans Silverlight

public class Person : DependencyObject, INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    public static readonly DependencyProperty FirstNameProperty = 
     DependencyProperty.Register("FirstName", 
            typeof (string), 
            typeof (Person), 
            null); 
    public static readonly DependencyProperty LastNameProperty = 
     DependencyProperty.Register("LastName", 
            typeof(string), 
            typeof(Person), 
            null); 

    public string FirstName 
    { 
     get 
     { 
      return (string) GetValue(FirstNameProperty); 
     } 
     set 
     { 
      SetValue(FirstNameProperty, value); 
      if(PropertyChanged != null) 
       PropertyChanged(this, new PropertyChangedEventArgs("FirstName")); 
     } 
    } 

    public string LastName 
    { 
     get 
     { 
      return (string) GetValue(LastNameProperty); 
     } 
     set 
     { 
      SetValue(LastNameProperty, value); 
      if (PropertyChanged != null) 
       PropertyChanged(this, new PropertyChangedEventArgs("LastName")); 
     } 
    } 
} 

Je veux aller sur la création d'une propriété readonly comme celui-ci

public string FullName 
    { 
     get { return FirstName + " " + LastName; } 
    } 

Comment fait le travail obligatoire dans ce scénario? J'ai essayé d'ajouter un DependancyProperty et soulevé l'événement PropertyChanged pour le nom complet. Fondamentalement, je veux juste avoir une propriété que je peux lier à qui renvoie le nom complet d'un utilisateur à chaque fois que le prénom ou le nom change. Voici la dernière classe que j'utilise avec les modifications.

public class Person : DependencyObject, INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    public static readonly DependencyProperty FirstNameProperty = 
     DependencyProperty.Register("FirstName", 
            typeof (string), 
            typeof (Person), 
            null); 
    public static readonly DependencyProperty LastNameProperty = 
     DependencyProperty.Register("LastName", 
            typeof(string), 
            typeof(Person), 
            null); 
    public static readonly DependencyProperty FullNameProperty = 
     DependencyProperty.Register("FullName", 
            typeof(string), 
            typeof(Person), 
            null); 

    public string FirstName 
    { 
     get 
     { 
      return (string) GetValue(FirstNameProperty); 
     } 
     set 
     { 
      SetValue(FirstNameProperty, value); 
      if (PropertyChanged != null) 
      { 
       PropertyChanged(this, new PropertyChangedEventArgs("FirstName")); 
       PropertyChanged(this, new PropertyChangedEventArgs("FullName")); 
      } 
     } 
    } 

    public string LastName 
    { 
     get 
     { 
      return (string) GetValue(LastNameProperty); 
     } 
     set 
     { 
      SetValue(LastNameProperty, value); 
      if (PropertyChanged != null) 
      { 
       PropertyChanged(this, new PropertyChangedEventArgs("LastName")); 
       PropertyChanged(this, new PropertyChangedEventArgs("FullName")); 
      } 
     } 
    } 

    public string FullName 
    { 
     get { return GetValue(FirstNameProperty) + " " + GetValue(LastNameProperty); } 
    } 
} 

Répondre

3

Je ne suis pas sûr de ce que vous essayez d'atteindre ici, mais pourquoi est votre classe de personne héritant de DependencyObject et pourquoi sont FirstName et LastName DependencyProperties? Si tout ce que vous voulez faire est de lier les propriétés Person aux contrôles utilisateur de votre vue, avoir la classe Person implémentant INotifyPropertyChanged est suffisant pour que la liaison de données fonctionne. Vous le lierz généralement aux propriétés d'un contrôle utilisateur qui sont des propriétés de dépendance (par exemple, la propriété Text d'un TextBlock).

Essayez pour vous classe Personne:

using System.ComponentModel; 
public class Person : INotifyPropertyChanged 
{ 
    #region INotifyPropertyChanged Members 

    public event PropertyChangedEventHandler PropertyChanged; 

    private void RaisePropertyChanged(string propertyName) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

    #endregion 

    private string _firstName; 
    public string FirstName 
    { 
     get { return _firstName; } 
     set 
     { 
      if (value != _firstName) 
      { 
       _firstName = value; 
       RaisePropertyChanged("FirstName"); 
       RaisePropertyChanged("FullName"); 
      } 
     } 
    } 

    private string _lastName; 
    public string LastName 
    { 
     get { return _lastName; } 
     set 
     { 
      if (value != _lastName) 
      { 
       _lastName = value; 
       RaisePropertyChanged("LastName"); 
       RaisePropertyChanged("FullName"); 
      } 
     } 
    } 

    public string FullName 
    { 
     get { return FirstName + " " + LastName; } 
    } 
} 

Et l'utiliser comme ceci dans votre vue:

<Grid x:Name="LayoutRoot" Background="White" > 
    <TextBlock Text="{Binding FullName}"/> 
</Grid> 

Ensuite, dans votre behind, vous pouvez instancier comme ceci:

public partial class MainPage : UserControl 
{ 
    public MainPage() 
    { 
     InitializeComponent(); 

     DataContext = new Person { FirstName = "John", LastName = "Doe" }; 
    } 
} 

HTH, Phil

+0

+1, cela ressemble bien moi. – AnthonyWJones

+0

Je suis très nouveau à Binding dans Silverlight. La plupart des exemples que j'ai trouvés utilisent tous DependencyProperty. En plus de cela, je ne pouvais pas vraiment faire fonctionner ma liaison avant d'avoir commencé à utiliser les propriétés de dépendance. L'apprentissage de la liaison Silverlight a été une bataille constante pour moi jusqu'ici. – Matt

1

Tout d'abord, votre implémentation des propriétés FirstName et LastName existantes est erronée. DependencyObject a déjà des moyens d'informer les liaisons des modifications apportées aux valeurs et les valeurs peuvent être modifiées par un autre mécanisme que l'appel des méthodes Setter.

Ma première question serait pourquoi sont FirstName et LastName propriétés de dépendance? Cela semble être un choix étrange pour ce type de classe. La réponse de Phil a déjà fourni ce que j'attendrais vraiment de la bonne réponse.

Cependant dans le cas où votre code était en fait une simplification et qu'il est en fait un réel besoin de créer des propriétés de dépendance ici est la façon dont il devrait être fait: -

public class Person : DependencyObject, INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    public static readonly DependencyProperty FirstNameProperty = 
     DependencyProperty.Register("FirstName", 
            typeof (string), 
            typeof (Person), 
            OnNamePropertyChanged); 

    public static readonly DependencyProperty LastNameProperty = 
     DependencyProperty.Register("LastName", 
            typeof(string), 
            typeof(Person), 
            OnNamePropertyChanged); 

    private static void OnNamePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     ((Person)d).OnNamePropertyChanged(); 
    } 

    private void OnNamePropertyChanged() 
    { 
     if (PropertyChanged != null) 
     PropertyChanged(this, new PropertyChangedEventArgs("FullName"))); 
    } 

    public string FirstName 
    { 
     get { return GetValue(FirstNameProperty) as string; } 
     set { SetValue(FirstNameProperty, value); } 
    } 

    public string LastName 
    { 
     get { return GetValue(LastNameProperty) as string; } 
     set { SetValue(LastNameProperty, value); } 
    } 
    public string FullName 
    { 
     get { return FirstName + " " + LastName; } 
    } 
} 
Questions connexes