Проблемът с именуването на коренния елемент XAML
е, че ако придобиете навика да използвате същото име (т.е., " _this", "Root" и т.н.) за всички корени във вашия проект, тогава късното свързване във вложени шаблони може да получи достъп до грешен елемент. Това е така, защото когато {Binding}
ElementName=...
се използва в Template
, имената се разрешават по време на изпълнение чрез ходене нагоре по дървото NameScope
, докато се намери първото съвпадение.
Решението на Clint избягва наименуването на коренния елемент, но настройва коренния елемент в собствен DataContext
, което може да не е опция, ако DataContext е необходим, да речем, за данни. Също така изглежда малко трудно да се въведе друго обвързване на елемент само с цел осигуряване на достъп до него. По-късно, ако достъпът вече не е необходим, този {Binding}
ще се превърне в бъркотия: отговорността за достъп правилно принадлежи на целта и обвързването.
Съответно, тук е просто разширение за маркиране за достъп до коренния елемент на XAML, без да го наименувате:
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>
забележка: за по-голяма яснота, не съм дефинирал MarkupExtension
в пространство от имена; използване на празен псевдоним clr-namespace
, както е показано тук d̲o̲e̲s̲ всъщност работи за достъп до пространството от имена global::
(въпреки че дизайнерът на VS2013 изглежда се оплаква от това).
Резултат:
![въведете описание на изображението тук](https://i.stack.imgur.com/vQfdP.png)
Прозорец, чието съдържание е обвързано със самия себе си.
N.b.
person
Glenn Slayden
schedule
19.12.2014