如何绑定Silverlight中的帮助器属性

时间:2010-04-01 19:06:17

标签: silverlight data-binding binding dependency-properties

为了争论,这里是一个简单的人类

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并为fullname引发了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 ); }
    }
}

2 个答案:

答案 0 :(得分:3)

我不确定你要在这里实现什么,但为什么你的Person类继承自DependencyObject,为什么是FirstName和LastName DependencyProperties?如果您只想将Person属性绑定到视图上的用户控件,那么实现INotifyPropertyChanged的Person类就足以使数据绑定工作。您通常会将它绑定到作为依赖项属性的用户控件的属性(例如TextBlock的Text属性)。

为你尝试这个人类:

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, 菲尔

答案 1 :(得分: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; }
    }
}