XAML 컨트롤, C++/WinRT 속성에 바인딩XAML controls; bind to a C++/WinRT property

XAML 컨트롤에 효과적으로 바인딩할 수 있는 속성은 식별할 수 있는(observable) 속성이라고 합니다.A property that can be effectively bound to a XAML control is known as an observable property. 이 아이디어는 ‘관찰자 패턴’이라고 알려진 소프트웨어 디자인 패턴에 바탕을 두고 있습니다. This idea is based on the software design pattern known as the observer pattern. 이 항목에서는 C++/WinRT에서 관찰 가능한 속성을 구현하는 방법과 XAML 컨트롤을 이 속성에 바인딩하는 방법을 보여줍니다(배경 정보는 데이터 바인딩 참조).This topic shows how to implement observable properties in C++/WinRT, and how to bind XAML controls to them (for background info, see Data binding).

중요

C++/WinRT를 사용해 런타임 클래스를 사용하거나 작성하는 방법을 더욱 쉽게 이해할 수 있는 필수 개념과 용어에 대해서는 C++/WinRT를 통한 API 사용C++/WinRT를 통한 API 작성을 참조하세요.For essential concepts and terms that support your understanding of how to consume and author runtime classes with C++/WinRT, see Consume APIs with C++/WinRT and Author APIs with C++/WinRT.

속성을 얘기할 때 관찰 가능하다는 것은 무슨 뜻인가요?What does observable mean for a property?

BookSku라고 하는 런타임 클래스에 이름이 Title인 속성이 있다고 가정하겠습니다.Let's say that a runtime class named BookSku has a property named Title. BookSku에서 Title 값이 바뀔 때마다 INotifyPropertyChanged::PropertyChanged 이벤트가 발생하도록 선택한다면 Title은 관찰 가능한 속성이 됩니다.If BookSku chooses to raise the INotifyPropertyChanged::PropertyChanged event whenever the value of Title changes, then Title is an observable property. 이벤트가 발생하거나 발생하지 않는 BookSku의 동작에 따라서 관찰 가능한 속성인지 알 수 있습니다.It's the behavior of BookSku (raising or not raising the event) that determines which, if any, of its properties are observable.

XAML 텍스트 요소, 즉 컨트롤은 업데이트된 값을 가져와 새로운 값을 표시하도록 스스로 업데이트함으로써 이러한 이벤트에 바인딩하여 처리할 수 있습니다.A XAML text element, or control, can bind to, and handle, these events by retrieving the updated value(s) and then updating itself to show the new value.

참고

프로젝트 템플릿 및 빌드 지원을 함께 제공하는 C++/WinRT Visual Studio 확장(VSIX) 및 NuGet 패키지를 설치하고 사용하는 방법에 대한 자세한 내용은 Visual Studio의 C++/WinRT 지원을 참조하세요.For info about installing and using the C++/WinRT Visual Studio Extension (VSIX) and the NuGet package (which together provide project template and build support), see Visual Studio support for C++/WinRT.

비어 있는 앱(Bookstore) 만들기Create a Blank App (Bookstore)

먼저 Microsoft Visual Studio에서 새 프로젝트를 만듭니다.Begin by creating a new project in Microsoft Visual Studio. 비어 있는 앱(C++/WinRT) 프로젝트를 만들고 이름을 Bookstore라고 지정합니다.Create a Blank App (C++/WinRT) project, and name it Bookstore.

지금부터 관찰 가능한 제목 속성을 갖는 동시에 책을 표현할 새로운 클래스를 작성하려고 합니다.We're going to author a new class to represent a book that has an observable title property. 동일한 컴파일 단위 내에서 클래스를 작성하고 사용합니다.We're authoring and consuming the class within the same compilation unit. 하지만 XAML에서 이 클래스에 바인딩할 수 있어야 하므로 결국 런타임 클래스가 될 것입니다.But we want to be able to bind to this class from XAML, and for that reason it's going to be a runtime class. 그 밖에도 런타임 클래스를 작성하고 사용하는 데 모두 C++/WinRT를 사용합니다.And we're going to use C++/WinRT to both author and consume it.

