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 Programmierobjekte sind definiert, durch die INameScope Schnittstelle und werden auch von der praktischen Klasse implementiert NameScope.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, Elemente, die allgemeine Stammelemente sind (z. B. Page, und Window) immer einen XAML-Namescope zu steuern.In WPF XAML, elements that are common root elements (such as Page, and Window) always control a XAML namescope. Wenn ein Element wie z. B. FrameworkElement oder FrameworkContentElement ist das Stammelement der Seite im Markup einer XAMLXAML Prozessor Fügt eine Page implizit root, damit die Page bieten einen XAML-Namescope arbeiten.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 in einer WPF XAML-Namescope hinzuzufügen, nachdem XAML geladen wurde, müssen Sie die entsprechende Implementierung von Aufrufen RegisterName für das Objekt, das den XAML-Namescope definiert, die normalerweise ist der Stamm der XAML-Seite.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, das hinzugefügte Objekt kann nicht verwiesen werden anhand des Namens durch Methoden wie z. B. FindName, und Sie können diesen Namen für die Animationsziel-nicht 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, den Sie verwenden RegisterName Namen im XAML-Namescope auf dem aktuellen Stammelement der Seite zu 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. RegisterName ist Teil des Storyboards ein wichtiger Aspekt dieses Zielobjekten für Animationen.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 aufrufen RegisterName auf ein anderes Objekt als das Objekt, das die XAML-Namescope definiert, der Name ist immer noch registriert auf der XAML-Namescope, der das aufrufende Objekt enthalten ist wie bei einem Aufruf RegisterName auf der XAML-Namescope definieren-Objekts.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 erstellt werden, und nicht geladenen XAML, muss das Objekt, das einen XAML-Namescope definiert implementieren INameScope, oder eine FrameworkElement oder FrameworkContentElement abgeleitete Klasse sein, um die Unterstützung der Erstellung eines XAML-Namescopes auf seine -Instanzen.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 einen XAML-Namescope zu erstellen, rufen Sie die statische SetNameScope Methode.To create a XAML namescope, you call the static SetNameScope method. Geben Sie das Objekt, das sie als besitzt die dependencyObject Parameter und ein neues NameScope Konstruktoraufruf als die value Parameter.Specify the object that will own it as the dependencyObject parameter, and a new NameScope constructor call as the value parameter.

Wenn Sie das Objekt als bereitgestellt dependencyObject für SetNameScope keine INameScope Implementierung FrameworkElement oder FrameworkContentElement, wird beim Aufruf RegisterName für keines der untergeordneten Elemente hat 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 nicht explizit zu den neuen XAML-Namescope erstellen, klicken Sie dann Aufrufe von RegisterName wird 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 folgende 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. Müssen Sie zuerst die angewendete Vorlage durch Abrufen von bestimmen die Template -Eigenschaftswert des Steuerelements, in dem 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 Vorlagenversion von FindName, übergeben das Steuerelement, auf 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 Autor eines Steuerelements sind, und generieren Sie eine Konvention, in denen ein bestimmtes benanntes Element in einer angewendeten Vorlage ist das Ziel für ein Verhalten, das vom Steuerelement selbst definiert ist, können Sie die GetTemplateChild Methode aus dem Code des Steuerelements-Implementierung.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 geschützt werden, sodass nur der Autor des Steuerelements Zugriff darauf hat.The GetTemplateChild method is protected, so only the control author has access to it.

Wenn es sich bei dem aus Sie arbeiten in einer Vorlage und erforderlich, um den XAML-Namescope zu erhalten, in dem die Vorlage angewendet wird, erhalten Sie den Wert der TemplatedParent, und rufen dann FindName vorhanden.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.

FrameworkElement verfügt über FindName, RegisterName und UnregisterName 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). FrameworkContentElement hat analoge Verhaltensweisen, mit der Ausnahme, die keine FrameworkContentElement wird jemals einen XAML-Namescope besitzen.FrameworkContentElement has analogous behaviors, with the exception that no FrameworkContentElement will ever own a XAML namescope. Die Methoden existieren auf FrameworkContentElement , damit die Aufrufe letztendlich zu weitergeleitet werden, können ein FrameworkElement übergeordneten Elements.The methods exist on FrameworkContentElement so that the calls can be forwarded eventually to a FrameworkElement parent element.

SetNameScope wird verwendet, um ein vorhandenes Objekt einen neuen XAML-Namescope zuzuordnen.SetNameScope is used to map a new XAML namescope to an existing object. Rufen Sie SetNameScope mehr als einmal zum Zurücksetzen oder deaktivieren Sie die XAML-Namescope, ist jedoch 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. Darüber hinaus GetNameScope wird nicht in der Regel aus Code verwendet.Also, GetNameScope is not typically used from code.

Implementierungen von XAML-NamescopesXAML Namescope Implementations

Die folgenden Klassen implementieren INameScope direkt:The following classes implement INameScope directly:

ResourceDictionary XAML-Namen oder -Namescopes wird nicht verwendet werden. Stattdessen verwendet es Schlüssel, da es die Implementierung eines Wörterbuch handelt.ResourceDictionary does not use XAML names or namescopes ; it uses keys instead, because it is a dictionary implementation. Nur deshalb, ResourceDictionary implementiert INameScope ist, damit es Ausnahmen für Benutzercode auslösen kann, die verdeutlichen den Unterschied zwischen einem wahren XAML-Namescope, und wie ein ResourceDictionary verarbeitet Tasten, und um sicherzustellen, dass die XAML-Namescopes auf nicht angewendet werden ein ResourceDictionary durch übergeordnete Elemente.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.

FrameworkTemplate und Style implementieren INameScope durch explizite Schnittstellendefinitionen.FrameworkTemplate and Style implement INameScope through explicit interface definitions. Die expliziten Implementierungen ermöglichen diese XAML-Namescopes konventionell zu Verhalten, wenn darauf zugegriffen werden die INameScope -Schnittstelle, die ist, wie XAML-Namescopes kommuniziert werden durch WPFWPF interne Prozesse.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 Teil der konventionellen API-Oberfläche FrameworkTemplate und Style, da Sie nur selten zum Aufrufen benötigen der INameScope Methoden FrameworkTemplate und Style direkt aus, und stattdessen andere API verwenden wie z. B. GetTemplateChild.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 ihren eigenen XAML-Namescope, mit der System.Windows.NameScope Hilfsklasse und Herstellen einer Verbindung mit der XAML-Namescope-Implementierung, über die NameScope.NameScope angefügte Eigenschaft: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:

Siehe auchSee also