【问题标题】:WPF Binding to UserControl Custom DependencyPropertyWPF 绑定到 UserControl 自定义 DependencyProperty
【发布时间】:2013-01-20 14:25:05
【问题描述】:

我有一个名为 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>

我在其中添加了 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();
    }
}

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

<local:SongDescription x:Name="songDescription" Song="{Binding DataContext}"/>

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

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

或者像这样打开窗口:

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

我什至尝试让 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>

没有任何帮助。 TextBlock title 可以很好地绑定歌曲名称。但我不能调用 updateLyrics() 方法。 (在现实生活中这个方法比较复杂,所以我不能像name一样使用Binding)。

谢谢!

【问题讨论】:

    标签: wpf binding user-controls dependency-properties


    【解决方案1】:

    是的,所以这是依赖属性的一个陷阱。您从来没有将验证代码放在访问器方法 (get/set) 中,因为 WPF 将依赖项属性存储在它自己管理的表中。这就是为什么您必须注册依赖属性的原因,它本质上是在此表上创建条目以存储与每个属性关联的值,并且当您使用“GetValue”/“SetValue”时,您正在更新此表上的条目(顺便说一下涉及到 WPF 如何能够管理数据绑定)。

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

    见:

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

    【讨论】:

    • 但是,是PropertyChanged回调,我将无法更新任何控件,因为它是一个共享函数!
    【解决方案2】:

    除了 sircodesalot 的回答之外,您不受歌词文本框的约束。此外,由于您绑定的歌曲是一个类,因此您需要完全指定要在“Path=Song.Lyrics”等框中显示的属性的路径。

    要考虑的另一件事是依赖属性;默认情况下,您的模式将是单向的,因此除非您更改它,否则使文本字段可编辑真的没有实际意义。

    第三,如果您使用的是 MVVM,您只需要将主窗口上下文设置为视图模型并具有匹配的 Song 属性来绑定。

    【讨论】:

      猜你喜欢
      • 2018-12-07
      • 2013-06-03
      • 2012-06-06
      • 2020-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多