2010-04-01 81 views
1

为了讨论的方便,这里有一个简单的人类我如何可以绑定到一个辅助属性在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")); 
     } 
    } 
} 

我希望去建立一个只读属性,这样

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

如何在这种情况下绑定工作?我试着添加一个DependancyProperty并为全名引发PropertyChanged事件。基本上我只想拥有一个我可以绑定的属性,只要名字或姓氏改变,就会返回用户的全名。这是我在修改中使用的最后一堂课。

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); } 
    } 
} 

回答

3

我不知道你正试图在这里实现什么,但为什么你的Person类自DependencyObject继承和为什么名字和姓氏DependencyProperties?如果您只想将Person属性绑定到视图上的用户控件,使Person类实现INotifyPropertyChanged足以使数据绑定起作用。您通常会将其绑定到依赖项属性(例如TextBlock的Text属性)的用户控件的属性。

试试这个你Person类:

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; } 
    } 
} 

而且在你看来像这样使用:

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

然后,在你的代码隐藏,那么你可以像这样:

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

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

HTH, Phil

+0

+1,这看起来不错我。 – AnthonyWJones 2010-04-01 21:53:34

+0

我很新,在Silverlight中绑定。我发现的大多数例子都使用了DependencyProperty。最重要的是,我实际上无法让我的绑定工作,直到我开始使用依赖属性。到目前为止,学习Silverlight绑定对我来说是一场稳步的艰苦战斗。 – Matt 2010-04-01 22:15:24

1

首先,您现有的FirstName和LastName属性的实现存在缺陷。 DependencyObject已经有方法通知绑定的值和值的变化可以通过调用Setter方法之外的其他机制来改变。

我的第一个问题是为什么FirstNameLastName依赖属性呢?这对于这类课程来说似乎是一个奇怪的选择。菲尔的回答已经提供了我真正期待正确答案的东西。

但是如果你的代码实际上是一个简化和有其实真正需要在这里创建依赖属性是它应该怎么做: -

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; } 
    } 
}