WPF-XAML-NamescopesWPF XAML Namescopes

XAML-Namescopes sind ein Konzept, das Objekte bezeichnet, die in XAML definiert sind.XAML namescopes are a concept that identifies objects that are defined in XAML. Die Namen in einem XAML-Namescope können verwendet werden, um Beziehungen zwischen den XAML-definierten Namen der Objekte und ihren Entsprechungen in einer Objektstruktur herzustellen.The names in a XAML namescope can be used to establish relationships between the XAML-defined names of objects and their instance equivalents in an object tree. In der Regel werden XAML-Namescopes in verwaltetem WPFWPF-Code beim Laden der einzelnen XAML Seitenstämme für XAML-Anwendungen erstellt.Typically, XAML namescopes in WPFWPF managed code are created when loading the individual XAML page roots for a XAML application. XAML-Namescopes als Programmierobjekt werden INameScope durch die Schnittstelle definiert NameScopeund auch von der praktischen Klasse implementiert.XAML namescopes as the programming object are defined by the INameScope interface and are also implemented by the practical class NameScope.

Namescopes in geladenen XAML-AnwendungenNamescopes in Loaded XAML Applications

Im weiter gefassten Kontext der Programmierung oder der Informatik beinhalten Programmierkonzepte oft einen eindeutigen Bezeichner oder Namen, der für den Objektzugriff verwendet werden kann.In a broader programming or computer science context, programming concepts often include the principle of a unique identifier or name that can be used to access an object. Für Systeme, die Bezeichner oder Namen verwenden, definiert der Namescope die Grenzen, innerhalb derer ein Prozess oder eine Technik sucht, wenn ein Objekt mit diesem Namen angefordert wird, oder die Grenzen, innerhalb derer die Eindeutigkeit von identifizierenden Namen erzwungen wird.For systems that use identifiers or names, the namescope defines the boundaries within which a process or technique will search if an object of that name is requested, or the boundaries wherein uniqueness of identifying names is enforced. Diese allgemeinen Prinzipien gelten für XAML-Namescopes.These general principles are true for XAML namescopes. In WPF werden XAML-Namescopes für das Stammelement einer XAML-Seite erstellt, wenn die Seite geladen wird.In WPF, XAML namescopes are created on the root element for a XAML page when the page is loaded. Jeder in der XAML-Seite angegebene Name wird, vom Stammelement ausgehend, einem entsprechenden XAML-Namescope hinzugefügt.Each name specified within the XAML page starting at the page root is added to a pertinent XAML namescope.

In WPF XAML steuern Elemente, die Pagegemeinsame WindowStammelemente sind (z. B. und ), immer ein XAML-Namescope.In WPF XAML, elements that are common root elements (such as Page, and Window) always control a XAML namescope. Wenn ein Element FrameworkElement FrameworkContentElement wie das Stammelement der Seite im XAMLXAML Markup Page oder das Stammelement ist, fügt ein Prozessor implizit einen Stamm hinzu, damit der Page ein funktionierendes XAML-Namescope bereitstellen kann.If an element such as FrameworkElement or FrameworkContentElement is the root element of the page in markup, a XAMLXAML processor adds a Page root implicitly so that the Page can provide a working XAML namescope.

Hinweis

WPF-Buildvorgänge erstellen für eine XAML-Produktion selbst dann einen XAML-Namescope, wenn für kein Element im XAMLXAML-Markup Name- oder x:Name-Attribute definiert sind.WPF build actions create a XAML namescope for a XAML production even if no Name or x:Name attributes are defined on any elements in the XAMLXAML markup.

