Namescopes XAML WPFWPF XAML Namescopes

Os namescopes de XAML são um conceito que identifica objetos que são definidos em XAML.XAML namescopes are a concept that identifies objects that are defined in XAML. Os nomes em um namescope de XAML podem ser usados para estabelecer relações entre os nomes de objetos definidos por XAML e seus equivalentes de instância em uma árvore de objetos.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. Normalmente, os namescopes de XAML no código gerenciado do WPFWPF são criados ao carregar as raízes da página XAML individual de um aplicativo XAML.Typically, XAML namescopes in WPFWPF managed code are created when loading the individual XAML page roots for a XAML application. Os namescopes XAML como objeto de INameScope programação são definidos pela NameScopeinterface e também são implementados pela classe prática .XAML namescopes as the programming object are defined by the INameScope interface and are also implemented by the practical class NameScope.

Namescopes em aplicativos de XAML carregadosNamescopes in Loaded XAML Applications

Em um contexto mais amplo de programação ou de ciência da computação, os conceitos de programação geralmente incluem o princípio de um identificador exclusivo ou de um nome que pode ser usado para acessar um objeto.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. Para sistemas que usam identificadores ou nomes, o namescope define os limites dentro dos quais um processo ou uma técnica pesquisará, se um objeto com esse nome for solicitado ou os limites em que a exclusividade de nomes de identificação é imposta.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. Esses princípios gerais são verdadeiros para namescopes XAML.These general principles are true for XAML namescopes. No WPF, os namescopes de XAML são criados no elemento raiz de uma página XAML quando a página é carregada.In WPF, XAML namescopes are created on the root element for a XAML page when the page is loaded. Cada nome especificado na página XAML, começando na raiz da página, é adicionado a um namescopes de XAML pertinente.Each name specified within the XAML page starting at the page root is added to a pertinent XAML namescope.

No WPF XAML, elementos que são Pageelementos radiculares comuns (como , e Window) sempre controlam um namescope XAML.In WPF XAML, elements that are common root elements (such as Page, and Window) always control a XAML namescope. Se um elemento FrameworkElement FrameworkContentElement como ou é o elemento raiz XAMLXAML da página Page na marcação, Page um processador adiciona uma raiz implicitamente para que possa fornecer um namescope XAML em funcionamento.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.

Observação

As ações de build do WPF criam um namescope de XAML para uma produção de XAML mesmo se os atributos Name ou x:Name não estiverem definidos em nenhum elemento na marcação de XAMLXAML.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.

Se você tentar usar o mesmo nome duas vezes em qualquer namescope de XAML, uma exceção será gerada.If you try to use the same name twice in any XAML namescope, an exception is raised. Para o XAML do WPF que tem code-behind e faz parte de um aplicativo compilado, a exceção é gerada em tempo de compilação por ações de compilação do WPF, ao criar a classe gerada para a página durante a compilação de marcação inicial.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. Para o XAML que não é compilado por marcação por qualquer ação de build, as exceções relacionadas a problemas de namescopes de XAML podem ser geradas quando o XAML é carregado.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. Os designers de XAML também podem prever problemas de namescope de XAML em tempo de design.XAML designers might also anticipate XAML namescope issues at design time.

Adicionando objetos a árvores de objetos de runtimeAdding Objects to Runtime Object Trees

O momento em que o XAML é analisado representa o momento em que um namescope de XAML do WPF é criado e definido.The moment that XAML is parsed represents the moment in time that a WPF XAML namescope is created and defined. Se você adicionar um objeto a uma árvore de objetos em um ponto no tempo após o momento em que o XAML que produziu a árvore foi analisado, um valor Name ou x:Name no novo objeto não atualizará automaticamente as informações em um namescope de XAML.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. Para adicionar um nome para um objeto em um namescope WPF XAML depois que RegisterName xAML é carregado, você deve chamar a implementação apropriada do objeto que define o namescope XAML, que é tipicamente a raiz da página XAML.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. Se o nome não estiver registrado, o objeto adicionado não poderá FindNameser referenciado por nome através de métodos como , e você não poderá usar esse nome para segmentação de animação.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.

O cenário mais comum para desenvolvedores RegisterName de aplicativos é que você usará para registrar nomes no namescope XAML na raiz atual da página.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. RegisterNamefaz parte de um cenário importante para storyboards que visam objetos para animações.RegisterName is part of an important scenario for storyboards that target objects for animations. Para obter mais informações, consulte Visão geral de storyboards.For more information, see Storyboards Overview.

