그리드 템플릿에 일반적인 기능을 추가하는 방법(JavaScript 및 HTML을 사용하는 Windows 스토어 앱)

Windows 8:  이 항목은 Windows 8에만 적용됩니다. Windows 8.1의 계층적 탐색 패턴 사용에 대한 자세한 내용은 계층적 탐색 전체 프로세스(HTML)를 참조하세요.

핵심 기능을 추가적으로 포함하여 응용 프로그램에 가치를 더하도록 Microsoft Visual Studio 그리드 응용 프로그램 템플릿을 확장할 수 있습니다. 이 자습서는 Windows 8에서 Microsoft Visual Studio 2012를 사용할 때 참조하도록 작성되었습니다. 여기에서 완료된 자습서에 대한 앱 패키지를 찾을 수 있습니다.

이 페이지는 기본 그리드 형태 응용 프로그램 템플릿 방문 페이지입니다.

기본 그리드 형태 응용 프로그램 템플릿 방문 페이지의 스크린샷

자습서를 완료한 후에 앱에는 다양한 템플릿을 사용하는 여러 크기의 항목이 생성됩니다.

다양한 템플릿을 사용하는 여러 크기의 항목이 있는 그리드 앱의 스크린샷

또한 항목이 선택될 때 상황에 맞는 명령을 표시하는 앱 바도 표시됩니다.

앱 바 및 항목이 선택된 경우의 상황에 맞는 명령이 표시된 앱의 스크린샷

SemanticZoom 컨트롤이 구현됩니다.

시맨틱 줌 컨트롤을 구현하는 앱의 스크린샷

또한 앱의 모든 페이지에서 자연스럽게 애니메이션 효과를 줍니다.

그리드 형태 응용 프로그램 템플릿

Visual Studio 앱 템플릿을 사용하면 "미리 만든" Microsoft 디자인 스타일로 앱 디자인을 빠르게 시작할 수 있습니다. 모든 개발자의 요구가 동일한 것은 아니므로 템플릿에 모든 기능이 포함되지는 않습니다. 이 자습서에서는 Microsoft 디자인 스타일에 대한 지침을 따르면서 템플릿 기반 앱을 사용자 지정하고 가치를 추가하는 방법을 보여 줍니다. 특히 그리드 형태 응용 프로그램 템플릿에 기반하는 앱 사용자 지정 방법을 설명합니다.

이 자습서의 각 섹션은 그리드 형태 응용 프로그램 템플릿에 특정 기능을 추가하는 방법을 중점적으로 소개합니다. 그리드 형태에 전환 페이지 애니메이션, 글로벌 및 상황에 맞는 명령이 있는 앱 바, SemanticZoom 컨트롤 및 여러 크기의 항목을 추가할 것입니다. 또한 이러한 각 항목을 추가하는 목적을 설명하고 템플릿에 기능을 추가하는 방법을 단계별로 설명합니다. 그리드 형태 응용 프로그램 템플릿을 중점적으로 설명하지만 여기에서 익히게 되는 많은 지침을 분할 응용 프로그램 템플릿에도 적용할 수 있습니다.

시작

이 자습서를 시작하기 전에 다음 단계를 완료하세요.

  1. Visual Studio 2012를 시작하고 파일 > 새 프로젝트를 선택합니다.
  2. 그리드 형태 응용 프로그램 템플릿을 사용하여 새 JavaScript 프로젝트를 만듭니다.

페이지 전환 애니메이션 추가

여러 페이지가 있는 앱은 사용자가 페이지 간을 이동할 때 페이지 전환에 대해 애니메이션 효과를 주어야 합니다. 이 섹션에서는 그리드 형태 응용 프로그램 템플릿에서 페이지에 페이지 전환 애니메이션을 추가합니다.

목적

시작 페이지 애니메이션을 추가하면 페이지가 더 빠르고 유연하게 전환되는 느낌을 줍니다. 사용자가 페이지 간을 전환할 때마다 이러한 애니메이션을 추가해야 합니다.

구현

각 템플릿 페이지에서 애니메이션 효과를 주려는 페이지의 요소를 애니메이션 표시 순서대로 반환하는 함수를 추가합니다. 그런 후 사용자가 특정 페이지로 이동할 때마다 애니메이션을 호출하도록 하는 Navigator.js에 대한 함수를 추가합니다.

