티스토리 뷰

반응형

엡에서 Page는 가상 키보드가 나올 때 자동으로 위로 살짝 올라가는데, 팝업은 자동으로 위치가 이동되지 않는다. 그래서, 팝업을 띄운 후 가상 키보드를 사용 할 때의 문제점을 해결하는 셈플을 만들어 보았다.

 

기본적인 팝업에서는 키보드를 띄우면 아래와 같이 입력 창이 가려져서 입력 작업을 할 수가 없다.

 

* 참고 포스트

Turn any UserControl into a pleasing Dialog/Flyout in Windows 8

http://socialeboladev.wordpress.com/2012/10/14/turn-any-usercontrol-into-a-pleasing-dialogflyout-in-windows-8/

 

1. 핵심

팝업을 출력한 후 팝업 내부에서 InputPane을 가지고 있다가, InputPane이 보이거나 숨길때 팝업의 위치라던가 크기를 변경 시켜야 한다.

 

 

2. ItemPage.xaml.cs

 

namespace InputPanelUsingPopupSample
{
    /// <summary>
    /// A page that displays a collection of item previews.  In the Split Application this page
    /// is used to display and select one of the available groups.
    /// </summary>
    public sealed partial class ItemsPage : InputPanelUsingPopupSample.Common.LayoutAwarePage
    {
        Popup normalPopup;

        public ItemsPage()
        {
            this.InitializeComponent();
        }

 

        protected override void LoadState(Object navigationParameter, Dictionary<String, Object> pageState)
        {
            // TODO: Create an appropriate data model for your problem domain to replace the sample data
            var sampleDataGroups = SampleDataSource.GetGroups((String)navigationParameter);
            this.DefaultViewModel["Items"] = sampleDataGroups;

            itemGridView.ItemClick += itemGridView_ItemClick;
        }

 

        void itemGridView_ItemClick(object sender, ItemClickEventArgs e)
        {
            var group = ((SampleDataGroup)e.ClickedItem);

            //현재 윈도우 바운드값
            var bounds = Windows.UI.Xaml.Window.Current.CoreWindow.Bounds;
            //팝업 생성
            normalPopup = new Popup();
            //내용 생성
            var content = new InputPopupUserControl();
            //선택된 아이템을 내용의 DataContext에 넣어서 표시
            content.DataContext = group;
            //내용의 전체 크기 변경 - 전체 화면을 덮도록
            content.Width = bounds.Width;
            content.Height = bounds.Height;
            //팝업의 차일드로 내용 추가
            normalPopup.Child = content;
            //팝업을 내용에 추가 - 나중에 팝업을 닫기 위해 사용
            content.Parent = normalPopup;
            //팝업 오픈
            normalPopup.IsOpen = true;

        }

 

        protected override void SaveState(Dictionary<string, object> pageState)
        {
            itemGridView.ItemClick -= itemGridView_ItemClick;
        }
    }
}

 

 

3. InputPopupUserControl.xaml.cs

 

namespace InputPanelUsingPopupSample
{
    public sealed partial class InputPopupUserControl : UserControl
    {
        public Popup Parent { get; set; }
        /// <summary>
        /// 가상 키보드 패널
        /// </summary>
        private Windows.UI.ViewManagement.InputPane popupInputPane;

 

        public InputPopupUserControl()
        {
            this.InitializeComponent();

            if (Windows.ApplicationModel.DesignMode.DesignModeEnabled == true)
            {
                //디자인타임소스
                var sampleDataGroup = SampleDataSource.GetGroup("01");
                this.DataContext = sampleDataGroup;
            }
            else
            {
                //런타임소스
                this.btnOK.Click += (s, e) =>
                {
                    Parent.IsOpen = false;
                };
                this.btnCancel.Click += (s, e) =>
                {
                    Parent.IsOpen = false;
                };

 

                //가상키보드 처리
                popupInputPane = Windows.UI.ViewManagement.InputPane.GetForCurrentView();
                popupInputPane.Showing += popupInputPane_ShowHide;
                popupInputPane.Hiding += popupInputPane_ShowHide;

 

                //윈도우 리사이즈
                Window.Current.SizeChanged += Current_SizeChanged;

            }
        }

        void Current_SizeChanged(object sender, Windows.UI.Core.WindowSizeChangedEventArgs e)
        {
            //노말에서 스냅 뷰 모드로 변경되거나 반대의 경우에도 각각 팝업의 크기 및 위치 조정이 필요할 수 있다.
        }

 

        void popupInputPane_ShowHide(Windows.UI.ViewManagement.InputPane sender, Windows.UI.ViewManagement.InputPaneVisibilityEventArgs args)
        {
            //인풋패널 크기
            var inputPanelRect = args.OccludedRect;
            //윈도우 크기
            Rect rect = Window.Current.CoreWindow.Bounds;
            if (inputPanelRect.Top == 0)
            {
                rect.Y = inputPanelRect.Bottom;
            }
            rect.Height -= inputPanelRect.Height;

            //키보드 뜰때 세로만 변경
            //1. 팝업의 세로 오프셋을 변경하는 방법
            //Parent.VerticalOffset = rect.Top - inputPanelRect.Height;
            //2. 그리드의 높이를 변경하는 방법
            //popupRoot.Height = rect.Height;
            //3. UserControl자체의 높이를 변경하는 방법
            this.Height = rect.Height;
            //등등 여러가지를 적용해서 제일 알맞는 방법을 사용한다.
        }

    }
}

 

4. 완료 화면

 

가상 키보드가 나타나면 팝업이 살짝 위로 올라간다.

 

5. 소스

 

InputPanelUsingPopupSample.zip

반응형
댓글