Wenn Sie versuchen, denselben Namen in einem beliebigen XAML-Namescope zweimal zu verwenden, wird eine Ausnahme ausgelöst.If you try to use the same name twice in any XAML namescope, an exception is raised. Für WPF-XAML, das CodeBehind verwendet und Teil einer kompilierten Anwendung ist, wird die Ausnahme während der Erstellung durch WPF-Buildaktionen ausgelöst, wenn die generierende Klasse für die Seite während der Kompilierung des ausgehenden Markups erstellt wird.For WPF XAML that has code-behind and is part of a compiled application, the exception is raised at build time by WPF build actions, when creating the generated class for the page during the initial markup compile. Für XAML, dessen Markup nicht durch Buildaktionen kompiliert wird, können XAML-Namescope-bezogene Ausnahmen während des Ladens des XAML ausgelöst werden.For XAML that is not markup-compiled by any build action, exceptions related to XAML namescope issues might be raised when the XAML is loaded. XAML-Designer können XAML-Namescope-Probleme auch zur Entwurfszeit vorausschauend behandeln.XAML designers might also anticipate XAML namescope issues at design time.

Hinzufügen von Objekten zu Laufzeit-ObjektstrukturenAdding Objects to Runtime Object Trees

Der Zeitpunkt, an dem das XAML analysiert wird, stellt den Zeitpunkt dar, an dem ein WPF-XAML-Namescope erstellt und definiert wird.The moment that XAML is parsed represents the moment in time that a WPF XAML namescope is created and defined. Wenn Sie ein Objekt zu einer Objektstruktur hinzufügen, nachdem der die Struktur erzeugende XAML-Code analysiert wurde, wird ein Name- oder x:Name-Wert für das neue Objekt nicht automatisch die Informationen in einem XAML-Namescope aktualisieren.If you add an object to an object tree at a point in time after the XAML that produced that tree was parsed, a Name or x:Name value on the new object does not automatically update the information in a XAML namescope. Um einen Namen für ein Objekt zu einem WPF XAML-Namescope hinzuzufügen, nachdem RegisterName XAML geladen wurde, müssen Sie die entsprechende Implementierung für das Objekt aufrufen, das den XAML-Namescope definiert, der in der Regel der XAML-Seitenstamm ist.To add a name for an object into a WPF XAML namescope after XAML is loaded, you must call the appropriate implementation of RegisterName on the object that defines the XAML namescope, which is typically the XAML page root. Wenn der Name nicht registriert ist, kann nicht mit dem FindNameNamen über Methoden wie , auf das hinzugefügte Objekt verwiesen werden, und Sie können diesen Namen nicht für animationszielartiger Ziele verwenden.If the name is not registered, the added object cannot be referenced by name through methods such as FindName, and you cannot use that name for animation targeting.

Das häufigste Szenario für Anwendungsentwickler ist, dass Sie RegisterName Namen im XAML-Namescope im aktuellen Stamm der Seite registrieren.The most common scenario for application developers is that you will use RegisterName to register names into the XAML namescope on the current root of the page. RegisterNameist Teil eines wichtigen Szenarios für Storyboards, die Objekte für Animationen zielen.RegisterName is part of an important scenario for storyboards that target objects for animations. Weitere Informationen finden Sie unter Übersicht über Storyboards.For more information, see Storyboards Overview.

Wenn Sie RegisterName ein anderes Objekt als das Objekt aufrufen, das das XAML-Namescope definiert, wird der Name weiterhin im XAML-Namescope registriert, in dem sich das aufrufende Objekt befindet, als ob Sie das XAML-Namescope-definierende Objekt aufgerufen RegisterName hätten.If you call RegisterName on an object other than the object that defines the XAML namescope, the name is still registered to the XAML namescope that the calling object is held within, as if you had called RegisterName on the XAML namescope defining object.

XAML Namescopes im CodeXAML Namescopes in Code

Sie können XAML-Namescopes im Code erstellen und anschließend verwenden.You can create and then use XAML namescopes in code. Die an der XAML-Namescope beteiligten APIs und Konzepte sind auch bei reiner Codeverwendung dieselben, da der XAML-Prozessor von WPFWPF diese APIs und Konzepte beim Verarbeiten des XAML selbst verwendet.The APIs and the concepts involved in XAML namescope creation are the same even for a pure code usage, because the XAML processor for WPFWPF uses these APIs and concepts when it processes XAML itself. Die Aufgaben dieser Konzepte und -APIs sind hauptsächlich, Objekte anhand des Namens innerhalb einer Objektstruktur zu finden, die in der Regel teilweise oder vollständig in XAML definiert ist.The concepts and API exist mainly for the purpose of being able to find objects by name within an object tree that is typically defined partially or entirely in XAML.