새로운 런타임 클래스를 작성하려면 먼저 새 Midl 파일(.idl) 항목을 프로젝트에 추가합니다.The first step in authoring a new runtime class is to add a new Midl File (.idl) item to the project. 이름을 BookSku.idl이라고 지정합니다.Name it BookSku.idl. BookSku.idl의 기본 콘텐츠를 삭제한 후 아래 런타임 클래스 선언에 붙여넣습니다.Delete the default contents of BookSku.idl, and paste in this runtime class declaration.

// BookSku.idl
namespace Bookstore
{
    runtimeclass BookSku : Windows.UI.Xaml.Data.INotifyPropertyChanged
    {
        String Title;
    }
}

참고

보기 모델 클래스(실제로는 애플리케이션에서 선언하는 런타임 클래스)는 기본 클래스에서 파생될 필요가 없습니다.Your view model classes—in fact, any runtime class that you declare in your application—need not derive from a base class. 위에 선언된 BookSku 클래스가 해당하는 예입니다.The BookSku class declared above is an example of that. 이 클래스는 인터페이스를 구현하지만 기본 클래스에서 파생되지 않습니다.It implements an interface, but it doesn't derive from any base class.

기본 클래스에서 ‘파생된’ 애플리케이션에서 선언하는 런타임 클래스를 ‘구성 가능’ 클래스라고 합니다. Any runtime class that you declare in the application that does derive from a base class is known as a composable class. 또한 구성 가능 클래스에 관련된 제약 조건이 있습니다.And there are constraints around composable classes. 애플리케이션이 Visual Studio 및 Microsoft Store에서 제출의 유효성 검사에 사용되는 Windows 앱 인증 키트 테스트를 통과하여 Microsoft Store로 성공적으로 수집되려면 구성 가능 클래스는 기본적으로 Windows 기본 클래스에서 파생되어야 합니다.For an application to pass the Windows App Certification Kit tests used by Visual Studio and by the Microsoft Store to validate submissions (and therefore for the application to be successfully ingested into the Microsoft Store), a composable class must ultimately derive from a Windows base class. 즉, 상속 계층 구조의 루트에 있는 클래스는 Windows.* 네임스페이스에서 시작되는 형식이어야 합니다.Meaning that the class at the very root of the inheritance hierarchy must be a type originating in a Windows.* namespace. 기본 클래스에서 런타임 클래스를 파생시켜야 하는 경우(예를 들어 파생시킬 모든 보기 모델에 대한 BindableBase 클래스를 구현하려면) Windows.UI.Xaml.DependencyObject에서 파생시킬 수 있습니다.If you do need to derive a runtime class from a base class—for example, to implement a BindableBase class for all of your view models to derive from—then you can derive from Windows.UI.Xaml.DependencyObject.

보기 모델은 보기의 추상화이므로 보기(XAML 태그)에 직접 바인딩됩니다.A view model is an abstraction of a view, and so it's bound directly to the view (the XAML markup). 데이터 모델은 데이터의 추상화이며 보기 모델에서만 사용되고 XAML에 직접 바인딩되지 않습니다.A data model is an abstraction of data, and it's consumed only from your view models, and not bound directly to XAML. 따라서 데이터 모델을 런타임 클래스가 아니라 C++ 구조체 또는 클래스로 선언할 수 있습니다.So, you can declare your data models not as runtime classes, but as C++ structs or classes. MIDL로 선언할 필요가 없으며 원하는 모든 상속 계층 구조를 자유롭게 사용할 수 있습니다.They don't need to be declared in MIDL, and you're free to use whatever inheritance hierarchy you like.

파일을 저장하고 프로젝트를 빌드합니다.Save the file and build the project. 빌드 프로세스에서 midl.exe 도구가 실행되어 런타임 클래스를 설명하는 Windows 런타임 메타데이터 파일(\Bookstore\Debug\Bookstore\Unmerged\BookSku.winmd)을 생성합니다.During the build process, the midl.exe tool is run to create a Windows Runtime metadata file (\Bookstore\Debug\Bookstore\Unmerged\BookSku.winmd) describing the runtime class. 그런 다음, cppwinrt.exe 도구가 실행되어 런타임 클래스를 작성하거나 사용하도록 지원하는 원본 코드 파일을 생성합니다.Then, the cppwinrt.exe tool is run to generate source code files to support you in authoring and consuming your runtime class. 원본 코드 파일에는 IDL로 선언한 BookSku 런타임 클래스의 구현을 시작할 수 있는 스텁이 포함됩니다.These files include stubs to get you started implementing the BookSku runtime class that you declared in your IDL. 이 스텁이 \Bookstore\Bookstore\Generated Files\sources\BookSku.hBookSku.cpp입니다.Those stubs are \Bookstore\Bookstore\Generated Files\sources\BookSku.h and BookSku.cpp.

