WPF databinding error in Tag property

后端 未结 3 686
眼角桃花
眼角桃花 2021-01-03 16:01


        
相关标签:
3条回答
  • 2021-01-03 16:43

    I tried below code snippet in WPF and its working fine.

    <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>
    

    0 讨论(0)
  • 2021-01-03 16:44

    The element (whose property is bound) should be part of the visual tree so that the visual tree search can be done. When using Binding with ElementName or RelativeSource, it performs some internal visual tree search. But in your code the Label is disconnected from visual tree by the Tag. Label is just an object in memory, referenced by the Tag property.

    Since .NET 4.0 you can use the {x:Reference} markup instead, like this:

    <Grid.Tag>
        <Label Content="{Binding ActualWidth, Source={x:Reference myGrid}}" />
    </Grid.Tag>
    

    Edit:

    Using {x:Reference} can cause issue of cyclic dependency if the reference name points to some element containing the {x:Reference}. In your case it is myGrid (containing {x:Reference}). So it cannot be used in your case. Instead you need to use some proxy. This technique seems a bit hacky but in fact it's very pretty. It also surely works in any version of .NET (supporting 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>
    

    As you see the Binding works with its Source set to StaticResource pointing to a DiscreteObjectKeyFrame. This is a Freezable object so it's quite interesting that all Bindings set for any DependencyProperty of a Freezable object work well no matter you use ElementName or RelativeSource. So we bind its Value property to the Grid (with name of myGrid). Later on we bind the Content property of Label to the Freezable object but with Path set to Value.ActualWidth (Value points to Grid, so we need to append ActualWidth to bind it to Grid.ActualWidth).

    In fact you can use any Freezable object but we use DiscreteObjectKeyFrame for convenience, its Value accepts all kinds of object.

    There is another technique to set Binding in a situation like this (disconnected context) but it requires you to create a custom MarkupExtension. It's of course more complicated (but still simple enough once you're familiar with WPF).

    0 讨论(0)
  • 2021-01-03 17:02

    I have also try to replicate issue but below code is working fine in 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>
    

    0 讨论(0)
提交回复
热议问题