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