Für Anwendungen, die programmgesteuert und nicht aus geladenem XAML erstellt werden, muss INameScopedas Objekt, FrameworkElement FrameworkContentElement das ein XAML-Namescope definiert, implementieren , oder eine oder abgeleitete Klasse sein, um die Erstellung eines XAML-Namescopes für seine Instanzen zu unterstützen.For applications that are created programmatically, and not from loaded XAML, the object that defines a XAML namescope must implement INameScope, or be a FrameworkElement or FrameworkContentElement derived class, in order to support creation of a XAML namescope on its instances.

Ebenso gilt, das bei jedem Element, das nicht von einem XAML-Prozessor geladen und verarbeitet wird, der XAML-Namescope für das Objekt standardmäßig nicht erstellt oder initialisiert wird.Also, for any element that is not loaded and processed by a XAML processor, the XAML namescope for the object is not created or initialized by default. Sie müssen explizit für jedes Objekt einen neuen XAML-Namescope erstellen, für das Sie anschließend Namen registrieren möchten.You must explicitly create a new XAML namescope for any object that you intend to register names into subsequently. Um ein XAML-Namescope zu SetNameScope erstellen, rufen Sie die statische Methode auf.To create a XAML namescope, you call the static SetNameScope method. Geben Sie das Objekt, dependencyObject das es besitzt, als Parameter und einen neuen NameScope Konstruktoraufruf als value Parameter an.Specify the object that will own it as the dependencyObject parameter, and a new NameScope constructor call as the value parameter.

Wenn es sich dependencyObject SetNameScope bei dem INameScope bereitgestellten Objekt nicht um eine Implementierung FrameworkElement oder FrameworkContentElementum das Aufrufen RegisterName von untergeordneten Elementen handelt, hat dies keine Auswirkungen.If the object provided as dependencyObject for SetNameScope is not a INameScope implementation, FrameworkElement or FrameworkContentElement, calling RegisterName on any child elements will have no effect. Wenn Sie das neue XAML-Namescope nicht RegisterName explizit erstellen können, wird bei Aufrufen zu eine Ausnahme ausgelöst.If you fail to create the new XAML namescope explicitly, then calls to RegisterName will raise an exception.

Ein Beispiel der Verwendung von XAML-Namescope-APIs in Code finden Sie unter Definieren eines Namensbereichs.For an example of using XAML namescope APIs in code, see Define a Name Scope.

XAML-Namescopes in Stilen und VorlagenXAML Namescopes in Styles and Templates

Stile und Vorlagen in WPFWPF bieten die Möglichkeit, Inhalte auf einfache Weise wieder zu verwenden und sie erneut anzuwenden.Styles and templates in WPFWPF provide the ability to reuse and reapply content in a straightforward way. Allerdings können Stile und Vorlagen auch Elemente mit XAML-Namen, die auf der Vorlagenebene definiert sind, enthalten.However, styles and templates might also include elements with XAML names defined at the template level. Dieselbe Vorlage wird möglicherweise mehrmals auf einer Seite verwendet.That same template might be used multiple times in a page. Aus diesem Grund definieren Stile und Vorlagen ihre eigenen XAML-Namescopes, unabhängig davon, an welcher Position in einer Objektstruktur der Stil oder die Vorlage angewendet wird.For this reason, styles and templates both define their own XAML namescopes, independent of whatever location in an object tree where the style or template is applied.

Betrachten Sie das folgenden Beispiel:Consider the following example:

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  >
  <Page.Resources>
    <ControlTemplate x:Key="MyButtonTemplate" TargetType="{x:Type Button}">
      <Border BorderBrush="Red" Name="TheBorder" BorderThickness="2">
        <ContentPresenter/>
      </Border>      
    </ControlTemplate>
  </Page.Resources>
  <StackPanel>
    <Button Template="{StaticResource MyButtonTemplate}">My first button</Button>
    <Button Template="{StaticResource MyButtonTemplate}">My second button</Button>
  </StackPanel>
</Page>

