Wpf 为什么我会犯错误;找不到引用为“”的绑定的源;?

Wpf 为什么我会犯错误;找不到引用为“”的绑定的源;?,wpf,Wpf,我的WPF控件未按预期呈现。具体地说,当我为用户控件的依赖项属性指定值时,如果该用户控件的子控件出现问题,并且子控件没有按其应有的方式呈现,则该用户控件会尝试在其中一个控件上使用该值 我将问题归结为一个简单的例子,如下所示。我创建了一个RedBox用户控件,它在红色边框内显示其内容,以及一个BlueBox用户控件,它应该在RedBox内的TextBlock中显示绑定文本。最后一部分失败了。我怀疑问题出在BlueBox.xaml的第35行,但这只是一个猜测 RedBox.xaml <User

我的WPF控件未按预期呈现。具体地说,当我为用户控件的依赖项属性指定值时,如果该用户控件的子控件出现问题,并且子控件没有按其应有的方式呈现,则该用户控件会尝试在其中一个控件上使用该值

我将问题归结为一个简单的例子,如下所示。我创建了一个RedBox用户控件,它在红色边框内显示其内容,以及一个BlueBox用户控件,它应该在RedBox内的TextBlock中显示绑定文本。最后一部分失败了。我怀疑问题出在BlueBox.xaml的第35行,但这只是一个猜测

RedBox.xaml

<UserControl
        x:Class="WpfApplication1.RedBox"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        mc:Ignorable="d">
    <ContentControl.Template>
        <ControlTemplate TargetType="UserControl">
            <Border BorderBrush="Red" BorderThickness="4" Padding="4">
                <ContentPresenter Margin="3,0,0,0" Content="{TemplateBinding Content}" VerticalAlignment="Center" />
            </Border>
        </ControlTemplate>
    </ContentControl.Template>
</UserControl>
BlueBox.xaml

<UserControl x:Class="WpfApplication1.BlueBox"
             x:Name="UserControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:wpfApplication1="clr-namespace:WpfApplication1"
             mc:Ignorable="d">

    <Border BorderBrush="Blue" BorderThickness="4" Padding="4">

        <Grid>

            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>

            <TextBlock Grid.Row="0" Grid.Column="0" Text="Show the BlueBox's Text property value:" />
            <TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding ElementName=UserControl, Path=Text}" />

            <TextBlock Grid.Row="1" Grid.Column="0" Text="Show static text within a RedBox:" />
            <wpfApplication1:RedBox Grid.Row="1" Grid.Column="1">
                <TextBlock Text="Static Text" />
            </wpfApplication1:RedBox>

            <TextBlock Grid.Row="2" Grid.Column="0" Text="Show the BlueBox's Text property value within a RedBox:" />
            <wpfApplication1:RedBox Grid.Row="2" Grid.Column="1">
                <TextBlock Text="{Binding ElementName=UserControl, Path=Text}" />
            </wpfApplication1:RedBox>

        </Grid>

    </Border>
</UserControl>
MainWindow.xaml

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:wpfApplication1="clr-namespace:WpfApplication1"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <wpfApplication1:BlueBox Text="Hi!" />
</Window>
在研究错误“找不到引用绑定的源”时,我发现错误的一个常见原因是人们试图绑定到他们绑定到的对象的可视树中不存在的东西。但我不认为这是我的问题,因为BlueBox在它自己的TextBlock控件的可视树中,不是吗

那么,发生了什么事

更新:

我发现,如果我将BlueBox.xaml的第35行替换为以下内容,它就会工作:

            <TextBlock Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type wpfApplication1:BlueBox}}, Path=Text}" />


这解决了我的问题。不过,我仍然对ElementName语法不起作用感到困惑。如果您能深入了解这一点,我将不胜感激。

您的依赖属性
Text
字符串的类型。但是您将其默认值注册为非特定类型的
PropertyMetadata()
。要么不提供类型元数据,要么给它一个合适的元数据,比如:
newpropertymetadata(“默认值”)

