WPF XAML 이름 범위WPF XAML Namescopes

XAML 이름 범위는 XAML에 정의된 개체를 식별하는 개념입니다.XAML namescopes are a concept that identifies objects that are defined in XAML. XAML 이름 범위의 이름은 XAML로 정의된 개체 이름과 개체 트리에서 그에 해당하는 인스턴스 간의 관계를 설정하는 데 사용할 수 있습니다.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. 일반적으로 WPFWPF 관리 코드의 XAML 이름 범위는 XAML 애플리케이션의 개별 XAML 페이지 루트를 로드할 때 만들어집니다.Typically, XAML namescopes in WPFWPF managed code are created when loading the individual XAML page roots for a XAML application. 프로그래밍 개체로 XAML 이름 범위는 인터페이스에 INameScope 의해 정의 되 고 NameScope또한 실용적인 클래스에 의해 구현 됩니다.XAML namescopes as the programming object are defined by the INameScope interface and are also implemented by the practical class NameScope.

로드된 XAML 애플리케이션의 이름 범위Namescopes in Loaded XAML Applications

더욱 폭넓은 프로그래밍이나 컴퓨터 과학의 측면에서 프로그래밍 개념에는 흔히 개체에 액세스하는 데 사용할 수 있는 고유한 식별자 또는 이름의 원칙이 포함됩니다.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. 식별자나 이름을 사용하는 시스템의 경우 이름 범위는 해당 이름의 개체가 요청되는 경우 프로세스 또는 기술을 통해 검색할 위치의 경계나 식별 이름의 고유성이 적용되는 경계를 정의합니다.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. 이러한 일반적인 원칙은 XAML 이름 범위에도 해당됩니다.These general principles are true for XAML namescopes. WPF에서 XAML 이름 범위는 페이지가 로드될 때 XAML 페이지의 루트 요소에 만들어집니다.In WPF, XAML namescopes are created on the root element for a XAML page when the page is loaded. XAML 페이지 내의 페이지 루트에서부터 지정된 각 이름은 관련 XAML 이름 범위에 추가됩니다.Each name specified within the XAML page starting at the page root is added to a pertinent XAML namescope.

WPF XAML에서 공통 루트 요소(예: Page및)인 Window요소는 항상 XAML 네임스코프를 제어합니다.In WPF XAML, elements that are common root elements (such as Page, and Window) always control a XAML namescope. 마크업에서 페이지의 FrameworkElement FrameworkContentElement 루트 요소와 같은 요소가 있는 경우 XAMLXAML 프로세서는 Page 루트를 암시적으로 Page 추가하여 작업 중인 XAML 네임스코프를 제공할 수 있습니다.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.

참고

WPF 빌드 작업에서는 XAMLXAML 태그의 모든 요소에 대해 Name 또는 x:Name 특성이 정의되지 않은 경우에도 XAML 프로덕션을 위한 XAML 이름 범위가 만들어집니다.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.

한 XAML 이름 범위에서 같은 이름을 두 번 사용하려고 하면 예외가 발생합니다.If you try to use the same name twice in any XAML namescope, an exception is raised. 코드 숨김 파일이 있고 컴파일된 애플리케이션의 일부인 WPF XAML의 경우에는 빌드 시 WPF 빌드 작업에서 초기 태그 컴파일 중 페이지에 대해 생성된 클래스를 만들 때 예외가 발생합니다.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. 빌드 작업을 통해 태그 컴파일되지 않은 XAML의 경우에는 XAML이 로드될 때 XAML 이름 범위 문제와 관련된 예외가 발생할 수 있습니다.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 디자이너가 디자인 타임에 XAML 이름 범위 문제를 예상할 수도 있습니다.XAML designers might also anticipate XAML namescope issues at design time.

런타임 개체 트리에 개체 추가Adding Objects to Runtime Object Trees

XAML이 구문 분석되는 시점은 WPF XAML 이름 범위가 만들어지고 정의되는 시점입니다.The moment that XAML is parsed represents the moment in time that a WPF XAML namescope is created and defined. 개체 트리를 생성한 XAML이 구문 분석된 후에 개체 트리에 개체를 추가할 경우에는 새 개체의 Name 또는 x:Name 값에 따라 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. XAML이 로드된 후 WPF XAML 네임스코프에 개체이름을 추가하려면 일반적으로 RegisterName XAML 페이지 루트인 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. 이름이 등록되지 않은 경우 추가된 개체는 FindName와 같은 메서드를 통해 이름으로 참조할 수 없으며 애니메이션 대상 지정에 해당 이름을 사용할 수 없습니다.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.

응용 프로그램 개발자를 위한 가장 일반적인 RegisterName 시나리오는 페이지의 현재 루트에 있는 XAML 네임스코프에 이름을 등록하는 데 사용됩니다.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는 애니메이션에 대한 오브젝트를 대상으로 하는 스토리보드의 중요한 시나리오의 일부입니다.RegisterName is part of an important scenario for storyboards that target objects for animations. 자세한 내용은 스토리보드 개요를 참조하세요.For more information, see Storyboards Overview.