프로젝트 노드를 마우스 오른쪽 단추로 클릭하고 파일 탐색기에서 폴더 열기를 클릭합니다.Right-click the project node and click Open Folder in File Explorer. 파일 탐색기에서 프로젝트 폴더가 열립니다.This opens the project folder in File Explorer. 여기서 스텁 파일인 BookSku.hBookSku.cpp\Bookstore\Bookstore\Generated Files\sources\ 폴더에서 프로젝트 폴더인 \Bookstore\Bookstore\로 복사합니다.There, copy the stub files BookSku.h and BookSku.cpp from the \Bookstore\Bookstore\Generated Files\sources\ folder and into the project folder, which is \Bookstore\Bookstore\. 솔루션 탐색기에서 프로젝트 노드를 선택하고 모든 파일 표시가 켜져 있는지 확인합니다.In Solution Explorer, with the project node selected, make sure Show All Files is toggled on. 복사한 스텁 파일을 마우스 오른쪽 단추로 클릭하고 프로젝트에 포함을 클릭합니다.Right-click the stub files that you copied, and click Include In Project.

BookSku 구현Implement BookSku

이제 \Bookstore\Bookstore\BookSku.hBookSku.cpp를 열고 런타임 클래스를 구현합니다.Now, let's open \Bookstore\Bookstore\BookSku.h and BookSku.cpp and implement our runtime class. BookSku.h에서 winrt::hstring을 가져올 생성자, 제목 문자열을 저장할 프라이빗 멤버 및 제목 변경 시 발생되는 이벤트에 사용할 프라이빗 멤버를 추가합니다.In BookSku.h, add a constructor that takes a winrt::hstring, a private member to store the title string, and another for the event that we'll raise when the title changes. 이 변경을 수행한 후 BookSku.h가 다음과 같이 표시됩니다.After making these changes, your BookSku.h will look like this.

// BookSku.h
#pragma once
#include "BookSku.g.h"

namespace winrt::Bookstore::implementation
{
    struct BookSku : BookSkuT<BookSku>
    {
        BookSku() = delete;
        BookSku(winrt::hstring const& title);

        winrt::hstring Title();
        void Title(winrt::hstring const& value);
        winrt::event_token PropertyChanged(Windows::UI::Xaml::Data::PropertyChangedEventHandler const& value);
        void PropertyChanged(winrt::event_token const& token);
    
    private:
        winrt::hstring m_title;
        winrt::event<Windows::UI::Xaml::Data::PropertyChangedEventHandler> m_propertyChanged;
    };
}

BookSku.cpp에서 아래와 같이 함수를 구현합니다.In BookSku.cpp, implement the functions like this.

// BookSku.cpp
#include "pch.h"
#include "BookSku.h"
#include "BookSku.g.cpp"

namespace winrt::Bookstore::implementation
{
    BookSku::BookSku(winrt::hstring const& title) : m_title{ title }
    {
    }

    winrt::hstring BookSku::Title()
    {
        return m_title;
    }

    void BookSku::Title(winrt::hstring const& value)
    {
        if (m_title != value)
        {
            m_title = value;
            m_propertyChanged(*this, Windows::UI::Xaml::Data::PropertyChangedEventArgs{ L"Title" });
        }
    }

    winrt::event_token BookSku::PropertyChanged(Windows::UI::Xaml::Data::PropertyChangedEventHandler const& handler)
    {
        return m_propertyChanged.add(handler);
    }

    void BookSku::PropertyChanged(winrt::event_token const& token)
    {
        m_propertyChanged.remove(token);
    }
}

Title 변경자(mutator) 함수에서 값이 현재 값과 다르게 설정되어 있는지 확인합니다.In the Title mutator function, we check whether a value is being set that's different from the current value. 다르게 설정되어 있으면 제목을 업데이트하고 변경된 속성의 이름과 같은 인수를 사용하여 INotifyPropertyChanged::PropertyChanged 이벤트를 발생시킵니다.And, if so, we update the title and also raise the INotifyPropertyChanged::PropertyChanged event with an argument equal to the name of the property that has changed. 이렇게 하면 UI(사용자 인터페이스)가 다시 쿼리할 속성 값을 인식할 수 있습니다.This is so that the user-interface (UI) will know which property's value to re-query.