Hier wird dieselbe Vorlage auf zwei verschiedene Schaltflächen angewendet.Here, the same template is applied to two different buttons. Hätten Vorlagen keine diskreten XAML-Namensbereiche, würde der in der Vorlage verwendete TheBorder-Name einen Namenskonflikt im XAML-Namescope verursachen.If templates did not have discrete XAML namescopes, the TheBorder name used in the template would cause a name collision in the XAML namescope. Jede Vorlageninstanz hat ihren eigenen XAML-Namescope, weshalb in diesem Beispiel der Namescope jeder Instanz der Vorlage genau einen Namen enthält.Each instantiation of the template has its own XAML namescope, so in this example each instantiated template's XAML namescope would contain exactly one name.

Auch Stile definieren ihre eigenen XAML-Namensbereich. Dies dient vor allem dazu, dass Teilen von Storyboards bestimmte Namen zugewiesen werden können.Styles also define their own XAML namescope, mostly so that parts of storyboards can have particular names assigned. Diese Namen ermöglichen steuerelementspezifische Verhalten, die auf Elemente dieses Namens selbst dann angewendet werden, wenn die Vorlage als Teil einer Anpassung von Steuerelementen neu definiert wurde.These names enable control specific behaviors that will target elements of that name, even if the template was re-defined as part of control customization.

Aufgrund der separaten XAML-Namescopes ist die Suche nach benannten Elementen in einer Vorlage schwieriger, als die Suche nach einem ohne Vorlage benannten Element in einer Seite.Because of the separate XAML namescopes, finding named elements in a template is more challenging than finding a non-templated named element in a page. Sie müssen zuerst die angewendete Vorlage Template bestimmen, indem Sie den Eigenschaftswert des Steuerelements abrufen, auf das die Vorlage angewendet wird.You first need to determine the applied template, by getting the Template property value of the control where the template is applied. Anschließend rufen Sie die FindNameVorlagenversion von auf, indem Sie das Steuerelement übergeben, an dem die Vorlage als zweiter Parameter angewendet wurde.Then, you call the template version of FindName, passing the control where the template was applied as the second parameter.

Wenn Sie ein Steuerelementautor sind und eine Konvention generieren, bei der ein bestimmtes benanntes Element in einer angewendeten GetTemplateChild Vorlage das Ziel für ein Verhalten ist, das vom Steuerelement selbst definiert wird, können Sie die Methode aus dem Steuerelementimplementierungscode verwenden.If you are a control author and you are generating a convention where a particular named element in an applied template is the target for a behavior that is defined by the control itself, you can use the GetTemplateChild method from your control implementation code. Die GetTemplateChild Methode ist geschützt, sodass nur der Steuerelementautor Zugriff darauf hat.The GetTemplateChild method is protected, so only the control author has access to it.

Wenn Sie innerhalb einer Vorlage arbeiten und zum XAML-Namescope gelangen müssen, in TemplatedParentdem die FindName Vorlage angewendet wird, rufen Sie den Wert von ab, und rufen Sie dann dort auf.If you are working from within a template, and need to get to the XAML namescope where the template is applied, get the value of TemplatedParent, and then call FindName there. Ein Beispiel für das Arbeiten innerhalb der Vorlage wäre, wenn Sie einen Ereignis-Handler dort implementieren möchten, wo das Ereignis von einem Element in einer angewendeten Vorlage ausgelöst wird.An example of working within the template would be if you are writing the event handler implementation where the event will be raised from an element in an applied template.

