Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
WPF绑定到UserControl自定义DependencyProperty_Wpf_Binding_User Controls_Dependency Properties - Fatal编程技术网

WPF绑定到UserControl自定义DependencyProperty

WPF绑定到UserControl自定义DependencyProperty,wpf,binding,user-controls,dependency-properties,Wpf,Binding,User Controls,Dependency Properties,我有一个名为SongDescription的自定义用户控件: <UserControl x:Class="DPTestAp.SongDescription" ...> <Grid x:Name="LayoutRoot"> <DockPanel Height="50"> <TextBlock x:Name="title" Text="{Binding name}" Width="100" Height="30

我有一个名为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>
问题是:如何将某些内容绑定到此属性? 我在主窗口中使用SongDescription,如下所示:

<local:SongDescription x:Name="songDescription" Song="{Binding DataContext}"/>
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" };
<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>
或者像这样打开窗口:

<local:SongDescription x:Name="songDescription" Song="{Binding DataContext}"/>
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" };
<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>
我甚至尝试将Song作为一种资源,并将其绑定到SongProperty,如下所示:

<local:SongDescription x:Name="songDescription" Song="{Binding DataContext}"/>
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" };
<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>

没有任何帮助。文本块标题绑定歌曲名称。但我无法调用updateLyrics()方法。(在现实生活中,这种方法更复杂,所以我不能像使用name一样使用绑定)


谢谢大家!

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

不过,其结果是WPF可以(也将)完全绕过您的属性访问器,因为它可以直接访问真实数据。如果它可以直接访问数据,为什么要使用访问器呢。相反,您需要实现一个“PropertyChanged”回调函数或一些WPF认可的验证方法,但永远不要在访问器中实现

见:


除了sircodesalot的答案外,您还没有被限制在歌词文本框中。此外,由于绑定到的歌曲是一个类,因此需要为要在框中显示的属性(如“Path=song.lyms”)指定完整的路径

另一个要考虑的是依赖属性;默认情况下,您的模式将是单向的,因此,除非您更改文本字段,否则使文本字段可编辑将毫无意义


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

但是,如果
PropertyChanged
回调,我将无法更新任何控件,因为它是一个共享函数!