Windows Phone Silverlight에서 UWP 사례 연구: Bookstore1Windows Phone Silverlight to UWP case study: Bookstore1

이 항목에서는 매우 간단한 Windows Phone Silverlight 앱을 UWP (Windows 10 유니버설 Windows 플랫폼) 앱으로 이식 하는 사례 연구를 제공 합니다.This topic presents a case study of porting a very simple Windows Phone Silverlight app to a Windows 10 Universal Windows Platform (UWP) app. Windows 10에서는 고객이 다양 한 장치에 설치할 수 있는 단일 앱 패키지를 만들 수 있으며,이 사례 연구에서이 작업을 수행할 수 있습니다.With Windows 10, you can create a single app package that your customers can install onto a wide range of devices, and that's what we'll do in this case study. UWP 앱에 대 한 가이드를참조 하세요.See Guide to UWP apps.

앱은 뷰 모델에 바인딩된 ListBox 로 구성 됩니다.The app we'll port consists of a ListBox bound to a view model. 보기 모델에는 제목, 저자 및 책 커버를 보여 주는 책 목록이 있습니다.The view model has a list of books that shows title, author, and book cover. 서적 커버 이미지는 빌드 작업콘텐츠 로 설정 하 고 출력 디렉터리로 복사복사 안 함으로 설정 합니다.The book cover images have Build Action set to Content and Copy to Output Directory set to Do not copy.

이 단원의 이전 항목에서는 플랫폼 간의 차이점에 대해 설명 하 고, 뷰 모델에 대 한 바인딩을 통해 데이터에 액세스 하는 것을 통해 XAML 태그에서 앱의 다양 한 측면에 대 한 이식 프로세스에 대 한 세부 정보 및 지침을 제공 합니다.The previous topics in this section describe the differences between the platforms, and they give details and guidance on the porting process for various aspects of an app from XAML markup, through binding to a view model, down to accessing data. 사례 연구는 실제 예제에서 작업을 수행 하 여 해당 지침을 보완 하는 것을 목표로 합니다.A case study aims to complement that guidance by showing it in action in a real example. 사례 연구에서는 반복 되지 않는 지침을 읽은 것으로 가정 합니다.The case studies assume you've read the guidance, which they do not repeat.

참고    _Visual studio에서 Bookstore1Universal 10을 열 때 "Visual studio 업데이트 필요" 메시지가 표시 되 면 Targetplatformversion에서 대상 플랫폼 버전 관리를 선택 하는 단계를 수행 합니다.Note   When opening Bookstore1Universal_10 in Visual Studio, if you see the message "Visual Studio update required", then follow the steps for selecting a Target Platform Versioning in TargetPlatformVersion.

다운로드Downloads

Bookstore1WPSL8 Windows Phone Silverlight 앱을 다운로드합니다.Download the Bookstore1WPSL8 Windows Phone Silverlight app.

Bookstore1Universal _ 10 Windows 10 앱을 다운로드합니다.Download the Bookstore1Universal_10 Windows 10 app.

Windows Phone Silverlight 앱The Windows Phone Silverlight app

Bookstore1WPSL8 하는 앱은 다음과 같이 표시 됩니다.Here’s what Bookstore1WPSL8—the app that we're going to port—looks like. 앱의 이름 및 페이지 제목 아래에 있는 책의 세로 스크롤 목록 상자 일 뿐입니다.It's just a vertically-scrolling list box of books beneath the heading of the app's name and page title.

bookstore1wpsl8 모양

Windows 10 프로젝트로 포팅Porting to a Windows 10 project