BookstoreViewModel 선언 및 구현Declare and implement BookstoreViewModel

이제 기본 XAML 페이지가 주요 보기 모델에 바인딩됩니다.Our main XAML page is going to bind to a main view model. 이 보기 모델은 BookSku 형식 중 하나를 포함해 여러 속성을 갖게 됩니다.And that view model is going to have several properties, including one of type BookSku. 이번 단계에서는 주요 보기 모델 런타임 클래스를 선언하고 구현합니다.In this step, we'll declare and implement our main view model runtime class.

BookstoreViewModel.idl이라는 이름의 새 Midl 파일(.idl) 항목을 추가합니다.Add a new Midl File (.idl) item named BookstoreViewModel.idl. 또한 런타임 클래스를 Midl 파일(.idl)로 팩터링도 참조하세요.But also see Factoring runtime classes into Midl files (.idl).

// BookstoreViewModel.idl
import "BookSku.idl";

namespace Bookstore
{
    runtimeclass BookstoreViewModel
    {
        BookSku BookSku{ get; };
    }
}

저장 후 빌드합니다.Save and build. BookstoreViewModel.hBookstoreViewModel.cppGenerated Files\sources 폴더에서 프로젝트 폴더로 복사한 후 프로젝트에 추가합니다.Copy BookstoreViewModel.h and BookstoreViewModel.cpp from the Generated Files\sources folder into the project folder, and include them in the project. 해당 파일을 열고 아래 표시된 대로 런타임 클래스를 구현합니다.Open those files and implement the runtime class as shown below. BookSku의 구현 형식(winrt::Bookstore::implementation::BookSku)을 선언하는 BookstoreViewModel.hBookSku.h를 포함하는 방법을 확인합니다.Note how, in BookstoreViewModel.h, we're including BookSku.h, which declares the implementation type for BookSku (which is winrt::Bookstore::implementation::BookSku). 또한 기본 생성자에서 = default를 제거합니다.And we're removing = default from the default constructor.

// BookstoreViewModel.h
#pragma once
#include "BookstoreViewModel.g.h"
#include "BookSku.h"

namespace winrt::Bookstore::implementation
{
    struct BookstoreViewModel : BookstoreViewModelT<BookstoreViewModel>
    {
        BookstoreViewModel();

        Bookstore::BookSku BookSku();

    private:
        Bookstore::BookSku m_bookSku{ nullptr };
    };
}
// BookstoreViewModel.cpp
#include "pch.h"
#include "BookstoreViewModel.h"
#include "BookstoreViewModel.g.cpp"

namespace winrt::Bookstore::implementation
{
    BookstoreViewModel::BookstoreViewModel()
    {
        m_bookSku = winrt::make<Bookstore::implementation::BookSku>(L"Atticus");
    }

    Bookstore::BookSku BookstoreViewModel::BookSku()
    {
        return m_bookSku;
    }
}

참고

m_bookSku 형식은 프로젝션된 형식(winrt::Bookstore::BookSku)이며, winrt::make와 함께 사용하는 템플릿 매개 변수는 구현 형식(winrt::Bookstore::implementation::BookSku)입니다.The type of m_bookSku is the projected type (winrt::Bookstore::BookSku), and the template parameter that you use with winrt::make is the implementation type (winrt::Bookstore::implementation::BookSku). 그렇다 하더라도 make는 프로젝션된 형식 인스턴스를 반환합니다.Even so, make returns an instance of the projected type.

BookstoreViewModel 형식의 속성을 MainPage에 추가Add a property of type BookstoreViewModel to MainPage

MainPage.idl을 열고 기본 UI 페이지를 나타내는 런타임 클래스를 선언합니다.Open MainPage.idl, which declares the runtime class that represents our main UI page. 가져오기 문을 추가하여 BookstoreViewModel.idl을 가져온 후 BookstoreViewModel 형식의 읽기 전용 속성(MainViewModel)을 추가합니다.Add an import statement to import BookstoreViewModel.idl, and add a read-only property named MainViewModel of type BookstoreViewModel. 또한 MyProperty 속성도 제거합니다.Also remove the MyProperty property. 아래 목록에 있는 import 지시문도 확인합니다.Also note the import directive in the listing below.

