조건부 XAMLConditional XAML

조건부 XAML은 XAML 태그에 ApiInformation.IsApiContractPresent 메서드를 사용하는 방법을 제공합니다.Conditional XAML provides a way to use the ApiInformation.IsApiContractPresent method in XAML markup. 이를 통해 코드 숨김을 사용하지 않고도 API의 존재 여부를 기반으로 태그에서 속성을 설정하고 개체를 인스턴스화할 수 있습니다.This lets you set properties and instantiate objects in markup based on the presence of an API without needing to use code behind. 조건부 XML은 요소나 특성을 런타임에 사용할 수 있는지 파악하기 위해 선택적으로 구문 분석합니다.It selectively parses elements or attributes to determine whether they will be available at runtime. 조건부 명령문은 런타임에 평가되며, true로 평가된 경우 조건부 XAML 태그로 자격이 부여된 요소가 구문 분석되고, 그렇지 않으면 무시됩니다.Conditional statements are evaluated at runtime, and elements qualified with a conditional XAML tag are parsed if they evaluate to true; otherwise, they are ignored.

조건부 XAML은 크리에이터스 업데이트(버전 1703 빌드 15063)부터 사용할 수 있습니다.Conditional XAML is available starting with the Creators Update (version 1703, build 15063). 조건부 XAML을 사용하려면 Visual Studio 프로젝트의 최소 버전이 15063(크리에이터스 업데이트) 이상으로 설정되어야 하며, 대상 버전은 최소 버전 이상으로 설정되어야 합니다.To use conditional XAML, the Minimum Version of your Visual Studio project must be set to build 15063 (Creators Update) or later, and the Target Version be set to a later version than the Minimum. Visual Studio 프로젝트 구성에 대한 자세한 내용은 버전 적응 앱을 참조하세요.See Version adaptive apps for more info about configuring your Visual Studio project.

참고

빌드 15063 이하의 최소 버전으로 버전 적응 앱을 만들려면 XAML이 아닌 버전 적응 코드를 사용해야 합니다.To create a version adaptive app with a Minimum Version less than build 15063, you must use version adaptive code, not XAML.

ApiInformation 및 API 계약에 대한 중요한 배경 정보는 버전 적응 앱을 참조하세요.For important background info about ApiInformation and API contracts, see Version adaptive apps.

조건부 네임스페이스Conditional namespaces

XAML에서 조건부 메서드를 사용하려면 먼저 페이지 맨 위에 조건부 XAML 네임스페이스를 선언해야 합니다.To use a conditional method in XAML, you must first declare a conditional XAML namespace at the top of your page. 조건부 네임스페이스의 가상 코드 예는 다음과 같습니다.Here's a psuedo-code example of a conditional namespace:

xmlns:myNamespace="schema?conditionalMethod(parameter)"

조건부 네임스페이스는 '?' 구분 기호를 사용하여 두 부분으로 나눌 수 있습니다.A conditional namespace can be broken down into two parts separated by the '?' delimiter.

  • 구분 기호 앞의 내용은 참조되는 API가 포함된 네임스페이스 또는 스키마를 나타냅니다.The content preceding the delimiter indicates the namespace or schema that contains the API being referenced.
  • '?' 구분 기호 뒤의 내용은 조건부 네임스페이스가 true 또는 false로 평가될지 결정하는 조건부 메서드를 나타냅니다.The content after the '?' delimiter represents the conditional method that determines whether the conditional namespace evaluates to true or false.

대부분의 경우 스키마가 기본 XAML 네임스페이스가 됩니다.In most cases, the schema will be the default XAML namespace:

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

조건부 XAML은 다음 조건부 메서드를 지원합니다.Conditional XAML supports the following conditional methods:

방법Method InverseInverse
IsApiContractPresent(ContractName, VersionNumber)IsApiContractPresent(ContractName, VersionNumber) IsApiContractNotPresent(ContractName, VersionNumber)IsApiContractNotPresent(ContractName, VersionNumber)
IsTypePresent(ControlType)IsTypePresent(ControlType) IsTypeNotPresent(ControlType)IsTypeNotPresent(ControlType)
IsPropertyPresent(ControlType, PropertyName)IsPropertyPresent(ControlType, PropertyName) IsPropertyNotPresent(ControlType, PropertyName)IsPropertyNotPresent(ControlType, PropertyName)

