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 Programmier Objekt werden von der INameScope -Schnittstelle definiert und auch durch die praktische-Klasse NameScopeimplementiert.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 allgemeine Stamm Elemente sind ( Pagez. Windowb. und), immer einen XAML-Namescope.In WPF XAML, elements that are common root elements (such as Page, and Window) always control a XAML namescope. Wenn ein Element, z FrameworkElement . FrameworkContentElement b. oder, das Stamm Element der Seite im Markup XAMLXAML ist, fügt Page ein Prozessor implizit einen Stamm Page hinzu, sodass der einen funktionierenden 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. Wenn Sie einen Namen für ein Objekt in einem WPF-XAML-Namescope nach dem Laden von XAML hinzufügen möchten, müssen RegisterName Sie die entsprechende Implementierung von für das Objekt, das den XAML-Namescope definiert (in der Regel der XAML-Seiten Stamm), aufruft.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 auf das hinzugefügte Objekt nicht anhand des Namens über FindNameMethoden wie verwiesen werden, und Sie können diesen Namen nicht für die Animations Ziel-Zielplattform 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 besteht darin, dass Sie zum RegisterName Registrieren von Namen im XAML-Namescope im aktuellen Stamm der Seite verwenden.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 auf Objekte für Animationen abzielen.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 für RegisterName ein anderes Objekt als das Objekt aufrufen, das den XAML-Namescope definiert, wird der Name weiterhin für den XAML-Namescope registriert, in dem das aufrufende Objekt enthalten ist, RegisterName als ob Sie für das XAML-Namescope, das das Objekt definiert, aufgerufen 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.

Bei Anwendungen, die Programm gesteuert erstellt werden, und nicht aus der geladenen XAML-Datei, muss das Objekt, das einen XAML INameScope-Namescope FrameworkElement definiert FrameworkContentElement , eine oder eine abgeleitete Klasse implementieren, um die Erstellung eines XAML-Namescope in seinem Verein.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 SetNameScope die statische-Methode auf.To create a XAML namescope, you call the static SetNameScope method. Geben Sie das Objekt, dessen Besitzer es ist dependencyObject , als den-Parameter NameScope und einen neuen value konstruktorbefehl als-Parameter an.Specify the object that will own it as the dependencyObject parameter, and a new NameScope constructor call as the value parameter.

dependencyObject Wenn das als für SetNameScope bereitgestellte Objekt INameScope FrameworkElement keine-RegisterName Implementierung ist, hatdasAufrufenvonfüruntergeordneteElementekeineAuswirkung.FrameworkContentElementIf 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 den neuen XAML-Namescope nicht explizit erstellen, wird von Aufrufen RegisterName von 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. Sie müssen zuerst die angewendete Vorlage ermitteln, indem Sie Template den Eigenschafts Wert des Steuer Elements, an dem die Vorlage angewendet wird, erhalten.You first need to determine the applied template, by getting the Template property value of the control where the template is applied. Anschließend wird die Vorlagen Version von FindNameaufgerufen, wobei das Steuerelement übergeben wird, in 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 Steuerungs Autor sind und Sie eine Konvention erstellen, bei der ein bestimmtes benanntes Element in einer angewendeten Vorlage das Ziel für ein Verhalten ist, das durch das Steuerelement selbst GetTemplateChild definiert ist, können Sie die-Methode aus dem Implementierungs Code des Steuer Elements 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 Autor des Steuer Elements darauf zugreifen kann.The GetTemplateChild method is protected, so only the control author has access to it.

Wenn Sie in einer Vorlage arbeiten und den XAML-Namescope abrufen müssen, in dem die Vorlage angewendet wird, können Sie den Wert von TemplatedParentabrufen und dort anrufen. FindNameIf 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.

FrameworkElementverfügt FindNameüber RegisterName die UnregisterName Methoden, und.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 Verhalten, mit der Ausnahme, dass FrameworkContentElement kein XAML-Namescope besitzen wird.FrameworkContentElement has analogous behaviors, with the exception that no FrameworkContentElement will ever own a XAML namescope. Die-Methoden sind FrameworkContentElement in vorhanden, sodass die Aufrufe letztendlich an ein FrameworkElement ü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 einen neuen XAML-Namescope einem vorhandenen-Objekt zuzuordnen.SetNameScope is used to map a new XAML namescope to an existing object. Sie können mehr SetNameScope als einmal aufzurufen, um den XAML-Namescope zurückzusetzen oder zu löschen, dies 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. GetNameScope Außerdem wird in der Regel nicht im 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:

ResourceDictionaryverwendet keine XAML-Namen oder-Namescopes. Stattdessen werden Schlüssel verwendet, da es sich um eine Wörterbuch Implementierung handelt.ResourceDictionary does not use XAML names or namescopes ; it uses keys instead, because it is a dictionary implementation. Der einzige Grund, ResourceDictionary den INameScope implementiert, besteht darin, dass damit Ausnahmen für Benutzercode ausgelöst werden können, um den Unterschied zwischen einem echten XAML- ResourceDictionary Namescope und der Handhabung von Schlüsseln zu verdeutlichen und sicherzustellen, dass XAML-Namescopes nicht auf einen 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.

FrameworkTemplateund Style implementierenINameScope Sie durch explizite Schnittstellendefinitionen.FrameworkTemplate and Style implement INameScope through explicit interface definitions. Die expliziten Implementierungen ermöglichen es diesen XAML-Namescopes, sich konsistent zu Verhalten, wenn INameScope über die-Schnittstelle auf Sie zugegriffen wird, sodass XAML- WPFWPF 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 Teil der herkömmlichen API-Ober FrameworkTemplate Fläche Stylevon und, da Sie die INameScope Methoden nur selten für FrameworkTemplate und Style direkt aufzurufen müssen und stattdessen eine andere API verwenden müssen. GetTemplateChildz. b.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, indem Sie System.Windows.NameScope die-Hilfsklasse verwenden und eine Verbindung mit ihrer XAML-Namescope-Implementierung über die NameScope.NameScope angefügte-Eigenschaft 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:

Siehe auchSee also