Se você RegisterName chamar um objeto diferente do objeto que define o namescope XAML, o nome ainda será registrado no namescope XAML que o objeto de chamada é mantido dentro, como se você tivesse chamado RegisterName o objeto definidor do namescope XAML.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.

Namescopes de XAML no códigoXAML Namescopes in Code

Você pode criar e usar namescopes de XAML no código.You can create and then use XAML namescopes in code. As APIs e os conceitos envolvidos na criação de namescopes de XAML são os mesmos, mesmo para um uso de código puro, porque o processador de XAML para o WPFWPF usa essas APIs e conceitos quando processa o próprio XAML.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. Os conceitos e a API existem principalmente para que seja possível encontrar objetos por nome em uma árvore de objeto que é normalmente definida, parcialmente ou totalmente, em XAML.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.

Para aplicativos criados de forma programática, e não de XAML carregado, o objeto que INameScopedefine um FrameworkElement FrameworkContentElement namescope XAML deve implementar , ou ser uma classe ou derivada, a fim de suportar a criação de um namescope XAML em suas instâncias.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.

Além disso, para qualquer elemento que não é carregado e processado por um processador de XAML, o namescope de XAML do objeto não é criado ou inicializado por padrão.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. Você deve criar explicitamente um novo namescope de XAML para qualquer objeto no qual você pretende registrar nomes posteriormente.You must explicitly create a new XAML namescope for any object that you intend to register names into subsequently. Para criar um namescope XAML, SetNameScope você chama o método estático.To create a XAML namescope, you call the static SetNameScope method. Especifique o objeto dependencyObject que o possuirá NameScope como parâmetro value e uma nova chamada do construtor como parâmetro.Specify the object that will own it as the dependencyObject parameter, and a new NameScope constructor call as the value parameter.

Se o objeto dependencyObject previsto SetNameScope como INameScope para FrameworkElement não FrameworkContentElementser RegisterName uma implementação, ou , chamar quaisquer elementos infantis não terá efeito.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. Se você não conseguir criar o novo namescope XAML explicitamente, então as chamadas RegisterName aumentarão uma exceção.If you fail to create the new XAML namescope explicitly, then calls to RegisterName will raise an exception.

Para obter um exemplo de uso de APIs de namescope de XAML no código, consulte Definir um escopo de nome.For an example of using XAML namescope APIs in code, see Define a Name Scope.

Namescopes de XAML em estilos e modelosXAML Namescopes in Styles and Templates

Os estilos e modelos no WPFWPF fornecem a capacidade para reutilizar e reaplicar conteúdo de uma maneira simples.Styles and templates in WPFWPF provide the ability to reuse and reapply content in a straightforward way. No entanto, os estilos e modelos também podem incluir elementos com nomes XAML definidos no nível do modelo.However, styles and templates might also include elements with XAML names defined at the template level. Esse mesmo modelo pode ser usado várias vezes em uma página.That same template might be used multiple times in a page. Por esse motivo, os estilos e modelos definem seus próprios namescopes de XAML, independente do local, em uma árvore de objetos, em que o estilo ou o modelo é aplicado.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.

Considere o exemplo a seguir: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>

Aqui, o mesmo modelo é aplicado a dois botões diferentes.Here, the same template is applied to two different buttons. Se os modelos não tivessem namescopes de XAML distintos, o nome TheBorder usado no modelo causaria uma colisão de nomes no namescope de XAML.If templates did not have discrete XAML namescopes, the TheBorder name used in the template would cause a name collision in the XAML namescope. Cada instanciação do modelo tem seu próprio namescope de XAML, portanto, neste exemplo, cada namescope de XAML de modelo instanciado conteria exatamente um nome.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.

Os estilos também definem seus próprios namescopes de XAML, principalmente para que as partes de storyboards possam ter nomes específicos atribuídos.Styles also define their own XAML namescope, mostly so that parts of storyboards can have particular names assigned. Esses nomes habilitam comportamentos específicos de controle que se destinarão a elementos desse nome, mesmo que o modelo tenha sido redefinido como parte da personalização do controle.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.

