如何绑定到 Silverlight 中的辅助属性

发布于 2024-08-27 01:44:22 字数 3691 浏览 2 评论 0原文

为了便于讨论,这里有一个简单的 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 ); }
    }
}

For the sake of argument, here's a simple person class

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

I want to go about creating a readonly property like this

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

How does binding work in this scenario? I've tried adding a DependancyProperty and raised the PropertyChanged event for the fullname. Basically I just want to have a property that I can bind to that returns the fullname of a user whenever the first or last name changes. Here's the final class I'm using with the 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 ); }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

美人骨 2024-09-03 01:44:22

我不确定您想在这里实现什么,但为什么您的 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,
菲尔

I'm not sure what you are trying to achieve here, but why is your Person class inheriting from DependencyObject and why are FirstName and LastName DependencyProperties? If all you want to do is bind the Person properties to user controls on your view, having the Person class implementing INotifyPropertyChanged is enough to make the data binding work. You will typically bind it to properties of a user control that are dependency properties (eg the Text property of a TextBlock).

Try this for you Person class:

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

And use it like this in your view:

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

Then, in your codebehind, you could instantiate it like so:

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

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

HTH,
Phil

剑心龙吟 2024-09-03 01:44:22

首先,您现有的 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; }
    }
}

First of all your implementation of the existing FirstName and LastName properties is flawed. The DependencyObject already has ways to inform bindings of changes to the values and values can be changed by other mechanism than calling the Setter methods.

My first question would be why are FirstName and LastName dependency properties at all? That seems like a strange choice for this type of class. Phil's answer has already provided what I would really expect the correct answer to be.

However in case your code was actually a simplification and that there is in fact a genuine need to create dependency properties here is how it should be done:-

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; }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文