FrameworkElementhat FindName RegisterName , UnregisterName und Methoden.FrameworkElement has FindName, RegisterName and UnregisterName methods. Wenn das Objekt, für das Sie diese Methoden aufrufen, einen XAML-Namescope besitzt, rufen die Methoden die Methoden des entsprechenden XAML-Namescopes auf.If the object you call these methods on owns a XAML namescope, the methods call into the methods of the relevant XAML namescope. Andernfalls wird das übergeordnete Element daraufhin überprüft, ob es einen XAML-Namescope besitzt. Dieser Vorgang wird rekursiv fortgesetzt, bis ein XAML-Namescope gefunden wird (wobei Erfolg garantiert ist, da aufgrund des Verhaltens des XAML-Prozessors das Stammelement immer einen XAML-Namescope hat).Otherwise, the parent element is checked to see if it owns a XAML namescope, and this process continues recursively until a XAML namescope is found (because of the XAML processor behavior, there is guaranteed to be a XAML namescope at the root). FrameworkContentElementhat analoge Verhaltensweisen, mit der FrameworkContentElement Ausnahme, dass kein XAML-Namescope jemals besitzen wird.FrameworkContentElement has analogous behaviors, with the exception that no FrameworkContentElement will ever own a XAML namescope. Die Methoden FrameworkContentElement sind vorhanden, sodass die Aufrufe FrameworkElement schließlich an ein übergeordnetes Element weitergeleitet werden können.The methods exist on FrameworkContentElement so that the calls can be forwarded eventually to a FrameworkElement parent element.

SetNameScopewird verwendet, um einem vorhandenen Objekt ein neues XAML-Namescope zuzuordnen.SetNameScope is used to map a new XAML namescope to an existing object. Sie können SetNameScope mehr als einmal aufrufen, um das XAML-Namescope zurückzusetzen oder zu löschen, aber das ist keine häufige Verwendung.You can call SetNameScope more than once in order to reset or clear the XAML namescope, but that is not a common usage. Außerdem GetNameScope wird in der Regel nicht aus Code verwendet.Also, GetNameScope is not typically used from code.

Implementierungen von XAML-NamescopesXAML Namescope Implementations

Die folgenden INameScope Klassen werden direkt implementiert:The following classes implement INameScope directly:

ResourceDictionaryXAML-Namen oder Namescopes nicht verwendet; Stattdessen werden Schlüssel verwendet, da es sich um eine Wörterbuchimplementierung handelt.ResourceDictionary does not use XAML names or namescopes ; it uses keys instead, because it is a dictionary implementation. Der einzige ResourceDictionary Grund, INameScope der implementiert wird, ist, dass es Ausnahmen von Benutzercode auslösen kann, ResourceDictionary die helfen, die Unterscheidung zwischen einem echten XAML-Namescope und dem Behandeln von Schlüsseln zu verdeutlichen und sicherzustellen, dass XAML-Namescopes nicht ResourceDictionary von übergeordneten Elementen angewendet werden.The only reason that ResourceDictionary implements INameScope is so it can raise exceptions to user code that help clarify the distinction between a true XAML namescope and how a ResourceDictionary handles keys, and also to assure that XAML namescopes are not applied to a ResourceDictionary by parent elements.

FrameworkTemplateund Style INameScope durch explizite Schnittstellendefinitionen zu implementieren.FrameworkTemplate and Style implement INameScope through explicit interface definitions. Die expliziten Implementierungen ermöglichen es diesen XAML-Namescopes, INameScope sich konventionell zu verhalten, wenn über die WPFWPF Schnittstelle darauf zugegriffen wird, wie XAML-Namescopes durch interne Prozesse kommuniziert werden.The explicit implementations allow these XAML namescopes to behave conventionally when they are accessed through the INameScope interface, which is how XAML namescopes are communicated by WPFWPF internal processes. Die expliziten Schnittstellendefinitionen sind jedoch nicht FrameworkTemplate Teil Styleder herkömmlichen API-Oberfläche INameScope von FrameworkTemplate Style und , da Sie die GetTemplateChildMethoden selten auf und direkt aufrufen müssen und stattdessen eine andere API wie verwenden würden.But the explicit interface definitions are not part of the conventional API surface of FrameworkTemplate and Style, because you seldom need to call the INameScope methods on FrameworkTemplate and Style directly, and instead would use other API such as GetTemplateChild.

Die folgenden Klassen definieren ihr eigenes XAML-Namescope, indem sie die System.Windows.NameScope Hilfsklasse verwenden NameScope.NameScope und über die angefügte Eigenschaft eine Verbindung mit der XAML-Namescope-Implementierung herstellen:The following classes define their own XAML namescope, by using the System.Windows.NameScope helper class and connecting to its XAML namescope implementation through the NameScope.NameScope attached property:

Weitere InformationenSee also