XAML RegisterName 네임스코프를 정의하는 개체가 아닌 다른 개체를 호출하는 경우 XAML namescope 정의 개체에 호출한 RegisterName 것처럼 호출 개체가 유지되는 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.

코드의 XAML 이름 범위XAML Namescopes in Code

코드에서 XAML 이름 범위를 만든 다음 사용할 수 있습니다.You can create and then use XAML namescopes in code. XAML 이름 범위를 만드는 데 관련된 API 및 개념은 순수형 코드를 사용하는 경우에도 동일합니다. WPFWPF용 XAML 프로세서에서는 XAML 자체를 처리할 때 이러한 API 및 개념을 사용하기 때문입니다.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. 이 개념 및 API는 대개 일부 또는 전체가 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.

로드된 XAML이 아닌 프로그래밍 방식으로 만들어진 응용 프로그램의 경우 XAML 네임스코프를 INameScope정의하는 개체는 해당 인스턴스에서 XAML 네임스코프 생성을 지원하기 위해 구현하거나 또는 FrameworkElement 파생된 클래스여야 FrameworkContentElement 합니다.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.

또한 XAML 프로세서로 로드 및 처리되지 않는 모든 요소에 대해서는 기본적으로 개체의 XAML 이름 범위가 만들어지거나 초기화되지 않습니다.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. 따라서 이후에 이름을 등록하려는 모든 개체에 대해 명시적으로 새 XAML 이름 범위를 만들어야 합니다.You must explicitly create a new XAML namescope for any object that you intend to register names into subsequently. XAML 네임스코프를 만들려면 SetNameScope 정적 메서드를 호출합니다.To create a XAML namescope, you call the static SetNameScope method. 매개 변수로 dependencyObject 소유할 개체를 지정하고 NameScope 새 생성자 value 호출을 매개 변수로 지정합니다.Specify the object that will own it as the dependencyObject parameter, and a new NameScope constructor call as the value parameter.

dependencyObject 제공 SetNameScope 된 개체가 INameScope 구현 FrameworkElement 또는 FrameworkContentElement에 대한 RegisterName 호출이 아닌 경우 자식 요소에 대한 호출은 영향을 미치지 않습니다.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. 새 XAML 네임스코프를 명시적으로 만들지 못하면 RegisterName 호출이 예외를 발생시게 됩니다.If you fail to create the new XAML namescope explicitly, then calls to RegisterName will raise an exception.

코드에서 XAML 이름 범위 API를 사용하는 예제를 보려면 이름 범위 정의를 참조하세요.For an example of using XAML namescope APIs in code, see Define a Name Scope.

스타일 및 템플릿의 XAML 이름 범위XAML Namescopes in Styles and Templates

WPFWPF의 스타일 및 템플릿을 사용하면 간편하게 콘텐츠를 다시 사용 및 적용할 수 있지만Styles and templates in WPFWPF provide the ability to reuse and reapply content in a straightforward way. 템플릿 수준에서 XAML 이름이 정의된 요소가 스타일 및 템플릿에 포함될 수 있습니다.However, styles and templates might also include elements with XAML names defined at the template level. 이런 템플릿은 한 페이지에서 여러 번 사용될 수 있기 때문에That same template might be used multiple times in a page. 스타일과 템플릿은 모두 해당 스타일 또는 템플릿이 적용되는 개체 트리 내의 위치와는 상관없이 고유한 XAML 이름 범위를 정의합니다.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.

다음과 같은 예제를 참조하세요.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>

여기에서는 두 개의 단추에 동일한 템플릿이 적용됩니다.Here, the same template is applied to two different buttons. 템플릿에 개별 XAML 이름 범위가 없으면 템플릿에 사용된 TheBorder 이름 때문에 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. 템플릿의 각 인스턴스에는 고유한 XAML 이름 범위가 있으므로 이 예제에서 인스턴스화된 각 템플릿의 XAML 이름 범위에는 정확하게 하나의 이름만 포함됩니다.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.

스타일도 고유한 XAML 이름 범위를 정의하므로 대부분의 경우 스토리보드의 각 부분에 특정 이름이 할당될 수 있습니다.Styles also define their own XAML namescope, mostly so that parts of storyboards can have particular names assigned. 이러한 이름을 사용하면 컨트롤 사용자 지정 과정에서 템플릿이 재정의된 경우에도 해당 이름의 요소를 대상으로 하는 특정 동작을 제어할 수 있습니다.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.

