【问题标题】:How can I bind to a helper property in Silverlight如何绑定到 Silverlight 中的辅助属性
【发布时间】:2011-02-03 12:15:20
【问题描述】:

为了论证,这里是一个简单的person类

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

【问题讨论】:

    标签: silverlight data-binding binding dependency-properties


    【解决方案1】:

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

    我的第一个问题是为什么 FirstName 和 LastName 依赖属性?对于这类课程来说,这似乎是一个奇怪的选择。 Phil 的回答已经提供了我真正期望的正确答案。

    但是,如果您的代码实际上是一个简化,并且实际上确实需要创建依赖属性,那么应该这样做:-

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

    【讨论】:

      【解决方案2】:

      我不确定你在这里想要实现什么,但为什么你的 Person 类继承自 DependencyObject 以及为什么 FirstName 和 LastName 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, 菲尔

      【讨论】:

      • 我对 Silverlight 中的绑定非常陌生。我发现的大多数示例都使用 DependencyProperty。最重要的是,在我开始使用依赖属性之前,我实际上无法让我的绑定工作。到目前为止,学习 Silverlight 绑定对我来说一直是一场艰苦的战斗。
      猜你喜欢
      • 2011-07-05
      • 2011-07-15
      • 1970-01-01
      • 2012-01-31
      • 2011-02-15
      • 1970-01-01
      • 2010-12-11
      • 1970-01-01
      • 2011-07-29
      相关资源
      最近更新 更多