WPF 绑定到 UserControl 自定义 DependencyProperty
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14711274/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WPF Binding to UserControl Custom DependencyProperty
提问by gs_vlad
I have a custom UserControl called SongDescription:
我有一个名为 SongDescription 的自定义用户控件:
<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>
I added DependencyProperty to it:
我添加了 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();
}
}
The question is: how to bind something to this SongProperty? I use SongDescription in my main window like this:
问题是:如何将一些东西绑定到这个 SongProperty?我在主窗口中使用 SongDescription 如下:
<local:SongDescription x:Name="songDescription" Song="{Binding DataContext}"/>
I cannot make my TextBox lyricsshow lyrics. In main window I tried to set DataContext to songDescription, like this:
我无法让我的 TextBox歌词显示歌词。在主窗口中,我尝试将 DataContext 设置为 SongDescription,如下所示:
songDescription.DataContext = new Song() { name="Home", lyrics="Hold on, to me as we go" };
or to window itself like this:
或者像这样窗口自己:
DataContext = new Song() { name="Home", lyrics="Hold on, to me as we go" };
I even tried to make Song a resource and bind it to SongProperty like this:
我什至尝试将 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>
Nothing helped. TextBlock titlebinds song name fine. But I can't make updateLyrics() method be called. (In real life this method is more complicated, so I can't use Binding like with name).
没有任何帮助。TextBlock标题绑定歌曲名称很好。但我无法调用 updateLyrics() 方法。(在现实生活中,这种方法更复杂,所以我不能像 name 一样使用 Binding)。
Thank you!
谢谢!
回答by sircodesalot
Yup, so that's a gotcha with dependency properties. You never everput validation code inside of the accessor methods (get/set) because dependency properties are stored by WPF in a table that it itself manages. This is why you have to register dependency properties, it essentially creates entries on this table for storing the values associated with each property, and when you use 'GetValue' / 'SetValue' you are updating the entries on this table (which by the way relates to how WPF is able to manage data bindings in general).
是的,这是一个具有依赖属性的问题。您永远不会将验证代码放在访问器方法(get/set)中,因为依赖属性由 WPF 存储在它自己管理的表中。这就是您必须注册依赖属性的原因,它本质上是在此表上创建条目以存储与每个属性关联的值,并且当您使用“GetValue”/“SetValue”时,您正在更新此表上的条目(顺便说一下与 WPF 如何能够管理数据绑定有关)。
The upshot of this though is that WPF can (and will) completely bypass your property accessors because it has direct access to the real data. Why should it use your accessors if it can just go to the data directly. Instead you need to implement a 'PropertyChanged' callback function or some WPF sanctioned method of doing validation, but never ever do it in your accessors.
这样做的结果是 WPF 可以(并且将会)完全绕过您的属性访问器,因为它可以直接访问真实数据。如果它可以直接访问数据,为什么要使用您的访问器。相反,您需要实现一个“PropertyChanged”回调函数或一些 WPF 认可的验证方法,但永远不要在您的访问器中这样做。
See:
看:
回答by Vynos
In addition to sircodesalot's answer, you are not bound on your lyrics textbox. Also, since the song your bound to is a class, you will need to specify the paths fully for the properties you want to show in the boxes such as "Path=Song.Lyrics".
除了 Sircodesalot 的回答,您不受歌词文本框的限制。此外,由于您绑定的歌曲是一个类,您需要为要在“Path=Song.Lyrics”等框中显示的属性完全指定路径。
Another thing to consider is that with dependency properties; your mode will be oneway by default so making the text field editable would be moot really unless you change it.
另一件要考虑的事情是依赖属性;默认情况下,您的模式将是单向的,因此除非您更改它,否则使文本字段可编辑实际上没有实际意义。
Third, if you're using MVVM you only need your main window context to be set to the view model and have a matching Song property to bind against.
第三,如果您使用的是 MVVM,您只需要将主窗口上下文设置为视图模型,并有一个匹配的 Song 属性来绑定。