이 문서에서 나중에 나올 섹션에서 이런 메서드에 대해 더 자세히 설명하겠습니다.We discuss these methods further in later sections of this article.

참고

IsApiContractPresent 및 IsApiContractNotPresent를 사용하는 것이 좋습니다.We recommend you use IsApiContractPresent and IsApiContractNotPresent. 다른 조건은 Visual Studio 디자인 환경에서 완전하게 지원되지 않습니다.Other conditionals are not fully supported in the Visual Studio design experience.

네임스페이스 만들기 및 속성 설정Create a namespace and set a property

이 예에서는 앱이 Fall Creators Update 이상에서 실행될 경우 텍스트 블록의 콘텐츠로 "Hello, Conditional XAML"을 표시하며, 기본값은 이전 버전에 실행이 되는 경우에는 콘텐츠를 표시하지 않도록 지정되어 있습니다.In this example, you display, "Hello, Conditional XAML", as the content of a text block if the app runs on the Fall Creators Update or later, and default to no content if it's on a previous version.

먼저 'contract5Present'라는 접두사를 가진 사용자 지정 네임스페이스를 정의하고, 기본 XAML 네임스페이스(https://schemas.microsoft.com/winfx/2006/xaml/presentation) 를 TextBlock.Text 속성이 포함된 스키마로 사용합니다.First, define a custom namespace with the prefix 'contract5Present' and use the default XAML namespace (https://schemas.microsoft.com/winfx/2006/xaml/presentation) as the schema containing the TextBlock.Text property. 이 조건부 네임스페이스를 만들려면 스키마 뒤에 '?'To make this a conditional namespace, add the ‘?’ 구분 기호를 추가합니다.delimiter after the schema.

그런 다음, Fall Creators Update 이상을 실행하는 디바이스에서 true를 반환하는 조건부를 정의합니다.You then define a conditional that returns true on devices that are running the Fall Creators Update or later. ApiInformation 메서드 IsApiContractPresent를 사용하여 5번째 버전의 UniversalApiContract를 확인할 수 있습니다.You use the ApiInformation method IsApiContractPresent to check for the 5th version of the UniversalApiContract. UniversalApiContract 버전 5는 Fall Creators Update(SDK 16299)와 함께 출시되었습니다.Version 5 of the UniversalApiContract was released with the Fall Creators Update (SDK 16299).

xmlns:contract5Present="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractPresent(Windows.Foundation.UniversalApiContract,5)"

네임스페이스가 정의된 후, 네임스페이스 접두사를 TextBox의 Text 속성 앞에 추가하여 런타임에 조건부로 설정되는 속성이 되도록 합니다.After the namespace is defined, you prepend the namespace prefix to the Text property of your TextBox to qualify it as a property that should be set conditionally at runtime.

<TextBlock contract5Present:Text="Hello, Conditional XAML"/>

완성된 XAML은 다음과 같습니다.Here's the complete XAML.

<Page
    x:Class="ConditionalTest.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:contract5Present="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractPresent(Windows.Foundation.UniversalApiContract,5)">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <TextBlock contract5Present:Text="Hello, Conditional XAML"/>
    </Grid>
</Page>

Fall Creators Update에서 이 예를 실행하면 “Hello, Conditional XAML”이라는 텍스트가 표시되며, 크리에이터스 업데이트에서 실행하면 텍스트가 표시되지 않습니다.When you run this example on the Fall Creators Update, the text, "Hello, Conditional XAML" is shown; when you run it on the Creators Update, no text is shown.

조건부 XAML을 사용하여 코드에서 하던 API 검사를 태그에서 대신할 수 있습니다.Conditional XAML lets you perform the API checks you can do in code in your markup instead. 이 검사와 동일한 기능을 하는 코드는 다음과 같습니다.Here's the equivalent code for this check.

if (ApiInformation.IsApiContractPresent("Windows.Foundation.UniversalApiContract", 5))
{
    textBlock.Text = "Hello, Conditional XAML";
}

IsApiContractPresent 메서드는 contractName 매개 변수에 대한 문자열을 받지만, XAML 네임스페이스 선언에는 따옴표(" ")를 사용할 수 없음을 유의하십시오.Notice that even though the IsApiContractPresent method takes a string for the contractName parameter, you don't put it in quotes (" ") in the XAML namespace declaration.

if/else 조건 사용Use if/else conditions

이전 예에서 Text 속성은 앱이 Fall Creators Update에서 실행되는 경우에만 설정됩니다.In the previous example, the Text property is set only when the app runs on the Fall Creators Update. 하지만 Creators Update에서 실행될 때 다른 텍스트를 표시하려면 어떻게 할까요?But what if you want to show different text when it runs on the Creators Update? 다음과 같이 조건부 한정자 없이 Text 속성을 설정할 수 있습니다.You could try to set the Text property without a conditional qualifier, like this.

<!-- DO NOT USE -->
<TextBlock Text="Hello, World" contract5Present:Text="Hello, Conditional XAML"/>

이는 크리에이터스 업데이트에서 실행될 때 작동하지만, Fall Creators Update에서 실행될 때는 Text 속성이 두 번 이상 설정되어 있다는 오류가 발생합니다.This will work when it runs on the Creators Update, but when it runs on the Fall Creators Update, you get an error saying that the Text property is set more than once.

앱이 Windows 10의 다른 버전에서 실행될 때 다른 텍스트가 표시되도록 설정하려면, 다른 조건이 필요합니다.To set different text when the app runs on different versions of Windows 10, you need another condition. 조건부 XAML은 다음과 같이 if/else 조건을 만들 수 있는 지원되는 각 ApiInformation 메서드의 반대 메서드를 제공합니다.Conditional XAML provides an inverse of each supported ApiInformation method to let you create if/else conditional scenarios like this.

현재 디바이스가 지정된 계약 및 버전 번호를 포함할 경우 IsApiContractPresent 메서드는 true를 반환합니다.The IsApiContractPresent method returns true if the current device contains the specified contract and version number. 예를 들어, 앱이 크리에이터스 업데이트에서 실행된다고 가정하면, 유니버설 API 계약의 4번째 버전을 가집니다.For example, assume your app is running on the Creators Update, which has the 4th version of the universal API Contract.

IsApiContractPresent에 대한 다양한 호출의 결과는 다음과 같습니다.Various calls to IsApiContractPresent would have these results:

  • IsApiContractPresent(Windows.Foundation.UniversalApiContract, 5) = falseIsApiContractPresent(Windows.Foundation.UniversalApiContract, 5) = false
  • IsApiContractPresent(Windows.Foundation.UniversalApiContract, 4) = trueIsApiContractPresent(Windows.Foundation.UniversalApiContract, 4) = true
  • IsApiContractPresent(Windows.Foundation.UniversalApiContract, 3) = trueIsApiContractPresent(Windows.Foundation.UniversalApiContract, 3) = true
  • IsApiContractPresent(Windows.Foundation.UniversalApiContract, 2) = trueIsApiContractPresent(Windows.Foundation.UniversalApiContract, 2) = true
  • IsApiContractPresent(Windows.Foundation.UniversalApiContract, 1) = true.IsApiContractPresent(Windows.Foundation.UniversalApiContract, 1) = true.

IsApiContractNotPresent는 IsApiContractPresent의 반대를 반환합니다.IsApiContractNotPresent returns the inverse of IsApiContractPresent. IsApiContractNotPresent에 대한 호출의 결과는 다음과 같습니다.Calls to IsApiContractNotPresent would have these results:

  • IsApiContractNotPresent(Windows.Foundation.UniversalApiContract, 5) = trueIsApiContractNotPresent(Windows.Foundation.UniversalApiContract, 5) = true
  • IsApiContractNotPresent(Windows.Foundation.UniversalApiContract, 4) = falseIsApiContractNotPresent(Windows.Foundation.UniversalApiContract, 4) = false
  • IsApiContractNotPresent(Windows.Foundation.UniversalApiContract, 3) = falseIsApiContractNotPresent(Windows.Foundation.UniversalApiContract, 3) = false
  • IsApiContractNotPresent(Windows.Foundation.UniversalApiContract, 2) = falseIsApiContractNotPresent(Windows.Foundation.UniversalApiContract, 2) = false
  • IsApiContractNotPresent(Windows.Foundation.UniversalApiContract, 1) = falseIsApiContractNotPresent(Windows.Foundation.UniversalApiContract, 1) = false

반대 조건을 사용하려면 IsApiContractNotPresent 조건을 사용하는 두 번째 조건부 XAML 네임스페이스를 만들어야 합니다.To use the inverse condition, you create a second conditional XAML namespace that uses the IsApiContractNotPresent conditional. 여기를 보면 접두사 'contract5NotPresent'가 있습니다.Here, it has the prefix 'contract5NotPresent'.

xmlns:contract5NotPresent="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractNotPresent(Windows.Foundation.UniversalApiContract,5)"

xmlns:contract5Present="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractPresent(Windows.Foundation.UniversalApiContract,5)"

두 네임스페이스가 정의되면, 다음과 같이 런타임에 한 속성만 사용된다는 전제 하에 Text 속성을 두 번 설정할 수 있습니다.With both namespaces defined, you can set the Text property twice as long as you prefix them with qualifiers that ensure only one property setting is used at runtime, like this:

<TextBlock contract5NotPresent:Text="Hello, World"
           contract5Present:Text="Hello, Fall Creators Update"/>

단추의 배경을 설정하는 다른 예는 다음과 같습니다.Here's another example that sets the background of a button. 아크릴 재질 기능은 Fall Creators Update에서 사용할 수 있으므로, 앱이 Fall Creators Update에서 실행되는 경우 배경으로 아크릴을 사용할 수 있습니다.The Acrylic material feature is available starting with the Fall Creators Update, so you’ll use Acrylic for the background when the app runs on the Fall Creators Update. 이전 버전에서는 사용할 수 없으므로 이 경우, 배경을 빨간색으로 설정합니다.It's not available on earlier versions, so in those cases, you set the background to red.

<Button Content="Button"
        contract5NotPresent:Background="Red"
        contract5Present:Background="{ThemeResource SystemControlAcrylicElementBrush}"/>

컨트롤 생성 및 속성 바인딩Create controls and bind properties

지금까지 조건부 XAML를 사용하여 속성을 설정하는 방법을 살펴 보았습니다. 하지만 런타임에 API 계약을 따라 조건부로 컨트롤을 인스턴스할 수도 있습니다.So far, you’ve seen how to set properties using conditional XAML, but you can also conditionally instantiate controls based on the API contract available at runtime.

다음 코드에서는 컨트롤을 사용할 수 있는 Fall Creators Update에서 앱이 실행될 때 ColorPicker가 인스턴스화됩니다.Here, a ColorPicker is instantiated when the app runs on the Fall Creators Update where the control is available. Fall Creators Update 이전 버전에서는 ColorPicker를 사용할 수 없으므로, 앱이 이전 버전에서 실행될 때는 ComboBox를 사용하여 사용자에게 간단한 색상 선택권을 제공할 수 있습니다.The ColorPicker isn't available prior to the Fall Creators Update, so when the app runs on earlier versions, you use a ComboBox to provide simplified color choices to the user.

<contract5Present:ColorPicker x:Name="colorPicker"
                              Grid.Column="1"
                              VerticalAlignment="Center"/>

<contract5NotPresent:ComboBox x:Name="colorComboBox"
                              PlaceholderText="Pick a color"
                              Grid.Column="1"
                              VerticalAlignment="Center">

다른 형식의 XAML 속성 구문을 통해 조건부 한정자를 사용할 수 있습니다.You can use conditional qualifiers with different forms of XAML property syntax. 다음 코드에서는 사각형의 Fill 속성이 Fall Creators Update에 대해서는 속성 요소 구문을 사용하여 설정되며, 이전 버전에 대해서는 특성 구문을 사용하여 설정됩니다.Here, the rectangle’s Fill property is set using property element syntax for the Fall Creators Update, and using attribute syntax for previous versions.

<Rectangle x:Name="colorRectangle" Width="200" Height="200"
           contract5NotPresent:Fill="{x:Bind ((SolidColorBrush)((FrameworkElement)colorComboBox.SelectedItem).Tag), Mode=OneWay}">
    <contract5Present:Rectangle.Fill>
        <SolidColorBrush contract5Present:Color="{x:Bind colorPicker.Color, Mode=OneWay}"/>
    </contract5Present:Rectangle.Fill>
</Rectangle>

조건부 네임스페이스에 의존하는 다른 속성에 속성을 바인딩할 경우, 두 속성에 같은 조건을 사용해야 합니다.When you bind a property to another property that depends on a conditional namespace, you must use the same condition on both properties. 여기에서 colorPicker.Color는 'contract5Present' 조건부 네임스페이스에 의존하므로, 'contract5Present' 접두사를 SolidColorBrush.Color 속성에도 붙여야 합니다.Here, colorPicker.Color depends on the 'contract5Present' conditional namespace, so you must also place the 'contract5Present' prefix on the SolidColorBrush.Color property. (또는 Color 속성 대신 SolidColorBrush에 'contract5Present' 접두사를 붙어야 합니다.) 그렇지 않으면 컴파일 시간 오류가 발생합니다.(Or, you can place the 'contract5Present' prefix on the SolidColorBrush instead of on the Color property.) If you don’t, you’ll get a compile-time error.

<SolidColorBrush contract5Present:Color="{x:Bind colorPicker.Color, Mode=OneWay}"/>

다음은 이러한 시나리오를 보여 주는 완전한 XAML입니다.Here's the complete XAML that demonstrates these scenarios. 이 예에는 사각형과 이의 색상을 설정할 수 있는 UI가 포함되어 있습니다.This example contains a rectangle and a UI that lets you set the color of the rectangle.

앱이 Fall Creators Update에서 실행될 경우, ColorPicker를 사용하여 사용자가 색상을 설정하도록 할 수 있습니다.When the app runs on the Fall Creators Update, you use a ColorPicker to let the user set the color. Fall Creators Update 이전 버전에서는 ColorPicker를 사용할 수 없으므로, 앱이 이전 버전에서 실행될 때는 콤보 상자를 사용하여 사용자에게 간단한 색상 선택권을 제공할 수 있습니다.The ColorPicker isn't available prior to the Fall Creators Update, so when the app runs on earlier versions, you use a combo box to provide simplified color choices to the user.

<Page
    x:Class="ConditionalTest.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:contract5Present="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractPresent(Windows.Foundation.UniversalApiContract,5)"
    xmlns:contract5NotPresent="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractNotPresent(Windows.Foundation.UniversalApiContract,5)">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>

        <Rectangle x:Name="colorRectangle" Width="200" Height="200"
                   contract5NotPresent:Fill="{x:Bind ((SolidColorBrush)((FrameworkElement)colorComboBox.SelectedItem).Tag), Mode=OneWay}">
            <contract5Present:Rectangle.Fill>
                <SolidColorBrush contract5Present:Color="{x:Bind colorPicker.Color, Mode=OneWay}"/>
            </contract5Present:Rectangle.Fill>
        </Rectangle>

        <contract5Present:ColorPicker x:Name="colorPicker"
                                      Grid.Column="1"
                                      VerticalAlignment="Center"/>

        <contract5NotPresent:ComboBox x:Name="colorComboBox"
                                      PlaceholderText="Pick a color"
                                      Grid.Column="1"
                                      VerticalAlignment="Center">
            <ComboBoxItem>Red
                <ComboBoxItem.Tag>
                    <SolidColorBrush Color="Red"/>
                </ComboBoxItem.Tag>
            </ComboBoxItem>
            <ComboBoxItem>Blue
                <ComboBoxItem.Tag>
                    <SolidColorBrush Color="Blue"/>
                </ComboBoxItem.Tag>
            </ComboBoxItem>
            <ComboBoxItem>Green
                <ComboBoxItem.Tag>
                    <SolidColorBrush Color="Green"/>
                </ComboBoxItem.Tag>
            </ComboBoxItem>
        </contract5NotPresent:ComboBox>
    </Grid>
</Page>