更改代码的这一部分:

public static readonly DependencyProperty TextProperty = 
       DependencyProperty.Register(
             name: "Text",
             propertyType: typeof(string),
             ownerType: typeof(BlueBox),
             typeMetadata: new PropertyMetadata());
为此:

public static readonly DependencyProperty TextProperty = 
       DependencyProperty.Register(
             name: "Text",
             propertyType: typeof(string),
             ownerType: typeof(BlueBox));

这可能会解决您的问题。

您的依赖项属性
Text
的类型为
String
。但是您将其默认值注册为非特定类型的
PropertyMetadata()
。要么不提供类型元数据,要么给它一个合适的元数据,比如:
newpropertymetadata(“默认值”)

更改代码的这一部分:

public static readonly DependencyProperty TextProperty = 
       DependencyProperty.Register(
             name: "Text",
             propertyType: typeof(string),
             ownerType: typeof(BlueBox),
             typeMetadata: new PropertyMetadata());
为此:

public static readonly DependencyProperty TextProperty = 
       DependencyProperty.Register(
             name: "Text",
             propertyType: typeof(string),
             ownerType: typeof(BlueBox));

这可能会解决您的问题。

@Will他的BlueBox在其xamlComment中被命名为“UserControl”,以避免混淆。奇怪,看起来不错。我将启动Snoop并在运行时验证您的可视树和绑定。@威尔,我接受了您的建议并下载了Snoop。非常容易使用。诚然,我是个新手,但我认为Snoop验证了名为“UserControl”的BlueBox是生成错误的TextBlock树中的直接祖先。不知道。也许叫它“MuhFooRootLol”而不是“UserControl”。你可能会有一些鬼鬼祟祟的Unicode代码,比如零宽度空格。删除并重新键入整个属性和绑定可能会使货机返回。如果你问题中的代码是你实际测试的代码,也许可以考虑打开一个与MS的连接,然后扔掉它。@Will,当你第一次指出它时,我意识到“UserControl”令人困惑,所以我将它重命名为“BlueBoxUserControl”,但这似乎无关紧要。无论如何,我通过使用RelativeSource绑定而不是ElementName绑定来完成整个工作。我不知道ElementName方法出了什么问题,但现在我已经有了解决方案,很难证明进一步的研究是正确的。再一次,WPF编程让我觉得我没有完全理解规则。@Will他的BlueBox在其xamlComment中被命名为“UserControl”,以避免混淆。奇怪,看起来不错。我将启动Snoop并在运行时验证您的可视树和绑定。@威尔,我接受了您的建议并下载了Snoop。非常容易使用。诚然,我是个新手,但我认为Snoop验证了名为“UserControl”的BlueBox是生成错误的TextBlock树中的直接祖先。不知道。也许叫它“MuhFooRootLol”而不是“UserControl”。你可能会有一些鬼鬼祟祟的Unicode代码,比如零宽度空格。删除并重新键入整个属性和绑定可能会使货机返回。如果你问题中的代码是你实际测试的代码,也许可以考虑打开一个与MS的连接,然后扔掉它。@Will,当你第一次指出它时,我意识到“UserControl”令人困惑,所以我将它重命名为“BlueBoxUserControl”,但这似乎无关紧要。无论如何,我通过使用RelativeSource绑定而不是ElementName绑定来完成整个工作。我不知道ElementName方法出了什么问题,但现在我已经有了解决方案,很难证明进一步的研究是正确的。再一次,WPF编程让我觉得我没有完全理解规则。我粘贴了您的编辑逐字记录,但似乎没有任何效果。这个答案是错误的,请参阅PropertyMetadata的构造函数:我粘贴了您的编辑逐字记录,但似乎没有任何效果。这个答案是错误的,请参阅PropertyMetadata的构造函数:
public static readonly DependencyProperty TextProperty = 
       DependencyProperty.Register(
             name: "Text",
             propertyType: typeof(string),
             ownerType: typeof(BlueBox));