XAML 이름 범위가 분리되어 있으므로 템플릿에서 명명된 요소를 찾는 것이 페이지에서 템플릿 형식이 아닌 명명된 요소를 찾는 것보다 복잡합니다.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. 먼저 템플릿이 적용되는 컨트롤의 Template 속성 값을 얻어 적용된 템플릿을 결정해야 합니다.You first need to determine the applied template, by getting the Template property value of the control where the template is applied. 그런 다음 템플릿이 두 FindName번째 매개 변수로 적용된 컨트롤을 전달하는 템플릿 버전의 을 호출합니다.Then, you call the template version of FindName, passing the control where the template was applied as the second parameter.

컨트롤 작성자인 경우 적용된 템플릿의 특정 명명된 요소가 컨트롤 자체에 의해 정의된 동작의 대상인 규칙을 생성하는 경우 GetTemplateChild 컨트롤 구현 코드에서 메서드를 사용할 수 있습니다.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. 메서드는 GetTemplateChild 보호되므로 컨트롤 작성자만 이 메서드에 액세스할 수 있습니다.The GetTemplateChild method is protected, so only the control author has access to it.

템플릿 내에서 작업하는 경우 템플릿이 적용되는 XAML 네임스코프로 이동하려면 TemplatedParent에서 의 값을 얻은 FindName 다음 이 곳에 호출합니다.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. 적용된 템플릿의 요소에서 이벤트가 발생되는 이벤트 처리기를 구현하는 경우가 템플릿 내에서 작업하는 예에 해당합니다.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.

FrameworkElementFindName RegisterName UnregisterName 메서드를 가합니다.FrameworkElement has FindName, RegisterName and UnregisterName methods. 이러한 메서드를 호출하는 개체에 고유한 XAML 이름 범위가 있는 경우 이러한 메서드는 관련 XAML 이름 범위의 메서드를 호출합니다.If the object you call these methods on owns a XAML namescope, the methods call into the methods of the relevant XAML namescope. 그렇지 않은 경우에는 부모 요소에 고유한 XAML 이름 범위가 있는지 확인하며, 이 확인 과정은 XAML 이름 범위를 찾을 때까지 재귀적으로 계속됩니다(XAML 프로세서의 동작 때문에 루트에는 반드시 XAML 이름 범위가 있음).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). FrameworkContentElementXAML 네임스코프를 소유하지 않는 FrameworkContentElement 경우를 제외하고는 유사한 동작이 있습니다.FrameworkContentElement has analogous behaviors, with the exception that no FrameworkContentElement will ever own a XAML namescope. 호출이 결국 FrameworkContentElement 부모 요소로 전달될 수 FrameworkElement 있도록 메서드가 존재합니다.The methods exist on FrameworkContentElement so that the calls can be forwarded eventually to a FrameworkElement parent element.

SetNameScope은 새 XAML 네임스코프를 기존 개체에 매핑하는 데 사용됩니다.SetNameScope is used to map a new XAML namescope to an existing object. XAML SetNameScope 네임스코프를 재설정하거나 지우기 위해 두 번 이상 호출할 수 있지만 일반적인 용도는 아닙니다.You can call SetNameScope more than once in order to reset or clear the XAML namescope, but that is not a common usage. GetNameScope 또한 일반적으로 코드에서 사용되지 않습니다.Also, GetNameScope is not typically used from code.

XAML 이름 범위 구현XAML Namescope Implementations

다음 클래스는 INameScope 직접 구현합니다.The following classes implement INameScope directly:

ResourceDictionaryXAML 이름 이나 네임 스코프를 사용 하지 않습니다. 사전 구현이기 때문에 대신 키를 사용합니다.ResourceDictionary does not use XAML names or namescopes ; it uses keys instead, because it is a dictionary implementation. ResourceDictionary 구현하는 INameScope 유일한 이유는 실제 XAML 이름 범위와 키 ResourceDictionary 를 처리하는 방법 간의 구분을 명확히 하고 XAML 이름 범위가 부모 요소에 적용되지 않도록 하는 데 ResourceDictionary 도움이 되는 사용자 코드에 예외를 발생시킬 수 있기 때문입니다.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.

FrameworkTemplateStyle 명시적 INameScope 인터페이스 정의를 통해 구현할 수 있습니다.FrameworkTemplate and Style implement INameScope through explicit interface definitions. 명시적 구현을 통해 이러한 XAML 네임스코프는 INameScope 인터페이스를 통해 액세스할 때 일반적으로 실행될 수 있으며, WPFWPF 이는 XAML 네임스코프가 내부 프로세스에서 전달되는 방식입니다.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. 그러나 명시적 인터페이스 정의는 의 기존 API FrameworkTemplate Style표면의 일부가 아니며, INameScope 메서드를 FrameworkTemplate Style 직접 호출할 필요가 거의 없기 GetTemplateChild때문에 대신 에 와 같은 다른 API를 사용합니다.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.

다음 클래스는 도우미 클래스를 System.Windows.NameScope 사용하고 연결된 속성을 통해 XAML 네임스코프 구현에 NameScope.NameScope 연결하여 자체 XAML 네임스코프를 정의합니다.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:

참고 항목See also