Tag属性中的WPF数据绑定错误

Jun*_*oic 1 c# data-binding wpf

<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>
Run Code Online (Sandbox Code Playgroud)

就像上面的一个简单代码一样,但是绑定找不到Element myGrid.在运行时,错误显示在"输出"窗口中

"System.Windows.Data错误:4:无法找到与引用'ElementName = myGrid'绑定的源.BindingExpression:Path = ActualWidth; DataItem = null;目标元素是'Label'(Name =''); target属性是'内容'(类型'对象')"

我正在使用Visual Studio 2015社区版与.Net Framework 4.5.2.有任何想法吗?先感谢您.

Hop*_*ess 15

元素(其属性已绑定)应该是可视树的一部分,以便可以进行可视树搜索.使用ElementName或使用Binding时RelativeSource,它会执行一些内部可视树搜索.但是在你的代码中,Label它与视觉树断开了Tag.Label只是内存中的一个对象,由Tag属性引用.

从.NET 4.0开始,您可以使用{x:Reference}标记,如下所示:

<Grid.Tag>
    <Label Content="{Binding ActualWidth, Source={x:Reference myGrid}}" />
</Grid.Tag>
Run Code Online (Sandbox Code Playgroud)

编辑:

{x:Reference}如果引用名称指向包含的某个元素,则使用会导致循环依赖性问题{x:Reference}.在你的情况下它是myGrid(包含{x:Reference}).所以它不能用在你的情况下.相反,你需要使用一些代理.这种技术看起来有点hacky,但事实上它非常漂亮.它也适用于任何版本的.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>
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,Binding使用其Source设置StaticResource指向a DiscreteObjectKeyFrame.这是一个Freezable对象,所以非常有趣的是,Freezable无论你使用什么,ElementName或者为对象的任何DependencyProperty设置的所有Bindings都能正常工作RelativeSource.所以我们将其Value属性绑定到Grid(名称为myGrid).稍后我们将Content属性绑定LabelFreezable对象,但Path设置为Value.ActualWidth(Value指向Grid,所以我们需要追加ActualWidth绑定它Grid.ActualWidth).

实际上你可以使用任何Freezable对象,但我们使用它是DiscreteObjectKeyFrame为了方便,它Value接受各种各样的object.

还有另一种技术可以在这种情况下设置Binding(断开连接的上下文),但它需要您创建自定义MarkupExtension.它当然更复杂(但是一旦你熟悉WPF,它仍然很简单).

  • 梦幻般的解决方案 非常感谢你.我认为现在我对视觉树有了更好的理解,并得到一个解决方法来处理上面的类似场景. (2认同)