// MainPage.idl
import "BookstoreViewModel.idl";

namespace Bookstore
{
    runtimeclass MainPage : Windows.UI.Xaml.Controls.Page
    {
        MainPage();
        BookstoreViewModel MainViewModel{ get; };
    }
}

파일을 저장합니다.Save the file. 현재는 프로젝트 빌드가 완료되지 않지만, 지금 빌드하는 것은 MainPage 런타임 클래스가 구현되는 원본 코드 파일(\Bookstore\Bookstore\Generated Files\sources\MainPage.hMainPage.cpp)을 생성하므로 유용한 작업입니다.The project won't build to completion at the moment, but building now is a useful thing to do because it regenerates the source code files in which the MainPage runtime class is implemented (\Bookstore\Bookstore\Generated Files\sources\MainPage.h and MainPage.cpp). 따라서 지금 바로 빌드합니다.So go ahead and build now. 이 스테이지에서 예상할 수 있는 빌드 오류는 ‘MainViewModel’: ‘winrt::Bookstore::implementation::MainPage’의 멤버가 아님입니다.The build error you can expect to see at this stage is 'MainViewModel': is not a member of 'winrt::Bookstore::implementation::MainPage'.

BookstoreViewModel.idl의 include를 생략하면(위의 MainPage.idl 목록 참조) 오류 “MainViewModel” 근처에 < 필요가 표시됩니다.If you omit the include of BookstoreViewModel.idl (see the listing of MainPage.idl above), then you'll see the error expecting < near "MainViewModel". 다른 팁은 모든 형식을 코드 목록에 표시된 동일한 네임스페이스에 남겨 두어야 한다는 것입니다.Another tip is to make sure that you leave all types in the same namespace: the namespace that's shown in the code listings.

표시될 것으로 예상하는 오류를 해결하려면 MainViewModel 속성의 접근자 스텁을 생성된 파일(\Bookstore\Bookstore\Generated Files\sources\MainPage.hMainPage.cpp)에서 복사하여 \Bookstore\Bookstore\MainPage.hMainPage.cpp에 붙여넣습니다.To resolve the error that we expect to see, you'll now need to copy the accessor stubs for the MainViewModel property out of the generated files (\Bookstore\Bookstore\Generated Files\sources\MainPage.h and MainPage.cpp) and into \Bookstore\Bookstore\MainPage.h and MainPage.cpp. 이 작업을 수행하는 단계는 다음과 같이 설명됩니다.The steps to do that are described next.

\Bookstore\Bookstore\MainPage.hBookstoreViewModel의 구현 형식(winrt::Bookstore::implementation::BookstoreViewModel)을 선언하는 BookstoreViewModel.h를 포함합니다.In \Bookstore\Bookstore\MainPage.h, include BookstoreViewModel.h, which declares the implementation type for BookstoreViewModel (which is winrt::Bookstore::implementation::BookstoreViewModel). 보기 모델을 저장할 프라이빗 멤버를 추가합니다.Add a private member to store the view model. 단, 속성 접근자 함수(및 m_mainViewModel 멤버)는 BookstoreViewModel의 프로젝션된 형식(Bookstore::BookstoreViewModel)을 기반으로 구현됩니다.Note that the property accessor function (and the member m_mainViewModel) is implemented in terms of the projected type for BookstoreViewModel (which is Bookstore::BookstoreViewModel). 구현 형식이 애플리케이션과 동일한 프로젝트(컴파일 단위)에 있으므로 std::nullptr_t를 가져오는 생성자 오버로드를 통해 m_mainViewModel을 생성합니다.The implementation type is in the same project (compilation unit) as the application, so we construct m_mainViewModel via the constructor overload that takes std::nullptr_t. 또한 MyProperty 속성도 제거합니다.Also remove the MyProperty property.

// MainPage.h
...
#include "BookstoreViewModel.h"
...
namespace winrt::Bookstore::implementation
{
    struct MainPage : MainPageT<MainPage>
    {
        MainPage();

        Bookstore::BookstoreViewModel MainViewModel();

        void ClickHandler(Windows::Foundation::IInspectable const&, Windows::UI::Xaml::RoutedEventArgs const&);

    private:
        Bookstore::BookstoreViewModel m_mainViewModel{ nullptr };
    };
}
...

