<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:son"
x:Class="son.SonWindow">
<Grid x:Name="myGrid">
<Grid.Tag>
<Label Content="{Binding ActualWidth, ElementName=myGrid}" />
</Grid.Tag>
</Grid>
</UserControl>
正如上面的一个简单代码,但绑定无法找到Element myGrid。在运行期间,错误显示在“输出”窗口中
&#34; System.Windows.Data错误:4:找不到绑定源 引用&#39; ElementName = myGrid&#39;。 BindingExpression:路径= ActualWidth的; 的DataItem = NULL;目标元素是&#39;标签&#39; (名称=&#39;&#39);目标属性是 &#39;内容&#39; (键入&#39;对象&#39;)&#34;
我正在使用Visual Studio 2015社区版和.Net Framework 4.5.2。有任何想法吗?提前谢谢。
答案 0 :(得分:15)
元素(其属性已绑定)应该是可视树的一部分,以便可以进行可视树搜索。在使用ElementName
或RelativeSource
绑定时,它会执行一些内部可视树搜索。但是在您的代码中Label
与Tag
的可视树断开连接。 Label
只是内存中的一个对象,由Tag属性引用。
从.NET 4.0开始,您可以使用{x:Reference}
标记,如下所示:
<Grid.Tag>
<Label Content="{Binding ActualWidth, Source={x:Reference myGrid}}" />
</Grid.Tag>
修改强>:
如果引用名称指向包含{x:Reference}
的某个元素,则使用{x:Reference}
会导致出现循环依赖性问题。在您的情况下,它是myGrid
(包含{x:Reference}
)。所以它不能用在你的情况下。相反,你需要使用一些代理。这种技术看起来有点笨拙,但实际上它非常漂亮。它也适用于任何版本的.NET(支持WPF):
<Grid x:Name="myGrid">
<Grid.Resources>
<DiscreteObjectKeyFrame x:Key="proxy" Value="{Binding ElementName=myGrid}"/>
</Grid.Resources>
<Grid.Tag>
<Label Content="{Binding Value.ActualWidth, Source={StaticResource proxy}}" />
</Grid.Tag>
</Grid>
如您所见,Binding的Source
设置为StaticResource
指向DiscreteObjectKeyFrame
。这是一个Freezable
对象,因此无论您使用Freezable
还是ElementName
,为RelativeSource
对象的任何DependencyProperty设置的所有Binding都能正常运行,这非常有趣。因此,我们将其Value
属性绑定到Grid
(名称为myGrid
)。稍后,我们将Content
Label
属性绑定到Freezable
对象,但Path
设置为Value.ActualWidth
(Value
指向{{1}因此我们需要附加Grid
以将其绑定到ActualWidth
)。
事实上,您可以使用任何Grid.ActualWidth
对象,但为方便起见,我们使用Freezable
,DiscreteObjectKeyFrame
接受各种Value
。
还有另一种技术可以在这种情况下设置Binding(断开连接的上下文),但它需要您创建自定义object
。它当然更复杂(但是一旦你熟悉WPF,它仍然很简单)。
答案 1 :(得分:0)
我在WPF中尝试了以下代码片段并且工作正常。
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid x:Name="myGrid">
<Grid.Tag>
<Label Content="{Binding ActualWidth, ElementName=myGrid}" />
</Grid.Tag>
</Grid>
答案 2 :(得分:0)
我也尝试复制问题,但是在VS 2010中,代码正常工作。
<Window x:Class="CustomEventHandlerClick.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:CustomEventHandlerClick"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid x:Name="myGrid">
<Grid.Tag>
<Label Content="{Binding ActualWidth, ElementName=myGrid}"/>
</Grid.Tag>
</Grid>
</Grid>