The problem with naming the XAML root element is that if you are used to using the same name (that is, "_this", "Root", etc.) for all the roots in your project, then late binding in the nested templates can access the wrong item. This is because when {Binding} ElementName=... used in Template , names are resolved at runtime by walking up the NameScope tree until the first is found.
The Clint solution avoids naming the root element, but it sets the root element in its own DataContext , which may not be available if the DataContext is needed, say, for data. It also seems a bit difficult to enter another binding to an element just to provide access to it. Later, if access is no longer needed, this {Binding} will become a mess: the responsibility for access properly belongs to the target and binding.
Accordingly, here is a simple markup extension for accessing the XAML root element without specifying its name:
using System.Xaml; using System.Windows.Markup; public sealed class XamlRootExtension : MarkupExtension { public override Object ProvideValue(IServiceProvider sp) { var rop = sp.GetService(typeof(IRootObjectProvider)) as IRootObjectProvider; return rop == null ? null : rop.RootObject; } };
XAML :
<Window x:Class="MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:global="clr-namespace:"> <TextBlock Text="{Binding Source={global:XamlRoot},Mode=OneTime}" /> </Window>
note: for clarity, I did not define MarkupExtension in the namespace; using the empty alias clr-namespace as shown here, d̲o̲e̲s̲ actually works to access the global:: namespace global:: (although the VS2013 designer seems to complain about this).
Result :

A window whose contents are associated with itself.
N.B.
Glenn Slayden Dec 19 '14 at 22:18 2014-12-19 22:18
source share