\Bookstore\Bookstore\MainPage.cpp에서 winrt::make(구현 형식 포함)를 호출하여 프로젝션된 형식의 새 인스턴스를 m_mainViewModel에 할당합니다.In \Bookstore\Bookstore\MainPage.cpp, call winrt::make (with the implementation type) to assign a new instance of the projected type to m_mainViewModel. 책 제목의 초기 값을 할당합니다.Assign an initial value for the book's title. MainViewModel 속성 접근자를 구현합니다.Implement the accessor for the MainViewModel property. 마지막으로 단추의 이벤트 처리기에서 책 제목을 업데이트합니다.And finally, update the book's title in the button's event handler. 또한 MyProperty 속성도 제거합니다.Also remove the MyProperty property.

// MainPage.cpp
#include "pch.h"
#include "MainPage.h"
#include "MainPage.g.cpp"

using namespace winrt;
using namespace Windows::UI::Xaml;

namespace winrt::Bookstore::implementation
{
    MainPage::MainPage()
    {
        m_mainViewModel = winrt::make<Bookstore::implementation::BookstoreViewModel>();
        InitializeComponent();
    }

    void MainPage::ClickHandler(Windows::Foundation::IInspectable const& /* sender */, Windows::UI::Xaml::RoutedEventArgs const& /* args */)
    {
        MainViewModel().BookSku().Title(L"To Kill a Mockingbird");
    }

    Bookstore::BookstoreViewModel MainPage::MainViewModel()
    {
        return m_mainViewModel;
    }
}

단추를 Title 속성에 바인딩Bind the button to the Title property

MainPage.xaml을 엽니다. 여기에는 기본 UI 페이지에 사용할 XAML 태그가 포함되어 있습니다.Open MainPage.xaml, which contains the XAML markup for our main UI page. 아래 목록과 같이, 단추에서 이름을 제거하고 해당 Content 속성 값을 리터럴에서 바인딩 식으로 변경합니다.As shown in the listing below, remove the name from the button, and change its Content property value from a literal to a binding expression. 바인딩 식에서 Mode=OneWay 속성을 확인합니다(보기 모델에서 UI로 단방향).Note the Mode=OneWay property on the binding expression (one-way from the view model to the UI). 이 속성이 없으면 UI가 속성 변경 이벤트에 응답하지 않습니다.Without that property, the UI will not respond to property changed events.

<Button Click="ClickHandler" Content="{x:Bind MainViewModel.BookSku.Title, Mode=OneWay}"/>

이제 프로젝트를 빌드하고 실행합니다.Now build and run the project. 단추를 클릭하여 Click 이벤트 처리기를 실행합니다.Click the button to execute the Click event handler. 처리기가 책의 제목 변경자 함수를 호출합니다. 그러면 변경자가 이벤트를 발생시켜 UI가 Title 속성이 변경되었다는 것을 알 수 있습니다. 마지막으로 단추가 해당 속성 값에 대한 쿼리를 다시 실행하여 Content 값을 업데이트합니다.That handler calls the book's title mutator function; that mutator raises an event to let the UI know that the Title property has changed; and the button re-queries that property's value to update its own Content value.

C++/WinRT와 함께 {Binding} 태그 확장 사용Using the {Binding} markup extension with C++/WinRT

현재 릴리스된 C++/WinRT 버전의 경우 {Binding} 태그 확장을 사용하려면 ICustomPropertyProviderICustomProperty 인터페이스를 구현해야 합니다.For the currently released version of C++/WinRT, in order to be able to use the {Binding} markup extension you'll need to implement the ICustomPropertyProvider and ICustomProperty interfaces.

요소 간 바인딩Element-to-element binding

한 XAML 요소의 속성을 다른 XAML 요소의 속성에 바인딩할 수 있습니다.You can bind the property of one XAML element to the property of another XAML element. 태그에서는 다음과 같이 표시됩니다.Here's an example of how that looks in markup.

<TextBox x:Name="myTextBox" />
<TextBlock Text="{x:Bind myTextBox.Text, Mode=OneWay}" />

명명된 XAML 엔터티 myTextBox를 Midl 파일(.idl)에서 읽기 전용 속성으로 선언해야 합니다.You'll need to declare the named XAML entity myTextBox as a read-only property in your Midl file (.idl).