Devido aos namescopes de XAML separados, encontrar elementos nomeados em um modelo é mais desafiador que localizar um elemento nomeado que não faz parte do modelo em uma página.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. Primeiro você precisa determinar o modelo aplicado, obtendo o Template valor de propriedade do controle onde o modelo é aplicado.You first need to determine the applied template, by getting the Template property value of the control where the template is applied. Em seguida, você chama FindNamea versão de modelo de , passando o controle onde o modelo foi aplicado como o segundo parâmetro.Then, you call the template version of FindName, passing the control where the template was applied as the second parameter.

Se você é um autor de controle e está gerando uma convenção onde um determinado elemento nomeado em um modelo aplicado GetTemplateChild é o alvo de um comportamento definido pelo próprio controle, você pode usar o método a partir do seu código de implementação de controle.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. O GetTemplateChild método é protegido, então apenas o autor de controle tem acesso a ele.The GetTemplateChild method is protected, so only the control author has access to it.

Se você estiver trabalhando dentro de um modelo e precisar chegar ao namescope XAML TemplatedParentonde o FindName modelo é aplicado, obtenha o valor de , e então ligue para lá.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. Um exemplo de trabalho dentro do modelo seria se você estivesse escrevendo a implementação do manipulador de eventos em que o evento será acionado de um elemento em um modelo aplicado.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.

FrameworkElementtem FindName RegisterName , UnregisterName e métodos.FrameworkElement has FindName, RegisterName and UnregisterName methods. Se o objeto em que você chama esses métodos é proprietário de um namescope de XAML, os métodos chamam nos métodos do namescope de XAML relevante.If the object you call these methods on owns a XAML namescope, the methods call into the methods of the relevant XAML namescope. Caso contrário, o elemento pai é verificado para ver se ele é proprietário de um namescope de XAML e esse processo continua recursivamente até que seja encontrado um namescope de XAML (devido ao comportamento do processador de XAML, é garantido que haverá um namescope de XAML na raiz).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). FrameworkContentElementtem comportamentos análogos, com FrameworkContentElement a exceção de que nunca terá um namescope XAML.FrameworkContentElement has analogous behaviors, with the exception that no FrameworkContentElement will ever own a XAML namescope. Os métodos FrameworkContentElement existem para que as chamadas possam FrameworkElement ser encaminhadas eventualmente para um elemento pai.The methods exist on FrameworkContentElement so that the calls can be forwarded eventually to a FrameworkElement parent element.

SetNameScopeé usado para mapear um novo namescope XAML para um objeto existente.SetNameScope is used to map a new XAML namescope to an existing object. Você pode SetNameScope ligar mais de uma vez para reiniciar ou limpar o namescope XAML, mas isso não é um uso comum.You can call SetNameScope more than once in order to reset or clear the XAML namescope, but that is not a common usage. Além GetNameScope disso, não é normalmente usado a partir de código.Also, GetNameScope is not typically used from code.

Implementações de namescope de XAMLXAML Namescope Implementations

As seguintes INameScope classes implementam diretamente:The following classes implement INameScope directly:

ResourceDictionarynão usa nomes XAML ou namescopes; em vez disso, usa chaves, porque é uma implementação de dicionário.ResourceDictionary does not use XAML names or namescopes ; it uses keys instead, because it is a dictionary implementation. A única ResourceDictionary razão INameScope pela qual implementa é para que ele possa aumentar as exceções ao código ResourceDictionary do usuário que ajudam a esclarecer a distinção entre um ResourceDictionary verdadeiro namescope XAML e como um manipula chaves, e também para garantir que os namescopes XAML não sejam aplicados a um dos elementos dos pais.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.

FrameworkTemplatee Style INameScope implementar através de definições explícitas de interface.FrameworkTemplate and Style implement INameScope through explicit interface definitions. As implementações explícitas permitem que esses namescopes XAML se INameScope comportem convencionalmente quando são acessados através WPFWPF da interface, que é como os namescopes XAML são comunicados por processos internos.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. Mas as definições explícitas de interface não FrameworkTemplate fazem Styleparte da superfície convencional da INameScope API FrameworkTemplate Style e, porque você raramente precisa GetTemplateChildchamar os métodos e diretamente, e em vez disso usaria outra API como .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.

As classes a seguir definem seu próprio System.Windows.NameScope namescope XAML, usando a classe helper NameScope.NameScope e conectando-se à implementação do namescope XAML através da propriedade anexada: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:

Confira tambémSee also