Visual Studio에서 새 프로젝트를 만들고, Bookstore1WPSL8에서 파일에 파일을 복사 하 고, 복사한 파일을 새 프로젝트에 포함 하는 것이 매우 빠른 작업입니다.It's a very quick task to create a new project in Visual Studio, copy files over to it from Bookstore1WPSL8, and include the copied files in the new project. 새 빈 응용 프로그램 (Windows 유니버설) 프로젝트를 만들어 시작 합니다.Start by creating a new Blank Application (Windows Universal) project. 이름을 Bookstore1Universal _ 10으로 합니다.Name it Bookstore1Universal_10. Bookstore1WPSL8에서 Bookstore1Universal 10으로 복사할 파일 _ 입니다.These are the files to copy over from Bookstore1WPSL8 to Bookstore1Universal_10.

  • 책 표지 이미지를 포함 하는 폴더를 복사 합니다. PNG 파일 \ ( \ CoverImages 폴더)입니다.Copy the folder containing the book cover image PNG files (the folder is \Assets\CoverImages). 폴더를 복사한 후 솔루션 탐색기에서 모든 파일 표시 가 설정 되어 있는지 확인 합니다.After copying the folder, in Solution Explorer, make sure Show All Files is toggled on. 복사한 폴더를 마우스 오른쪽 단추로 클릭 하 고 프로젝트에 포함을 클릭 합니다.Right-click the folder that you copied and click Include In Project. 이 명령은 프로젝트의 파일 또는 폴더를 "포함" 하 여 의미 합니다.That command is what we mean by "including" files or folders in a project. 파일이 나 폴더를 복사할 때마다 솔루션 탐색기 에서 새로 고침 을 클릭 한 다음 프로젝트에 파일 또는 폴더를 포함 합니다.Each time you copy a file or folder, click Refresh in Solution Explorer and then include the file or folder in the project. 대상에서 대체 하는 파일에 대해서는이 작업을 수행할 필요가 없습니다.There's no need to do this for files that you're replacing in the destination.
  • 뷰 모델 원본 파일이 포함 된 폴더를 복사 \ 합니다 (ViewModel).Copy the folder containing the view model source file (the folder is \ViewModel).
  • MainPage을 복사 하 고 대상의 파일을 바꿉니다.Copy MainPage.xaml and replace the file in the destination.

Windows 10 프로젝트에서 Visual Studio가 생성 한 App.xaml.cs 및 Visual Studio를 유지할 수 있습니다.We can keep the App.xaml, and App.xaml.cs that Visual Studio generated for us in the Windows 10 project.

방금 복사한 소스 코드 및 태그 파일을 편집 하 고 Bookstore1WPSL8 네임 스페이스에 대 한 참조를 Bookstore1Universal 10으로 변경 _ 합니다.Edit the source code and markup files that you just copied and change any references to the Bookstore1WPSL8 namespace to Bookstore1Universal_10. 이 작업을 수행 하는 빠른 방법은 파일에서 바꾸기 기능을 사용 하는 것입니다.A quick way to do that is to use the Replace In Files feature. 뷰 모델 소스 파일의 명령적 코드에서 다음과 같은 포팅 변경이 필요 합니다.In the imperative code in the view model source file, these porting changes are needed:

  • System.ComponentModel.DesignerProperties을로 변경 하 DesignMode 고이에 대해 Resolve 명령을 사용 합니다.Change System.ComponentModel.DesignerProperties to DesignMode and then use the Resolve command on it. 속성을 삭제 하 IsInDesignTool 고 IntelliSense를 사용 하 여 올바른 속성 이름를 추가 DesignModeEnabled 합니다.Delete the IsInDesignTool property and use IntelliSense to add the correct property name: DesignModeEnabled.
  • 에서 Resolve 명령을 사용 ImageSource 합니다.Use the Resolve command on ImageSource.
  • 에서 Resolve 명령을 사용 BitmapImage 합니다.Use the Resolve command on BitmapImage.
  • 및를 사용 하 여 삭제 System.Windows.Media; using System.Windows.Media.Imaging; 합니다.Delete using System.Windows.Media; and using System.Windows.Media.Imaging;.
  • **Bookstore1Universal _ ** 속성에서 반환 하는 값을 "BOOKSTORE1WPSL8"에서 "Bookstore1Universal"로 변경 합니다.Change the value returned by the Bookstore1Universal_10.BookstoreViewModel.AppName property from "BOOKSTORE1WPSL8" to "BOOKSTORE1UNIVERSAL".