// MainPage.idl
runtimeclass MainPage : Windows.UI.Xaml.Controls.Page
{
    MainPage();
    Windows.UI.Xaml.Controls.TextBox myTextBox{ get; };
}

이렇게 해야 하는 이유는 다음과 같습니다.Here's the reason for this necessity. XAML 컴파일러에서 유효성을 검사해야 하는 모든 형식({x:Bind}에서 사용되는 형식 포함)을 Windows 메타 데이터(WinMD)에서 읽어옵니다.All types that the XAML compiler needs to validate (including those used in {x:Bind}) are read from Windows Metadata (WinMD). 사용자는 Midl 파일에 읽기 전용 속성을 추가하기만 하면 됩니다.All you need to do is to add the read-only property to your Midl file. 구현하지 않도록 합니다. 자동 생성된 XAML 코드 숨김에서 자동으로 구현을 제공하기 때문입니다.Don't implement it, because the autogenerated XAML code-behind provides the implementation for you.

XAML 태그에서 개체 사용Consuming objects from XAML markup

XAML {x:Bind} 태그 확장을 통해 사용되는 모든 엔터티는 IDL에 공개적으로 노출되어야 합니다.All entities consumed by using the XAML {x:Bind} markup extension must be exposed publicly in IDL. 또한 XAML 태그에 또 다른 요소에 대한 참조도 포함되어 있는 경우 해당 태그에 대한 getter가 IDL에 있어야 합니다.Furthermore, if XAML markup contains a reference to another element that's also in markup, then the getter for that markup must be present in IDL.

<Page x:Name="MyPage">
    <StackPanel>
        <CheckBox x:Name="UseCustomColorCheckBox" Content="Use custom color"
             Click="UseCustomColorCheckBox_Click" />
        <Button x:Name="ChangeColorButton" Content="Change color"
            Click="{x:Bind ChangeColorButton_OnClick}"
            IsEnabled="{x:Bind UseCustomColorCheckBox.IsChecked.Value, Mode=OneWay}"/>
    </StackPanel>
</Page>

ChangeColorButton 요소는 바인딩을 통해 UseCustomColorCheckBox 요소를 참조합니다.The ChangeColorButton element refers to the UseCustomColorCheckBox element via binding. 따라서 바인딩에 액세스할 수 있도록 이 페이지의 IDL에서 UseCustomColorCheckBox라는 읽기 전용 속성을 선언해야 합니다.So the IDL for this page must declare a read-only property named UseCustomColorCheckBox in order for it to be accessible to binding.

UseCustomColorCheckBox에 대한 클릭 이벤트 처리기 대리자는 클래식 XAML 대리자 구문을 사용하므로 IDL의 항목이 필요하지 않으며 단지 구현 클래스에서 public으로만 선언하면 됩니다.The click event handler delegate for UseCustomColorCheckBox uses classic XAML delegate syntax, so that doesn't need an entry in the IDL; it just needs to be public in your implementation class. 반면, ChangeColorButton에는 IDL에도 포함되어야 하는 {x:Bind} 클릭 이벤트 처리기도 있습니다.On the other hand, ChangeColorButton also has an {x:Bind} click event handler, which must also go into the IDL.

runtimeclass MyPage : Windows.UI.Xaml.Controls.Page
{
    MyPage();

    // These members are consumed by binding.
    void ChangeColorButton_OnClick();
    Windows.UI.Xaml.Controls.CheckBox UseCustomColorCheckBox{ get; };
}

UseCustomColorCheckBox 속성에 대한 구현은 제공할 필요가 없습니다.You don't need to provide an implementation for the UseCustomColorCheckBox property. XAML 코드 생성기에서 이를 수행합니다.The XAML code generator does that for you.

부울에 바인딩Binding to Boolean

이 작업은 진단 모드에서 수행할 수 있습니다.You might do this in a diagnostic mode.

이 경우 C++/CX에서는 true 또는 false가 표시되지만, C++/WinRT에서는 Windows.Foundation.IReference`1 이 표시됩니다.This shows true or false in C++/CX, but shows Windows.Foundation.IReference`1 in C++/WinRT.

부울에 바인딩하는 경우 x:Bind를 사용합니다.Use x:Bind when binding to a Boolean.

<TextBlock Text="{x:Bind CanPair}"/>

중요 APIImportant APIs