페이지 전환 애니메이션에 대한 자세한 내용은 HTML 애니메이션 라이브러리 샘플(영문)을 참조하세요.

  1. GroupedItems.js에서 HTML 요소 배열을 반환하는 ui.Pages.define에 대한 함수를 추가합니다. 이 함수는 그리드 형태 보기를 포함하는 머리글 및 페이지 구역을 제공합니다.
    
    
    getAnimationElements: function () {
        return [[this.element.querySelector("header")], [this.element.querySelector("section")]];
    },
    
    

    참고  앞의 예제에 표시된 것처럼 목록의 마지막 함수를 제외하고 함수 끝에 쉼표를 추가해야 합니다. 마지막 함수인 경우에는 함수 앞에 쉼표를 추가해야 합니다. 동일한 규칙이 다음 단계에도 적용됩니다.

  2. GroupDetail.js에서 애니메이션 효과를 적용할 HTML 요소 배열을 반환하는 ui.Pages.define에 대한 함수를 추가합니다.
    
    getAnimationElements: function () {
        return [[this.element.querySelector("header")], [this.element.querySelector("section")]];
    },
    
    
  3. ItemDetail.js에서 애니메이션 효과를 적용할 HTML 요소 배열을 반환하는 ui.Pages.define에 대한 함수를 추가합니다.
    
    getAnimationElements: function () {
        return [[this.element.querySelector("header")], [this.element.querySelector(".content")]];
    },
    
    
  4. Navigator.js에서 애니메이션 효과를 적용할 페이지의 요소를 검색하는 WinJS.Namespace.define에 대한 함수를 추가합니다. 페이지가 요소 배열을 반환하는 함수를 제공하지 않으면 전체 페이지에 애니메이션 효과를 줍니다.
    
    _getAnimationElements: function () {
        if (this.pageControl && this.pageControl.getAnimationElements) {
            return this.pageControl.getAnimationElements();
        }
        return this.pageElement;
    },
    
    
  5. 애니메이션이 완료된 후에 올바른 UI 포커스를 설정하려면 각 페이지에 단일 함수를 추가해야 합니다. 시작 애니메이션이 완료된 후에 이 함수를 호출합니다.

    GroupedItems.js에서 UI 포커스를 페이지의 컨트롤로 설정하는 ui.Pages.define에 대한 함수를 추가합니다.

    
    setPageFocus: function () {
        this.element.querySelector(".groupeditemslist").winControl.element.focus();
    },
    
    

    참고  앞의 예제에 표시된 것처럼 목록의 마지막 함수를 제외하고 함수 끝에 쉼표를 추가해야 합니다. 마지막 함수인 경우에는 함수 앞에 쉼표를 추가해야 합니다. 동일한 규칙이 다음 단계에도 적용됩니다.

    GroupDetail.js에서 UI 포커스를 페이지의 컨트롤로 설정하는 ui.Pages.define에 대한 함수를 추가합니다.

    
    setPageFocus: function () {
        this.element.querySelector(".itemslist").winControl.element.focus();
    },
    
    

    ItemDetail.js에서 UI 포커스를 페이지의 컨트롤로 설정하는 ui.Pages.define에 대한 함수를 추가합니다.

    
    setPageFocus: function () {
        this.element.querySelector(".content").focus();
    },
    
    

    각 페이지의 ready 함수(ItemDetail.js, GroupDetail.js 및 GroupedItems.js)를 업데이트하여 다음 줄을 제거합니다.

    • GroupedItems.js: listView.element.focus();
    • GroupDetail.js: listView.element.focus();
    • ItemDetail.js: element.querySelector(".content").focus();
  6. 마지막으로 시작 페이지 애니메이션을 추가합니다. Navigator.js에서 navigated 함수(_navigated 아님) 맨 위에 다음 코드를 추가하여 움직이는 애니메이션을 설정합니다.
    
    
    navigated: function () {
        // Add the following two lines of code.
        var that = this;
        WinJS.UI.Animation.enterPage(that._getAnimationElements(), null).done(function () { 
            that.pageControl.setPageFocus.bind(that.pageControl); 
            });
    
        var backButton = this.pageElement.querySelector("header[role=banner] .win-backbutton");
    
        ...
    
    
    

앱 바 추가

여기에서 사용자가 수행하려고 할 수 있는 글로벌 또는 상황에 맞는 명령이 들어 있는 앱 바를 추가합니다.

목적

Microsoft 디자인 스타일의 원칙 중 하나는 "크롬 앞에 콘텐츠가 오는 것입니다". 이 원칙은 적은 내용으로 많은 효과를 얻는 방식을 추구하고 화면에 관련성이 가장 높은 요소만 표시한다는 개념을 바탕으로 합니다. 이 원칙에 따라 Windows 8 앱은 화면에서 닿기 쉬운 위치에 상황에 맞는 관련 명령을 배치할 수 있도록 하는 일반적인 컨트롤인 앱 바를 활용할 수 있습니다. 자주 사용하는 명령은 손이 닿기 쉽도록 오른쪽 및 왼쪽 가장자리 근처에 있습니다. 앱 바는 앱 화면에 컨트롤보다 콘텐츠가 중점적으로 표시되도록 합니다. 앱 바는 시스템 전체에서 사용되므로 사용자는 앱 바 조작에 익숙해질 수 있습니다. 이로 인해 앱의 사용 편리성이 높아지고 전체 시스템이 보다 유기적으로 연결된 느낌을 줄 수 있습니다.

실전

Windows 스토어 앱 웹 사이트 사례 연구에서는 앱 개발자가 앱 바를 사용하여 명령 지원 방식을 다시 지정하는 방법을 보여 줍니다. 다음 과정을 통해 사진 업로드 방법을 연습해 볼 수 있습니다. 왼쪽에는 웹에서 이 작업을 수행하는 방법을 단계별로 연습하는 과정이 표시됩니다. 오른쪽에는 Microsoft 디자인 스타일을 활용하는 시나리오가 나와 있습니다.

사진 업로드 단계의 스크린샷

앞의 연습에서 웹 사이트는 페이지에 사진을 업로드하는 명령을 보여 줍니다. 이와는 대조적으로 Windows 스토어 앱은 앱 바를 사용하여 사진 업로드 동작을 보여 줍니다. 그런 다음 앱 바의 명령을 통해 파일 선택기가 열립니다. 이 연습은 앱이 작업을 수행하고 앱 바에 이러한 작업을 추가함으로써 적은 동작으로 더 많은 효과를 얻고 크롬보다 먼저 콘텐츠를 선택할 수 있도록 하는 방법의 한 가지 예에 불과합니다.

지침

앱 바의 명령은 사용자가 보고 있는 페이지 또는 앱의 컨텍스트에 따라 달라질 수 있습니다. 글로벌 명령은 사용자가 페이지를 탐색할 때 나타나지만 상황에 맞는(또는 선택) 명령은 특정 항목이 선택될 때 나타납니다. 상황에 맞는 명령은 그리드를 선택 가능하게 만들고 상황에 맞는 앱 바 명령을 표시할 때 나타납니다.

참고  메일 보내기나 제품 구매처럼 사용자가 워크플로를 완료하는 데 필요한 명령은 예외이며 캔버스에 표시될 수 있습니다.

예제 개요

이 자습서 부분에서는 그리드 형태 응용 프로그램 템플릿의 그룹화된 항목 페이지 및 항목 세부 정보 페이지에 앱 바를 추가합니다. 그룹화된 항목 페이지의 레이블 크기와 항목 세부 정보 페이지의 본문 텍스트 크기를 변경할 수 있는 명령을 추가합니다. 보고 있는 페이지와 관련된 명령만 표시하고 그룹 세부 정보 페이지에는 앱 바를 표시하지 않을 것입니다.

다음 스크린샷에서 그룹화된 항목 페이지의 앱 바에는 Increase label size(레이블 크기 늘리기) 명령이 표시됩니다.

앱 바에 Increase label size(레이블 크기 늘리기) 명령을 표시하는 그룹화된 항목 페이지의 스크린샷

이 스크린샷에는 Increase text size(텍스트 크기 늘리기) 명령을 표시하는 앱 바가 있는 항목 세부 정보 페이지가 표시됩니다.

앱 바에 Increase text size(텍스트 크기 늘리기) 명령을 표시하는 항목 세부 정보 페이지의 스크린샷

구현

다음 단계에서는 글로벌 앱 바 단추가 있는 글로벌 앱 바를 추가합니다. 각 페이지의 ready 함수에서 단추를 표시하거나 숨깁니다. 이벤트 처리기를 호출하여 앞에 설명된 기능을 수행하는 명령을 이벤트 수신기에 적용합니다. 그룹 세부 정보 페이지에는 표시할 명령이 없으므로 이 페이지의 앱 바는 사용되지 않도록 설정합니다.

  1. Default.html에서는 템플릿에서 앱 바를 찾아 보겠지만 주석 처리되어 있을 것입니다. 이 주석을 제거하여 앱 바를 HTML의 일부로 적용합니다.

  2. 앱 바 div 요소에는 자리 표시자 단추가 포함되어 있습니다. 이 단추를 다음 단추로 교체합니다.

    
    <button id="labelSize" data-win-control="WinJS.UI.AppBarCommand" data-win-options="{id:'labelSize', section:'global', label:'Label size', icon:'add'}"></button>
    <button id="textSize" data-win-control="WinJS.UI.AppBarCommand" data-win-options="{id:'textSize', section:'global', label:'Text size', icon:'add'}"></button>
    
    
  3. Default.js에서 다음 이벤트 수신기를 추가합니다.

    
    
    app.addEventListener("activated", function (args) {
        if (args.detail.kind === activation.ActivationKind.launch) {
            if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
                // TODO: This application has been newly launched. Initialize your 
                // application here.
    
                // Add the following two lines of code.									
                document.getElementById("labelSize").onclick = increaseLabelSize;
                document.getElementById("textSize").onclick = increaseTextSize;
            } else {
    
            ...
    
    
    
  4. Default.js에서 다른 함수 옆에 다음 함수를 추가합니다(파일에 속함).

    
    function increaseLabelSize() {
        var titles = document.getElementsByClassName("item-title");
        var subtitles = document.getElementsByClassName("item-subtitle");
        var i;
        for (i = 0; i < titles.length; i++) {
            var prevTitleAttributes = titles[i].getAttribute("style");
            var prevSubtitleAttributes = subtitles[i].getAttribute("style");
            if (prevTitleAttributes != null)
                titles[i].setAttribute("style", prevTitleAttributes + "font-size:20px");
            else
                titles[i].setAttribute("style", "font-size:20px");
            if (prevSubtitleAttributes != null)
                subtitles[i].setAttribute("style", prevSubtitleAttributes + "font-size: 14px");
            else
                subtitles[i].setAttribute("style", "font-size: 14px");
        }
    };
    
    function increaseTextSize() {
        var content = document.getElementsByClassName("item-content");
        content[0].setAttribute("style", "font-size:20px");
    };
    
    
  5. 각 페이지에 관련 명령만 표시되는지 확인합니다.

    GroupedItems.js에서 ready 함수에 다음 코드를 추가합니다.

    
    appbar.winControl.disabled = false;
    appbar.winControl.hideCommands([textSize]);
    appbar.winControl.showCommands([labelSize]);
    
    

    GroupDetail.js에서는 ready 함수에 다음 코드 줄을 추가합니다.

    
    appbar.winControl.disabled = true;
    
    

    ItemDetail.js에서 ready 함수에 다음 코드를 추가합니다.

    
    appbar.winControl.disabled = false;
    appbar.winControl.hideCommands([labelSize]);
    appbar.winControl.showCommands([textSize]);
    
    

그리드를 선택 가능하게 만들고 상황에 맞는 앱 바 명령 표시

여기서는 사용자가 작업을 수행하려는 항목을 선택할 수 있는 ListView를 추가합니다. ListView에 대한 자세한 내용은 HTML ListView 샘플 팩(영문)을 참조하세요.

목적

사용자는 ListView의 항목에 대해 다양한 작업을 수행하려고 할 수 있습니다. 작업을 하나의 기본 작업과 여러 개의 보조 작업으로 나눕니다. 기본 작업은 항목을 탭하거나 클릭하여 수행할 수 있습니다. 이 작업을 수행하려면 일반적으로 사용자가 해당 항목으로 이동해야 합니다.

사용자는 항목을 선택하고 앱 바를 통해 항목에 대해 명령을 수행하여 보조 작업을 수행합니다. 사용자는 그리드의 항목에 대해 항목 삭제, 시작에 항목 추가, 항목을 즐겨찾기로 만들기, 항목을 읽은 상태로 표시, 항목 이름 바꾸기 등과 같은 다양한 보조 작업을 수행할 수 있습니다. 사용자는 이동 방향에 수직으로 밀거나, 마우스 오른쪽 단추를 클릭하거나, 키보드의 스페이스바를 눌러 항목을 선택할 수 있습니다.

실전

iPad - Windows 8 Windows 스토어 앱 사례 연구에서는 앱이 선택 가능한 그리드 및 앱 바를 사용하여 상황에 맞는 명령을 다시 지정하는 방법을 보여 줍니다. 다음은 사진 저널 앱에서 사진을 삭제하는 방법을 연습하는 과정입니다. 왼쪽에는 iPad에서 이 작업을 수행하는 방법을 단계별로 연습하는 과정이 표시됩니다. 오른쪽에는 Microsoft 디자인 스타일을 활용하는 시나리오가 나와 있습니다.

iPad 및 Windows 스토어 앱에서 사진을 삭제하는 단계에 대한 스크린샷

iPad 앱에서 사용자는 우선 선택 모드를 시작하며, 화면 위쪽에 상황에 맞는 명령이 표시됩니다. Windows 스토어 앱에서는 앱 바 화면에서 상황에 맞는 명령이 숨겨집니다. A단계에서 사용자는 앱 바를 호출합니다. 처음에 앱 바가 호출되면 그리드에서 선택된 항목이 없으며 글로벌 명령만 표시됩니다. B단계에서 사용자는 앱 바 왼쪽 부분에 상황에 맞는 명령이 표시되는 그리드에서 항목을 선택하기 시작합니다.

설명

항목이 선택되면 선택한 항목에 대해 상황에 맞는 명령을 표시하도록 앱 바가 호출되어야 합니다. 여러 항목이 선택되면 이 앱 바는 그대로 작동 상태를 유지하고 선택한 모든 항목에 대해 상황에 맞는 명령을 표시해야 합니다. 사용자가 항목을 선택 취소할 경우 마지막 항목이 선택 취소될 때 앱 바가 숨겨져야 합니다.

상황에 맞는 명령을 포함하는 앱 바가 표시되더라도 글로벌 명령은 항상 계속 표시되어야 합니다. 글로벌 명령은 앱 바 오른쪽에 맞춰지고 상황에 맞는 명령은 왼쪽에 맞춰집니다.

한 번에 항목 하나만 또는 여러 개를 선택하도록 선택할 수 있습니다.

앱을 끌어도 앱은 가능한 많은 상태를 유지할 수 있어야 합니다. 앱 바가 작동될 때는 앱을 끌어도 앱 바가 그대로 작동 상태를 유지해야 합니다. 항목이 선택된 상태에서 앱을 끌어도 항목은 선택된 상태를 유지해야 합니다.

그러나 그룹화된 항목 페이지를 끌 경우 끌어온 뷰에 그룹의 축소된 뷰가 표시됩니다. 따라서 끌기 상태인 동안에는 개별 항목의 선택 여부가 표시될 수 없습니다. 개별 항목은 표시할 수 없으므로 이전에 선택한 항목에 대한 모든 상황에 맞는 명령은 숨겨져야 합니다.

예제 개요

이 자습서 섹션에서는 그리드의 항목을 선택 가능하게 만듭니다. 이렇게 하면 한 번에 여러 항목이 선택될 수 있습니다. 항목이 선택되면 앱 바가 즉시 호출되고 항목을 읽은 상태로 표시하기 위한 상황에 맞는 명령이 나타납니다. 이 경우 선택된 모든 항목의 제목이 회색으로 바뀝니다. 항목을 선택 취소하면 앱 바가 숨겨집니다. 읽은 상태로 표시된 항목을 선택하면 해당 작업이 수행되고, 항목이 선택 취소되고, 앱 바가 숨겨집니다.

이 스크린샷에는 여러 개의 항목이 선택되어 있고 읽은 상태로 표시 상황에 맞는 명령과 Increase label size(레이블 크기 늘리기) 글로벌 명령을 표시하는 앱 바가 있는 그룹화된 항목 페이지가 나와 있습니다.

이 스크린샷에는 여러 개의 항목이 선택되어 있고 상황에 맞는 명령과 글로벌 명령을 표시하는 앱 바가 있는 그룹화된 항목 페이지를 나타내는 스크린샷

구현

다음 단계에서는 그리드 형태 항목을 선택할 수 있도록 합니다. 또한 선택한 항목에 대한 상황에 맞는 명령이 들어 있는 앱 바를 표시하는 이벤트 수신기를 추가합니다.

  1. GroupedItems.html에서 ListView의 선택 모드를 'none'에서 'multi'로 변경하여 GridView 항목을 선택 가능하게 만듭니다.

    
    data-win-options="{ selectionMode: 'multi' }"
    
    
    
  2. Default.html에서 다른 앱 바 명령 옆에 다음의 상황에 맞는 앱 바 명령을 추가합니다.

    
    <button id="markItem" data-win-control="WinJS.UI.AppBarCommand" data-win-options="{id:'markItem', section:'selection', label:'Mark as read', icon:'accept'}"></button>
    
    
  3. Default.js에서 app.onactivated 처리기의 다른 앱 바 이벤트 수신기 옆에 다음 이벤트 수신기를 추가합니다.

    
    document.getElementById("markItem").onclick = markItem;
    
    
  4. Default.js에서 다른 앱 바 명령 함수 옆에 markItem 함수를 추가합니다.

    
    function markItem() {
        var titles = document.getElementsByClassName("item-title");
        var subtitles = document.getElementsByClassName("item-subtitle");
        var listView = document.querySelector(".groupeditemslist").winControl;
        var items = listView.selection.getItems();
        var i;
        for (i = 0; i < items._value.length; i++) {
            var key = parseFloat(items._value[i].key);
            if (titles[0].innerHTML != "") {
                if (key == 0) continue;
                key--;
            }
            var prevTitleAttributes = titles[key].getAttribute("style");
            var prevSubtitleAttributes = subtitles[key].getAttribute("style");
            if (prevTitleAttributes != null)
                titles[key].setAttribute("style", prevTitleAttributes + "color:gray");
            else
                titles[key].setAttribute("style", "color:gray");
    
            if (prevSubtitleAttributes != null)
                subtitles[key].setAttribute("style", prevSubtitleAttributes + "color:gray");
            else
                subtitles[key].setAttribute("style", "color:gray");
        }
        listView.selection.clear();
    }
    
    
  5. ItemDetail.js에서 Mark Item(항목 표시) 단추도 숨기도록 hideCommands 함수에 대한 호출을 수정합니다.

    
    appbar.winControl.hideCommands([labelSize, markItem]);
    
    
  6. GroupedItems.js에서 Mark Item(항목 표시) 단추도 숨기도록 hideCommands 함수에 대한 호출을 수정합니다.

    
    appbar.winControl.hideCommands([textSize, markItem]);
    
    
  7. GroupedItems.js에서 ui.Pages.define 함수 앞에 다음 함수를 추가합니다. 이러한 함수는 프로그래밍 방식으로 앱 바를 표시 및 숨깁니다.

    
    function showAppBar(currentItem) {
        // Get the app bar.
        var element = document.activeElement;
        var appbar = document.getElementById("appbar");
        
        // Keep the app bar open after it's shown.
        appbar.winControl.sticky = true;
     
        // Set the app bar context.
        showItemCommands();
    
        // Show the app bar.
        appbar.winControl.show();
    
        // Return focus to the original item which invoked the app bar.
        if (element != null) element.focus();
    }
    
    function hideAppBar() {
        var element = document.activeElement;
        var appbar = document.getElementById("appbar");
        appbar.winControl.sticky = false;
        appbar.winControl.hide();
        hideItemCommands();
        if (element != null) element.focus();
    }
    
    
  8. GroupedItems.js에서 앞의 함수 다음에 다음 함수를 추가합니다. 다음 함수는 앱 바 명령을 표시 및 숨깁니다.

    
    function showItemCommands() {
        appbar.winControl.showCommands([markItem]);
    }
    
    function hideItemCommands() {
        appbar.winControl.hideCommands([markItem]);
    }
    
    
  9. GroupedItems.js에서 프로그래밍 방식으로 앱 바를 열고 닫는 코드를 추가합니다. ready 함수에서 페이지에 ListView에 대한 선택 내용 변경함 이벤트 처리기를 추가합니다.

    
    listView.onselectionchanged = this.itemSelected.bind(this);
    
    
  10. GroupedItems.js에서 ListView의 선택 내용을 처리하기 위해 다음 함수를 추가합니다.

    
    itemSelected: function (eventObject) {
        var listView = document.querySelector(".groupeditemslist").winControl;
    
        // Check for selection.
        if (listView.selection.count() === 0) {
            hideAppBar();
        } else {
            listView.selection.getItems().then(function (items) {
                showAppBar(items[0]);
           	});
        }
    },
    
    
  11. GroupedItems.js에서 updateLayouthideItemCommands 함수에 대한 호출을 추가합니다. 이 호출은 앱을 끌 때 앱 바에서 상황에 맞는 명령을 숨깁니다. 항목은 끌기 상태에서는 선택된 것으로 표시되지 않으므로 앱을 끌 때는 상황에 맞는 명령이 나타나지 않습니다.

    
    updateLayout: function (element, viewState, lastViewState) {
        /// <param name="element" domElement="true" />
        /// <param name="viewState" value="Windows.UI.ViewManagement.ApplicationViewState" />
        /// <param name="lastViewState" value="Windows.UI.ViewManagement.ApplicationViewState" />
    
        var listView = element.querySelector(".groupeditemslist").winControl;
        if (lastViewState !== viewState) {
            if (lastViewState === appViewState.snapped || viewState === appViewState.snapped) {
                var handler = function (e) {
                    listView.removeEventListener("contentanimating", handler, false);
                    e.preventDefault();
                }
            listView.addEventListener("contentanimating", handler, false);
    
            // Add the following five lines of code.        
            this.initializeLayout(listView, viewState);
            hideItemCommands();
            if (viewState === appViewState.snapped)
                listView.selectionMode = "none";
            else
                listView.selectionMode = "multi";
            }
        }
    }
    
    

SemanticZoom 컨트롤 추가

이 섹션에서는 SemanticZoom 컨트롤을 추가하여 ListView 그리드의 항목에 대해 시맨틱 뷰를 제공합니다. 축소된 뷰의 각 항목은 그리드의 항목 그룹에 해당합니다.

ListView 그리드의 항목을 표시하는 스크린샷

시맨틱 줌에 대한 자세한 내용은 HTML ListView 그룹화 및 SemanticZoom 샘플(영문)을 참조하세요.

목적

그리드 형태 응용 프로그램 템플릿은 계층형 탐색 패턴을 사용합니다. 즉, 앱의 각 주요 섹션에서 관심 있는 콘텐츠를 방문 페이지에서 알릴 수 있습니다. 이 방문 페이지는 많은 수의 그룹이나 많은 수의 항목을 포함하도록 커질 수 있습니다. 사용자는 뷰를 이동하여 콘텐츠를 탐색할 수 있지만 페이지의 다른 섹션으로 빠르게 이동할 수 있도록 시맨틱 줌을 추가하는 것을 고려해 보세요.

SemanticZoom 컨트롤을 사용하여 그리드를 그룹에 대한 광학 뷰가 아니라 시맨틱 뷰로 축소할 수 있습니다. 이 뷰에서 사용자는 다시 확대할 그룹을 선택할 수 있습니다. 시맨틱 줌을 사용하면 이동하지 않고도 대규모 항목 그룹을 볼 수 있으며 그리드에 포함된 그룹에 대한 전반적인 뷰도 볼 수 있습니다.

축소된 뷰는 사용자를 페이지에서 관심 있는 섹션으로 안내하기 위해 그룹에 대한 메타 정보를 제공할 수도 있습니다. 예를 들어 축소된 뷰에 숫자 오버레이가 있는 그룹의 항목 수가 표시될 수 있습니다.

실전

iPad - Windows 8 Windows 스토어 앱 사례 연구에서는 앱에서 시맨틱 줌을 사용하여 항목 그룹 간을 빠르게 이동할 수 있도록 하는 방법을 보여 줍니다. 다음은 시맨틱 줌을 사용하여 그룹의 시맨틱 뷰를 표시하는 방법을 연습해보는 과정입니다. 왼쪽에는 iPad에서 이 작업을 수행하는 방법을 단계별로 연습하는 과정이 표시됩니다. 오른쪽에는 Microsoft 디자인 스타일을 활용하는 시나리오가 나와 있습니다.

시맨틱 줌과 iPad에서 항목 그룹 간을 전환하는 방법을 비교해서 보여 주는 스크린샷

iPad 앱에서는 위쪽 탐색 모음의 단추를 눌러 연도 목록이 있는 팝업을 표시할 수 있습니다. Windows 스토어 앱에서 사용자는 손가락 모으기 제스처로 시맨틱 줌을 사용하여 그룹을 축소할 수 있습니다. 이 예제에서 이 시맨틱 뷰는 설명 그룹에 포함된 설명의 수를 표시하고 사진이 있는 월을 표시하도록 구성되었습니다.

구현

다음 단계에서는 그룹화된 항목 페이지에 시맨틱 줌 컨테이너를 추가하고 시맨틱 줌 그룹에 대한 템플릿을 추가합니다.

의미 중심 그룹을 그룹 데이터 소스에 연결한 다음 CSS(CSS 스타일시트)를 적용하여 그룹 스타일을 적절히 지정합니다.

  1. GroupedItems.html에서는 주 콘텐츠 섹션에서 ListView 컨트롤을 찾습니다.

    
    <section aria-label="Main content" role="main">
        <div class="groupeditemslist" aria-label="List of groups" data-win-control="WinJS.UI.ListView" data-win-options="{ selectionMode: 'multi' }"></div>
    </section>
    
    

    기본적으로 SemanticZoom 컨트롤은 현재의 배율에 따라 하위 요소를 하나만 표시하는 컨테이너입니다. 여기서는 SemanticZoom 컨트롤을 섹션의 "루트"로 추가하고 두 개의 ListView 컨트롤을 SemanticZoom 컨트롤에 배치합니다.

    먼저 주 콘텐츠 섹션을 다음과 같이 변경합니다.

    
    <section aria-label="Main content" role="main">
        <div class="sezoDiv" data-win-control="WinJS.UI.SemanticZoom" data-win-options="{ zoomFactor: 0.5, initiallyZoomedOut: false }">
            <div class="groupeditemslist" aria-label="List of groups" data-win-control="WinJS.UI.ListView" data-win-options="{selectionMode: 'multi'}"></div>
            <div class="groupeditemslistZoomOut groupeditemslist" aria-label="List of groups" data-win-control="WinJS.UI.ListView" data-win-options="{selectionMode: 'none'}"></div>
        </div>
    </section>
    
    
    
    • 페이지의 컨트롤을 설정했으므로 현재 콘텐츠가 표시되도록 하는 코드를 추가할 것입니다.

      GroupedItems.js에서 ready 함수에 다음과 같은 추가 및 변경 작업을 수행합니다. 기본적으로 첫 번째 목록 뷰에서 이미 존재하는 항목을 복제한 다음 축소된 새 ListView에 적용합니다.

      
      ready: function (element, options) {
          var listView = element.querySelector(".groupeditemslist").winControl;
      
          // Add the following two lines of code.
          var listViewZoomOut = element.querySelector(".groupeditemslistZoomOut").winControl;
          var semanticZoom = element.querySelector(".sezoDiv").winControl;
      
          listView.groupHeaderTemplate = element.querySelector(".headerTemplate");
          listView.itemTemplate = element.querySelector(".itemtemplate");
      
          // Add the following line of code.
          listViewZoomOut.itemTemplate = element.querySelector(".itemtemplate");
      
          listView.oniteminvoked = this.itemInvoked.bind(this);
      
          // Add the following line of code.
          listViewZoomOut.oniteminvoked = this.groupInvoked.bind(this)
      
          // Change the second and third parameters of the following call as shown.
          this.initializeLayout(listView,listViewZoomOut, semanticZoom, appView.value);
      },
      
      
  2. GroupedItems.js에서 두 번째 목록 뷰를 수용하도록 inializeLayout 함수를 업데이트합니다. 또한 이 함수는 끌어온 뷰에서 시맨틱 줌 컨트롤을 처리합니다.
    
    
    // Add the listViewZoomOut and semanticZoom parameters as shown.
    initializeLayout: function (listView, listViewZoomOut, semanticZoom, viewState) {
        /// <param name="listView" value="WinJS.UI.ListView.prototype" />
    
        if (viewState === appViewState.snapped) {
            listView.itemDataSource = Data.groups.dataSource;
            listView.groupDataSource = null;
            listView.layout = new ui.ListLayout();
    
            // Add the following three lines of code.
            semanticZoom.zoomedOut = false;
            semanticZoom.forceLayout();
            semanticZoom.locked = true;
        } else {
            listView.itemDataSource = Data.items.dataSource;
            listView.groupDataSource = Data.groups.dataSource;
            listView.layout = new ui.GridLayout({ groupHeaderPosition: "top" });
    
            // Add the following four lines of code.
            listViewZoomOut.itemDataSource = Data.groups.dataSource;
            listViewZoomOut.layout = new ui.GridLayout({ maxRows: 1 });
            semanticZoom.forceLayout();
            semanticZoom.locked = false;
        }
    },
    
    
  3. GroupedItems.js에서 updateLayout 함수를 업데이트하고, 그룹화된 데이터 소스를 사용하여 그룹 목록을 표시하도록 새 ListView를 구성합니다.

    
    updateLayout: function (element, viewState, lastViewState) {
        /// <param name="element" domElement="true" />
        /// <param name="viewState" value="Windows.UI.ViewManagement.ApplicationViewState" />
        /// <param name="lastViewState" value="Windows.UI.ViewManagement.ApplicationViewState" />
        var listView = element.querySelector(".groupeditemslist").winControl;
    
        // Add the following two lines of code.
        var listViewZoomOut = element.querySelector(".groupeditemslistZoomOut").winControl;
        var semanticZoom = element.querySelector(".sezoDiv").winControl;
    
        if (lastViewState !== viewState) {
            if (lastViewState === appViewState.snapped || viewState === appViewState.snapped) {
                var handler = function (e) {
                    listView.removeEventListener("contentanimating", handler, false);
                        e.preventDefault();
                }
                listView.addEventListener("contentanimating", handler, false);
    
                // Add the listViewZoomOut and semanticZoom parameters as shown.
                this.initializeLayout(listView, listViewZoomOut, semanticZoom, viewState);
            }
    
            // Add the following four lines of code.
            if (lastViewState === appViewState.snapped) {
                semanticZoom.zoomedOut = true;
                semanticZoom.forceLayout();
            }
        }
    },
    
    
  4. GroupedItems.js에서 사용자가 축소된 뷰에서 항목을 탭하거나 클릭할 때 처리할 다음 함수를 추가합니다.

    
    groupInvoked: function (args) {
       	var group = Data.groups.getAt(args.detail.itemIndex);
        nav.navigate("/pages/groupDetail/groupDetail.html", { groupKey: group.key });
    },
    
    
  5. 이제 CSS를 추가하여 항목을 멋지게 꾸며 보세요.

    참고  시맨틱 줌에 대한 UX(사용자 환경) 지침을 구현하기 위해 행과 열이 하나씩만 있는 CSS 그리드를 사용합니다. 이 그리드에서 머리글 및 섹션 콘텐츠가 겹쳐질 수 있게 배치합니다. 즉, SemanticZoom 컨트롤이 페이지 머리글을 비롯한 전체 화면을 덮을 수 있습니다.

    GroupedItems.css에서 다음 스타일을 추가하여 SemanticZoom 컨트롤이 화면의 가용 공간을 차지하게 합니다. 이 경우 전체 프레그먼트의 레이아웃이 변경되므로 페이지 머리글 콘텐츠가 sezo div를 포함하는 섹션 콘텐츠 아래에 배치됩니다.

    
    .groupeditemspage {
        /* Change the display type to have only one row */
        -ms-grid-rows: 1fr;
        display: -ms-grid;
        height: 100%;
        width: 100%;
    }
    
        .groupeditemspage header[role=banner] {
            /* Position this at the top of the screen */
            -ms-grid-row: 1;    
            -ms-grid-columns: 120px 1fr;
            display: -ms-grid;
        }
    
        .groupeditemspage section[role=main] {
            /* Position this at the top of the screen */
            -ms-grid-row: 1;
            height: 100%;
            width: 100%;
        }
    
    .sezoDiv
     {
        height: 100%;
        width: 100%;
    }
    
    
  6. 다음에는 SemanticZoom 컨트롤이 음수 여백을 사용하여 배치되기 때문에 발생하는 일부 문제를 해결해야 합니다.

    페이지 머리글을 보려면 목록 뷰를 133픽셀 아래로 이동합니다.

    
    .groupeditemspage .groupeditemslist .win-horizontal.win-viewport .win-surface {
        margin-left: 45px;
        /* Add the following line. */
        margin-top: 133px;
        margin-bottom: 60px;
    }
    
    /* Add the following lines near the end of the CSS file. */
    .groupeditemspage .groupeditemslistZoomOut .win-horizontal.win-viewport .win-surface {
        margin-left: 116px;
        margin-top: 133px;
    }
    
    
  7. 이제 축소된 뷰로 표시되도록 항목의 스타일을 지정해야 합니다. 다음 CSS 코드를 추가하여 이미 파일에 속해 있는 groupeditemslist.win-item 스타일 다음에 선언되도록 합니다.

    
    
        .groupeditemspage .groupeditemslistZoomOut .win-item {
            -ms-grid-columns: 1fr;   
            -ms-grid-rows: 1fr 90px;
            display: -ms-grid;
            height: 250px;
            width: 250px;
        }
    .groupeditemspage .groupeditemslistZoomOut .win-item {
        -ms-grid-rows: 1fr 180px;
        display: -ms-grid;
        height: 580px;
        width: 250px;
    }
    
    
  8. 이제 끌어온 뷰 및 세로 뷰에 영향을 미치도록 변경을 수행했으므로 이러한 뷰를 수정해야 합니다. GroupedItems.css의 @media screen and (-ms-view-state: snapped) 섹션에 다음 스타일을 모두 추가합니다.

    다음 스타일을 추가하여 머리글 섹션의 다시 맞춥니다.

    
    .groupeditemspage header[role=banner] {
        -ms-grid-columns: auto 1fr;
        margin-left: 20px;
    }
    
    

    화면 위에 여백을 추가하여 목록이 제목을 덮지 않도록 합니다.

    
    .groupeditemspage .groupeditemslist .win-vertical.win-viewport .win-surface {
        margin-bottom: 30px;
        /* Add the following line. */
        margin-top: 133px;
        margin-left: 6px;
    }
    
    
  9. 이제 끌어온 뷰의 문제는 해결되었습니다. 다음에는 세로 뷰를 업데이트해야 합니다.

    GroupedItems.css에서 @media screen and (-ms-view-state: fullscreen-portrait) 섹션에 다른 스타일을 추가합니다.

    
    
    .groupeditemspage .groupeditemslistZoomOut .win-horizontal.win-viewport .win-surface {
        margin-left: 96px;
    }
    
    

여러 크기 항목을 그리드 형태로 제공

그리드에 다양한 크기의 항목을 표시하는 것은 그리드를 사용자 지정하고 앱을 차별화하는 좋은 방법입니다. 여러 크기 항목을 사용하여 앱은 좀 더 중요한 항목의 크기는 늘려서 특정 항목은 강조하고 다른 항목은 덜 강조할 수 있습니다.

크기가 다른 항목마다 다른 템플릿을 사용할 수도 있습니다. 예를 들어 좀 더 큰 항목에 대해서는 텍스트 오버레이가 나타나고 더 작은 항목에 대해서는 텍스트만 있는 이미지를 표시하려고 할 수 있습니다.

실전

iPad - Windows 8 Windows 스토어 앱 사례 연구에서는 앱에서 여러 크기 항목 및 다양한 템플릿을 사용하여 그리드 형태 템플릿을 사용자 지정하고 앱을 브랜딩하는 방법을 보여 줍니다. 다음 예제에서는 iPad 앱 방문 페이지와 그리드 형태 템플릿을 사용자 지정한 Windows 스토어 앱 방문 페이지를 비교합니다.

iPad 및 Windows 스토어 앱 방문 페이지를 비교하는 스크린샷

iPad 앱에서 모든 콘텐츠는 균일한 그리드 형태 사진으로 제공됩니다. Windows 스토어 앱에서 항목은 다양한 크기로 여러 템플릿과 함께 제공됩니다. 첫 번째 그룹에는 항목과 작은 사진 및 설명 텍스트가 나란히 포함되어 있습니다. 나머지 그룹은 다양한 크기의 텍스트가 겹쳐진 크고 작은 이미지로 구성됩니다.

예제 개요

이 섹션의 예제는 세 가지 다른 크기의 항목을 사용하도록 그룹화된 항목 페이지의 그리드 형태를 사용자 지정합니다. 기본 그리드 형태는 200x200 픽셀 항목을 사용합니다. 또한 310x310 픽셀, 310x150 픽셀 및 150x150 픽셀의 항목을 사용합니다. 크기가 더 큰 항목은 기본 이미지와 텍스트 오버레이 레이아웃을 사용하고 더 작은 항목은 텍스트만 포함합니다.

다음은 세 가지 다른 항목 크기를 갖는 그룹화된 항목 페이지입니다.

세 가지 다른 항목 크기를 표시하는 그룹화된 항목 페이지의 스크린샷

구현

이 시나리오에 맞는 사용자 환경을 구현하려면 목록 뷰에 대한 자체 렌더링 함수를 정의해야 합니다. 또한 여러 다른 크기 항목에 대해 CSS를 추가해야 합니다.

렌더링 함수의 경우 함수에 수동으로 CSS를 만드는 대신 미리 정의된 HTML 템플릿에서 읽어옵니다.

여러 항목 크기를 선택할 때는 다음 수식에 따라 크기를 지정해야 합니다. itemSize = ((slotSize + margin) x multiplier) – margin.

  1. GroupedItems.html에서 다음 항목 템플릿을 추가합니다.

    
    <div class="multisizebaseitemtemplate" data-win-control="WinJS.Binding.Template">
        <img class="item-image" src="#" data-win-bind="src: backgroundImage; alt: title" />
        <div class="item-overlay">
            <h4 class="item-title" data-win-bind="textContent: title"></h4>
            <h6 class="item-subtitle win-type-ellipsis" data-win-bind="textContent: subtitle"></h6>
        </div>
    </div>
    
    
  2. GroupedItems.js에서 페이지 정의(ui.Pages.define) 앞에 다음 함수를 추가합니다.

    
    function multisizeItemTemplateRenderer(itemPromise) {
        return itemPromise.then(function (currentItem) {
            var content;
            // Grab the default item template used on the groupeditems page.
            content = document.getElementsByClassName("multisizebaseitemtemplate")[0];
            var result = content.cloneNode(true);
    
            // Change the CSS class of the item depending on the group, then set the size in CSS.
            switch (currentItem.groupKey) {
                case "group1":
                    {
                        // For the first item, use the largest template.
                        if (currentItem.index == 0) {
                            result.className = "largeitemtemplate"
                        }
                        else {
                            result.className = "mediumitemtemplate"
                        }
                        break;
                    }
                case "group2":
                    {
                        result.className = "mediumitemtemplate"
                        break;
                    }
                default:
                    {
                        result.className = "smallitemtemplate"
                    }
            }
            // Because we used a WinJS template, we need to strip off some attributes 
            // for it to render.
            result.attributes.removeNamedItem("data-win-control");
            result.attributes.removeNamedItem("style");
            result.style.overflow = "hidden";
    
            // Because we're doing the rendering, we need to put the data into the item.
            // We can't use databinding.
            result.getElementsByClassName("item-image")[0].src = currentItem.data.backgroundImage;
            result.getElementsByClassName("item-title")[0].textContent = currentItem.data.title;
            result.getElementsByClassName("item-subtitle")[0].textContent = currentItem.data.subtitle;
            return result;
        });
    }
    
    
  3. GroupedItems.js에서 아래의 groupInfo 함수를 페이지 정의 밖에도 추가합니다. 이 함수는 뷰에서 여러 크기 항목을 사용하도록 ListView에 지정하고 항목의 "기본 크기"를 지정합니다. 기본 크기는 목록에 표시된 가장 작은 항목입니다. 레이아웃이 제대로 작동하려면 다른 항목 크기가 이 크기의 배수여야 합니다.

    
    function groupInfo() {
        return {
            enableCellSpanning: true,
            cellWidth: 150,
            cellHeight: 150
        };
    }
    
    
  4. 이제 이러한 새 함수가 그룹화된 항목 페이지의 ListView 컨트롤에 작동하도록 해야 합니다. 끌어온 뷰에서는 가변 크기 이미지를 사용하려고 하지 않으므로 ready 함수 및 updateLayout 함수 둘 다에서 목록 뷰 코드에 템플릿이 적용되는 방식을 변경해야 합니다.

    GroupedItems.js에서 페이지가 끌어온 뷰일 때 그룹의 단순 목록을 표시하도록 initializeLayout 함수를 변경합니다. 그러나 가로 보기에서 여러 크기 항목을 사용합니다.

    
    
    // Add the itemTemplate parameter as shown.
    initializeLayout: function (listView, listViewZoomOut, semanticZoom, viewState, itemTemplate) {
        /// <param name="listView" value="WinJS.UI.ListView.prototype" />
    
        if (viewState === appViewState.snapped) {
            listView.itemDataSource = Data.groups.dataSource;
            listView.groupDataSource = null;
    
            // Add the followign line of code.
            listView.itemTemplate = itemTemplate;
    
            listView.layout = new ui.ListLayout();
            semanticZoom.zoomedOut = false;
            semanticZoom.forceLayout();
            semanticZoom.locked = true;
        } else {
            listView.itemDataSource = Data.items.dataSource;
            listView.groupDataSource = Data.groups.dataSource;
    
            // Add the following two lines of code.
            listView.itemTemplate = multisizeItemTemplateRenderer;
            listView.layout = new ui.GridLayout({ groupInfo: groupInfo, groupHeaderPosition: "top" });
    
            listViewZoomOut.itemDataSource = Data.groups.dataSource;
            listViewZoomOut.layout = new ui.GridLayout({ maxRows: 1 });
            semanticZoom.forceLayout();
            semanticZoom.locked = false;
        }
    },
    
    

    다음 코드에서 ListView에 항목 템플릿을 할당하는 줄을 제거하고 주석에 표시된 대로 변경합니다.

    
    ready: function (element, options) {
        var listView = element.querySelector(".groupeditemslist").winControl;
        var listViewZoomOut = element.querySelector(".groupeditemslistZoomOut").winControl;
        var semanticZoom = element.querySelector(".sezoDiv").winControl;
    
        // Add the following line of code.
        var itemTemplate = element.querySelector(".itemtemplate");
    
        listView.groupHeaderTemplate = element.querySelector(".headerTemplate");
    
        listView.oniteminvoked = this.itemInvoked.bind(this);
        listViewZoomOut.itemTemplate = element.querySelector(".itemtemplate");
        listViewZoomOut.oniteminvoked = this.groupInvoked.bind(this)
    
        // Change the last argument of the following function to itemTemplate.
        this.initializeLayout(listView,listViewZoomOut, semanticZoom, appView.value, itemTemplate);
        listView.element.focus();
     },
    
    // This function updates the page layout in response to viewState changes.
    updateLayout: function (element, viewState, lastViewState) {
        /// <param name="element" domElement="true" />
        /// <param name="viewState" value="Windows.UI.ViewManagement.ApplicationViewState" />
        /// <param name="lastViewState" value="Windows.UI.ViewManagement.ApplicationViewState" />
        var listView = element.querySelector(".groupeditemslist").winControl;
        var listViewZoomOut = element.querySelector(".groupeditemslistZoomOut").winControl;
        var semanticZoom = element.querySelector(".sezoDiv").winControl;
    
        // Add the following line of code.
        var itemTemplate = element.querySelector(".itemtemplate");
    
        if (lastViewState !== viewState) {
            if (lastViewState === appViewState.snapped || viewState === appViewState.snapped) {
                var handler = function (e) {
                    listView.removeEventListener("contentanimating", handler, false);
                    e.preventDefault();
                }
                listView.addEventListener("contentanimating", handler, false);
    
                // Change this line to pass through the item template.
                this.initializeLayout(listView, listViewZoomOut, semanticZoom,viewState,itemTemplate);
            }
            if (lastViewState === appViewState.snapped) {
                semanticZoom.zoomedOut = true;
                semanticZoom.forceLayout();
            }
        }
    },
    
    
  5. 이 영역에 대한 코드가 이제 완료되었습니다. 다음에는 항목의 스타일을 추가해야 합니다.

    GroupedItems.css에서 작은 항목, 보통 항목 및 큰 항목 템플릿에 대해 다음 스타일을 추가합니다.

    
    
    .groupeditemspage .smallitemtemplate
    {
        width: 150px;
        height: 150px;
        overflow: hidden;
        -ms-grid-columns: 1fr;
        -ms-grid-rows: 0px 1fr;
        display: -ms-grid;
    }
    .smallitemtemplate .item-overlay .item-title {
        position: absolute; 
        padding-right: 6px;
        bottom: 10px; 
        font-size: 16pt;
    }
    .smallitemtemplate .item-overlay .item-subtitle {
        display: none;
    }
    .groupeditemspage .mediumitemtemplate
    {
        width: 310px;
        height: 150px;
        -ms-grid-columns: 1fr;
        -ms-grid-rows: 1fr 60px;
        display: -ms-grid;
        overflow: hidden;
    }       
    .groupeditemspage .largeitemtemplate
    {
        width: 310px;
        height: 310px;
        overflow: hidden;
        -ms-grid-columns: 1fr;
        -ms-grid-rows: 1fr 90px;
        display: -ms-grid;
    }
    
    
    
  6. 다음 CSS 코드를 제거하여 스타일을 덮어쓰지 않도록 합니다.

    
    .groupeditemspage .groupeditemslistZoomOut .win-item {
        -ns-grid-columns: 1fr;
        -ms-grid-rows: 1fr 90px;
        display: -ms-grid;
        height: 250px;
        width: 250px;
    }
    
    

    참고  시맨틱 줌 섹션을 구현하지 않은 경우 파일에서 위의 CSS를 삭제하여 여러 크기 항목에 대해 방금 추가한 CSS를 재정의하지 않도록 합니다.

 

 

표시:
© 2014 Microsoft