MainPage에서 다음과 같은 이식 변경이 필요 합니다.In MainPage.xaml, these porting changes are needed:

  • phone:PhoneApplicationPage를로 변경 Page 합니다 (속성 요소 구문에서 발생 하는 것을 잊지 마세요).Change phone:PhoneApplicationPage to Page (don't forget the occurrences in property element syntax).
  • phoneshell 네임 스페이스 접두사 선언을 삭제 합니다.Delete the phone and shell namespace prefix declarations.
  • 나머지 네임 스페이스 접두사 선언에서 "clr-namespace"를 "using"으로 변경 합니다.Change "clr-namespace" to "using" in the remaining namespace prefix declaration.

태그가 일시적으로 제거 되는 것을 의미 하는 경우에도 결과 제거를 확인 하려는 경우 태그 컴파일 오류를 수정 하도록 선택할 수 있습니다.We can choose to correct markup compilation errors very cheaply if we want to see results soonest, even if that means temporarily removing markup. 그러나 이렇게 하면 계산 된 부채에 대 한 기록을 유지 하겠습니다.But, let's keep a record of the debt we accrue by doing so. 이 경우에는 여기에 있습니다.Here it is in this case.

  1. Mainpage의 root page 요소에서를 삭제 SupportedOrientations="Portrait" 합니다.In the root Page element in MainPage.xaml, delete SupportedOrientations="Portrait".
  2. Mainpage의 root page 요소에서를 삭제 Orientation="Portrait" 합니다.In the root Page element in MainPage.xaml, delete Orientation="Portrait".
  3. Mainpage의 root page 요소에서를 삭제 shell:SystemTray.IsVisible="True" 합니다.In the root Page element in MainPage.xaml, delete shell:SystemTray.IsVisible="True".
  4. BookTemplate데이터 템플릿에서 및 TextBlock 스타일에 대 한 참조를 PhoneTextExtraLargeStyle 삭제 PhoneTextSubtleStyleTextBlock 합니다.In the BookTemplate data template, delete the references to the PhoneTextExtraLargeStyle and PhoneTextSubtleStyleTextBlock styles.
  5. TitlePanelStackPanel에서 및 TextBlock 스타일에 대 한 참조를 삭제 PhoneTextNormalStyle PhoneTextTitle1StyleTextBlock 합니다.In the TitlePanelStackPanel, delete the references to the PhoneTextNormalStyle and PhoneTextTitle1StyleTextBlock styles.

먼저 모바일 장치 제품군에 대 한 UI를 살펴보겠습니다. 그 후에는 다른 폼 팩터를 고려할 수 있습니다.Let's work on the UI for the mobile device family first, and we can consider other form factors after that. 이제 앱을 빌드하고 실행할 수 있습니다.You can build and run the app now. 모바일 에뮬레이터에서 표시 되는 방법은 다음과 같습니다.Here's how it looks on the mobile emulator.

초기 소스 코드가 변경 된 모바일의 uwp 앱

뷰 및 뷰 모델이 제대로 작동 하 고 ListBox 가 작동 합니다.The view and the view model are working together correctly, and the ListBox is functioning. 대부분 스타일을 수정 하 고 이미지를 표시 해야 합니다.We mostly just need to fix the styling and get the images to show up.

부채 항목의 지불 및 몇 가지 초기 스타일 지정Paying off the debt items, and some initial styling

기본적으로 모든 방향이 지원 됩니다.By default, all orientations are supported. Windows Phone Silverlight 앱은 명시적으로 세로 전용으로 제한 되기 때문에, # # 새 프로젝트의 앱 패키지 매니페스트로 이동 하 여 지원 되는 방향에서 세로로 확인 하 여 부채 항목 1과 2를 지불 합니다.The Windows Phone Silverlight app explicitly constrains itself to portrait-only, though, so debt items #1 and #2 are paid off by going into the app package manifest in the new project and checking Portrait under Supported orientations.

이 앱의 경우 # 상태 표시줄 (이전에는 시스템 트레이 라고 함)이 기본적으로 표시 되므로 항목 3은 부채가 아닙니다.For this app, item #3 is not a debt since the status bar (formerly called the system tray) is shown by default. 항목 # 4와 5의 경우 # 사용 중인 Windows Phone Silverlight 스타일에 해당 하는 UWP (4 유니버설 Windows 플랫폼) TextBlock 스타일을 찾아야 합니다.For items #4 and #5, we need to find four Universal Windows Platform (UWP) TextBlock styles that correspond to the Windows Phone Silverlight styles that we were using. 에뮬레이터에서 Windows Phone Silverlight 앱을 실행 하 고 텍스트 섹션의 그림과 나란히 비교할 수 있습니다.You can run the Windows Phone Silverlight app in the emulator and compare it side-by-side with the illustration in the Text section. 이 작업을 수행 하 고 Silverlight 시스템 스타일 Windows Phone의 속성을 살펴보면이 테이블을 만들 수 있습니다.From doing that, and from looking at the properties of the Windows Phone Silverlight system styles, we can make this table.

| Windows Phone Silverlight 스타일 키Windows Phone Silverlight style key | UWP 스타일 키UWP style key | |-------------------------------------|------------------------| | PhoneTextExtraLargeStylePhoneTextExtraLargeStyle | TitleTextBlockStyleTitleTextBlockStyle | | PhoneTextSubtleStylePhoneTextSubtleStyle | SubtitleTextBlockStyleSubtitleTextBlockStyle | | PhoneTextNormalStylePhoneTextNormalStyle | CaptionTextBlockStyleCaptionTextBlockStyle | | PhoneTextTitle1StylePhoneTextTitle1Style | HeaderTextBlockStyleHeaderTextBlockStyle |   이러한 스타일을 설정 하려면 태그 편집기에 입력 하거나 Visual Studio XAML 도구를 사용 하 여 입력 하지 않고 설정할 수 있습니다.To set those styles, you can just type them into the markup editor or you can use the Visual Studio XAML Tools and set them without typing a thing. 이렇게 하려면 TextBlock 을 마우스 오른쪽 단추로 클릭 하 고 스타일 편집 > 리소스 적용을 클릭 합니다.To do that, you right-click a TextBlock and click Edit Style > Apply Resource. 항목 템플릿에서 TextBlocks를 사용 하 여이 작업을 수행 하려면 목록 상자 를 마우스 오른쪽 단추로 클릭 하 고 추가 템플릿 편집 > 생성 된 항목 (ItemTemplate) 을 클릭 합니다.To do that with the TextBlocks in the item template, right click the ListBox and click Edit Additional Templates > Edit Generated Items (ItemTemplate).

ListBox 컨트롤의 기본 스타일은 해당 배경을 시스템 리소스로 설정 하므로 항목 뒤에 80% 불투명 흰색 배경이 있습니다 ListBoxBackgroundThemeBrush .There is an 80% opaque white background behind the items, because the default style of the ListBox control sets its background to the ListBoxBackgroundThemeBrush system resource. Background="Transparent"해당 배경을 지우려면 ListBox 에 설정 합니다.Set Background="Transparent" on the ListBox to clear that background. 항목 템플릿에서 TextBlocks를 왼쪽으로 정렬 하려면 위에서 설명한 것과 같은 방식으로 다시 편집 하 고 두 번째 Textblock에 여백을 설정 "9.6,0" 합니다. TextBlockTo left-align the TextBlocks in the item template, edit it again the same way as described above and set a Margin of "9.6,0" on both TextBlocks.

이 작업을 수행한 후에는 보기 픽셀과 관련 된 변경 내용때문에 아직 변경 하지 않은 고정 크기 차원 (여백, 너비, 높이 등)을 0.8에 곱해 야 합니다.After that is done, because of changes related to view pixels, we need to go through and multiply any fixed size dimension that we haven’t yet changed (margins, width, height, etc) by 0.8. 예를 들어 이미지는 70x70px에서 56x56px로 변경 되어야 합니다.So, for example, the images should change from 70x70px to 56x56px.

하지만 스타일의 결과를 표시 하기 전에 렌더링할 이미지를 살펴보겠습니다.But, let’s get those images to render before we show the results of our styling.

이미지를 뷰 모델에 바인딩Binding an Image to a view model

Bookstore1WPSL8에서는 다음을 수행 했습니다.In Bookstore1WPSL8, we did this:

    // this.BookCoverImagePath contains a path of the form "/Assets/CoverImages/one.png".
    return new BitmapImage(new Uri(this.CoverImagePath, UriKind.Relative));

Bookstore1Universal에서는 ms appx URI 체계를 사용 합니다.In Bookstore1Universal, we use the ms-appx URI scheme. 코드의 나머지 부분을 동일 하 게 유지할 수 있도록, system.uri 생성자의 다른 오버 로드를 사용 하 여 기본 uri에 MS appx uri 체계를 추가 하 고 나머지 경로를 해당 경로에 추가할 수 있습니다.So that we can keep the rest of our code the same, we can use a different overload of the System.Uri constructor to put the ms-appx URI scheme in a base URI and append the rest of the path onto that. 다음과 같습니다.Like this:

    // this.BookCoverImagePath contains a path of the form "/Assets/CoverImages/one.png".
    return new BitmapImage(new Uri(new Uri("ms-appx://"), this.CoverImagePath));

유니버설 스타일 지정Universal styling

이제 몇 가지 최종 스타일 지정을 수행 하 고 모바일 뿐만 아니라 데스크톱 (및 기타) 폼 팩터에서 앱이 잘 표시 되는지 확인 해야 합니다.Now, we just need to make some final styling tweaks and confirm that the app looks good on desktop (and other) form factors as well as mobile. 단계는 다음과 같습니다.The steps are below. 이 항목의 맨 위에 있는 링크를 사용 하 여 프로젝트를 다운로드 하 고 여기와 사례 연구의 끝 사이에 있는 모든 변경 내용에 대 한 결과를 볼 수 있습니다.And you can use the links at the top of this topic to download the projects and see the results of all the changes between here and the end of the case study.

  • 항목 사이의 간격을 강화 하려면 BookTemplate mainpage에서 데이터 템플릿을 찾고 Margin 루트 표에서특성을 삭제 합니다.To tighten up the spacing between items, find the BookTemplate data template in MainPage.xaml and delete the Margin attribute from the root Grid.
  • 페이지 제목에 좀 더 보냅니다 공간을 제공 하려면 -5.6 0 페이지 제목 TextBlock에서의 아래쪽 여백을로 다시 설정할 수 있습니다.If you want to give the page title a little more breathing room, you can reset the bottom margin of -5.6 to 0 on the page title TextBlock.
  • 이제 LayoutRoot 테마의 내용에 관계 없이 모든 장치에서 실행 될 때 앱이 적절 하 게 보이도록 올바른 기본값으로를 설정 해야 합니다.Now, we need to set LayoutRoot's Background to the correct default value so that the app looks appropriate when running on all devices no matter what the theme is. 에서로 변경 "Transparent" "{ThemeResource ApplicationPageBackgroundThemeBrush}" 합니다.Change it from "Transparent" to "{ThemeResource ApplicationPageBackgroundThemeBrush}".

더 복잡 한 앱을 사용 하면 폼 팩터 및 사용자 경험을 위해 포팅 하는 지침을 사용 하 고 이제 앱이 실행 될 수 있는 여러 장치의 폼 팩터를 최적으로 사용 하 게 됩니다.With a more sophisticated app, this would be the point at which we'd use the guidance in Porting for form factor and user experience and really make optimal use of the form factor of each of the many devices the app can now run on. 그러나이 간단한 응용 프로그램의 경우 여기에서 중지 하 고 스타일 지정 작업의 마지막 시퀀스 이후에 앱이 어떻게 표시 되는지 확인할 수 있습니다.But, for this simple app, we can stop here and see how the app looks after that last sequence of styling operations. 이는 와이드 폼 팩터를 최대한 활용 하는 것이 아니라 모바일 및 데스크톱 장치에서 동일 하 게 보입니다. 하지만 이후 사례 연구에서이 작업을 수행 하는 방법을 조사 합니다.It actually looks the same on mobile and desktop devices, although it's not making best use of space on wide form factors (but we'll investigate how to do that in a later case study).

앱의 테마를 제어 하는 방법을 보려면 테마 변경 을 참조 하세요.See Theme changes to see how to control the theme of your app.

포팅 된 windows 10 앱

모바일 장치에서 실행 되는 이식 된 Windows 10 앱The ported Windows 10 app running on a Mobile device

모바일 장치의 목록 상자에 대 한 선택적 조정An optional adjustment to the list box for Mobile devices

앱이 모바일 장치에서 실행 되는 경우 목록 상자의 배경은 기본적으로 두 테마에 모두 표시 됩니다.When the app is running on a Mobile device, the background of a list box is light by default in both themes. 원하는 스타일 일 수 있으며,이 경우 더 이상 수행할 작업이 없습니다.That may be the style that you prefer and, if so, then there's nothing more to do. 그러나 컨트롤은 동작의 영향을 받지 않고 모양을 사용자 지정할 수 있도록 디자인 되었습니다.But, controls are designed so that you can customize their look while leaving their behavior unaffected. 따라서 원본 앱이 표시 되는 방식으로 목록 상자를 어두운 테마에 어둡게 표시 하려면 "선택적 조정"에서 다음 지침 을 따르세요.So, if you want the list box to be dark in the dark theme—the way the original app looked—then follow these instructions under "An optional adjustment".

결론Conclusion

이 사례 연구는 매우 간단한 앱을 이식 하는 프로세스를 보여 주었습니다. 통해 비현실적으로 단순 합니다.This case study showed the process of porting a very simple app—arguably an unrealistically simple one. 예를 들어 목록 컨트롤을 선택 하거나 탐색을 위한 컨텍스트를 설정 하는 데 사용할 수 있습니다. 앱은 탭 된 항목에 대 한 자세한 정보를 포함 하는 페이지로 이동 합니다.For instance, list controls can be used for selection or for establishing a context for navigation; the app navigates to a page with more details about the item that was tapped. 이 특정 앱은 사용자가 선택 하는 것이 없으며 탐색이 없습니다.This particular app does nothing with the user's selection, and it has no navigation. 그러나 사례 연구는 ice를 중단 하 고 포팅 프로세스를 소개 하며 실제 UWP 앱에서 사용할 수 있는 중요 한 기술을 보여 주기 위해 제공 됩니다.Even so, the case study served to break the ice, to introduce the porting process, and to demonstrate important techniques that you can use in real UWP apps.

다음 사례 연구는 그룹화 된 데이터에 액세스 하 고 표시 하는 것을 Bookstore2.The next case study is Bookstore2, in which we look at accessing and displaying grouped data.