WPF绑定到UserControl自定义DependencyProperty

gs_*_*lad 6 wpf binding user-controls dependency-properties

我有一个名为SongDescription的自定义UserControl:

<UserControl x:Class="DPTestAp.SongDescription" ...>
    <Grid x:Name="LayoutRoot">
        <DockPanel Height="50">
            <TextBlock x:Name="title" Text="{Binding name}" Width="100" Height="30"/>
            <TextBox x:Name="lyrics"/>
        </DockPanel>
    </Grid>
</UserControl>
Run Code Online (Sandbox Code Playgroud)

我添加了DependencyProperty:

public partial class SongDescription : UserControl
{
    public static readonly DependencyProperty SongProperty = DependencyProperty.Register("Song", typeof(Song), typeof(SongDescription));

    public Song Song
    {
        get
        {
            return (Song)GetValue(SongProperty);
        }
        set
        {
            SetValue(SongProperty, value);
            updateLyrics()
        }
    }

    private void updateLyrics()
    {
        lyrics.Text = Song.lyrics;
    }

    public SongDescription()
    {
        InitializeComponent();
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是:如何将某些东西绑定到这个SongProperty?我在我的主窗口中使用SongDescription,如下所示:

<local:SongDescription x:Name="songDescription" Song="{Binding DataContext}"/>
Run Code Online (Sandbox Code Playgroud)

我无法让我的TextBox 歌词显示歌词.在主窗口中,我尝试将DataContext设置为songDescription,如下所示:

songDescription.DataContext = new Song() { name="Home", lyrics="Hold on, to me as we go" };
Run Code Online (Sandbox Code Playgroud)

或像这样的窗口:

DataContext = new Song() { name="Home", lyrics="Hold on, to me as we go" };
Run Code Online (Sandbox Code Playgroud)

我甚至尝试将Song作为资源并将其绑定到SongProperty,如下所示:

<Window.Resources>
    <local:Song x:Key="res" name="Home" lyrics="Hold on, to me as we go"/>
</Window.Resources>
<Grid>
    <local:SongDescription x:Name="songDescription" Song="{StaticResource res}"/>
</Grid>
Run Code Online (Sandbox Code Playgroud)

什么都没有帮助.TextBlock 标题将歌曲名称绑定.但我无法调用updateLyrics()方法.(在现实生活中这种方法比较复杂,所以我不能像名字那样使用Binding).

谢谢!

sir*_*lot 9

是的,所以这是一个依赖属性的问题.您永远不会将验证代码放在访问器方法(get/set)中,因为依赖项属性由WPF存储在它自己管理的表中.这就是为什么你必须注册依赖属性,它实际上在这个表上创建条目用于存储与每个属性关联的值,当你使用'GetValue'/'SetValue'时,你正在更新这个表上的条目(顺便说一下与WPF如何能够管理数据绑定有关.

这样做的结果是,WPF可以(并且将)完全绕过您的属性访问器,因为它可以直接访问真实数据.如果它可以直接转到数据,为什么要使用你的访问器.相反,您需要实现'PropertyChanged'回调函数或一些WPF认可的验证方法,但永远不要在您的访问器中执行.

看到:

http://msdn.microsoft.com/en-us/library/ms752914.aspx