첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
본 블로그는 광고를 포함하고 있습니다.
광고 클릭에서 발생하는 수익금은 모두 블로그 콘텐츠 향상을 위해 쓰여집니다.

728x90
반응형
728x170

TestProject.zip
0.03MB

▶ Person.cs

using System.ComponentModel;
using System.Runtime.CompilerServices;
using Windows.UI.Xaml.Media;

namespace TestProject
{
    /// <summary>
    /// 사람
    /// </summary>
    public class Person : INotifyPropertyChanged
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Event
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 속성 변경시 이벤트 - PropertyChanged

        /// <summary>
        /// 속성 변경시 이벤트
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// ID
        /// </summary>
        public int id;

        /// <summary>
        /// 성명
        /// </summary>
        public string name;

        /// <summary>
        /// 나이
        /// </summary>
        public int age;

        /// <summary>
        /// 브러시
        /// </summary>
        public Brush brush;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region ID - ID

        /// <summary>
        /// ID
        /// </summary>
        public int ID
        {
            get => this.id;
            set
            {
                if(this.id != value)
                {
                    this.id = value;

                    FirePropertyChangedEvent();
                }
            }
        }

        #endregion
        #region 성명 - Name

        /// <summary>
        /// 성명
        /// </summary>
        public string Name
        {
            get => this.name;
            set
            {
                if(this.name != value)
                {
                    this.name = value;

                    FirePropertyChangedEvent();
                }
            }
        }

        #endregion
        #region 나이 - Age

        /// <summary>
        /// 나이
        /// </summary>
        public int Age
        {
            get => this.age;
            set
            {
                if(this.age != value)
                {
                    this.age = value;

                    FirePropertyChangedEvent();
                }
            }
        }

        #endregion
        #region 브러시 - Brush

        /// <summary>
        /// 브러시
        /// </summary>
        public Brush Brush
        {
            get => this.brush;
            set
            {
                if(this.brush != value)
                {
                    this.brush = value;

                    FirePropertyChangedEvent();
                }
            }
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - Person(id, name, age, brush)

        /// <summary>
        /// 생성자
        /// </summary>
        /// <param name="id">ID</param>
        /// <param name="name">성명</param>
        /// <param name="age">나이</param>
        /// <param name="brush">브러시</param>
        public Person(int id, string name, int age, Brush brush)
        {
            this.id    = id;
            this.name  = name;
            this.age   = age;
            this.brush = brush;
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Protected

        #region 속성 변경시 이벤트 발생시키기 - FirePropertyChangedEvent(propertyName)

        /// <summary>
        /// 속성 변경시 이벤트 발생시키기
        /// </summary>
        /// <param name="propertyName">속성명</param>
        protected void FirePropertyChangedEvent([CallerMemberName] string propertyName = null) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));

        #endregion
    }
}

 

▶ App.xaml

<Application x:Class="TestProject.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
</Application>

 

▶ App.xaml.cs

using System;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;
using Windows.Foundation;
using Windows.Graphics.Display;
using Windows.UI.Core;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;

namespace TestProject
{
    /// <summary>
    /// 앱
    /// </summary>
    sealed partial class App : Application
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - App()

        /// <summary>
        /// 생성자
        /// </summary>
        public App()
        {
            InitializeComponent();

            Suspending += Application_Suspending;
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Protected

        #region 시작시 처리하기 - OnLaunched(e)

        /// <summary>
        /// 시작시 처리하기
        /// </summary>
        /// <param name="e">이벤트 인자</param>
        protected override void OnLaunched(LaunchActivatedEventArgs e)
        {
            SystemNavigationManager.GetForCurrentView().BackRequested += SystemNavigationManager_BackRequested;

            Frame rootFrame = Window.Current.Content as Frame;

            if(rootFrame == null)
            {
                rootFrame = new Frame();

                rootFrame.NavigationFailed += rootFrame_NavigationFailed;

                if(e.PreviousExecutionState == ApplicationExecutionState.Terminated)
                {
                }

                Window.Current.Content = rootFrame;
            }

            if(e.PrelaunchActivated == false)
            {
                if(rootFrame.Content == null)
                {
                    rootFrame.Navigate(typeof(MainPage), e.Arguments);
                }

                Window.Current.Activate();
            }

            #region 윈도우 크기를 설정한다.

            double width  = 800d;
            double height = 600d;

            double dpi = (double)DisplayInformation.GetForCurrentView().LogicalDpi;

            ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.PreferredLaunchViewSize;

            Size windowSize = new Size(width * 96d / dpi, height * 96d / dpi);

            ApplicationView.PreferredLaunchViewSize = windowSize;

            Window.Current.Activate();

            ApplicationView.GetForCurrentView().TryResizeView(windowSize);

            #endregion
        }

        #endregion

        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region 애플리케이션 정지시 처리하기 - Application_Suspending(sender, e)

        /// <summary>
        /// 애플리케이션 정지시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void Application_Suspending(object sender, SuspendingEventArgs e)
        {
            SuspendingDeferral deferral = e.SuspendingOperation.GetDeferral();

            deferral.Complete();
        }

        #endregion
        #region 시스템 탐색 관리자 뒤로 이동 요청시 처리하기 - SystemNavigationManager_BackRequested(sender, e)

        /// <summary>
        /// 시스템 탐색 관리자 뒤로 이동 요청시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void SystemNavigationManager_BackRequested(object sender, BackRequestedEventArgs e)
        {
            Frame rootFrame = Window.Current.Content as Frame;

            if(rootFrame == null)
            {
                return;
            }

            if(rootFrame.CanGoBack && e.Handled == false)
            {
                e.Handled = true;

                rootFrame.GoBack();
            }
        }

        #endregion
        #region 루트 프레임 네비게이션 실패시 처리하기 - rootFrame_NavigationFailed(sender, e)

        /// <summary>
        /// 루트 프레임 네비게이션 실패시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void rootFrame_NavigationFailed(object sender, NavigationFailedEventArgs e)
        {
            throw new Exception($"페이지 로드를 실패했습니다 : {e.SourcePageType.FullName}");
        }

        #endregion
    }
}

 

▶ MainPage.xaml

<Page x:Class="TestProject.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:TestProject"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
    NavigationCacheMode="Enabled"
    FontFamily="나눔고딕코딩"
    FontSize="16">
    <Page.Resources>
        <ItemsPanelTemplate x:Key="GridViewItemsPanelTemplateKey">
            <ItemsWrapGrid
                HorizontalAlignment="Center"
                Orientation="Horizontal" />
        </ItemsPanelTemplate>
        <DataTemplate x:Key="GridViewDataTemplateKey" x:DataType="local:Person">
            <Grid Name="personGrid"
                Margin="10"
                Height="100"
                Width="100"
                Background="{x:Bind Brush}">
                <StackPanel
                    HorizontalAlignment="Center"
                    VerticalAlignment="Center">
                    <TextBlock
                        HorizontalAlignment="Center"
                        Text="{x:Bind ID}" />
                    <TextBlock
                        HorizontalAlignment="Center"
                        Text="{x:Bind Name}" />
                    <TextBlock
                        HorizontalAlignment="Center"
                        Text="{x:Bind Age}"  />
                </StackPanel>
            </Grid>
        </DataTemplate>
        <Style x:Key="GridViewDefaultItemContainerStyleKey" TargetType="GridViewItem">
            <Setter Property="Margin"     Value="10"        />
            <Setter Property="Background" Value="LightGray" />
        </Style>
    </Page.Resources>
    <Grid>
        <GridView Name="gridView"
            ItemsPanel="{StaticResource GridViewItemsPanelTemplateKey}"
            ItemTemplate="{StaticResource GridViewDataTemplateKey}"
            ItemContainerStyle="{StaticResource GridViewDefaultItemContainerStyleKey}"
            IsItemClickEnabled="True"
            ItemsSource="{x:Bind PersonCollection}"
            Loaded="{x:Bind gridView_Loaded}"
            ItemClick="gridView_ItemClick" />
    </Grid>
</Page>

 

▶ MainPage.xaml.cs

using Microsoft.Toolkit.Uwp.UI.Animations;
using System;
using System.Collections.ObjectModel;
using Windows.UI;
using Windows.UI.Core;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Animation;
using Windows.UI.Xaml.Navigation;

namespace TestProject
{
    /// <summary>
    /// 메인 페이지
    /// </summary>
    public sealed partial class MainPage : Page
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 현재 사람
        /// </summary>
        private Person currentPerson;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 사람 컬렉션 - PersonCollection

        /// <summary>
        /// 사람 컬렉션
        /// </summary>
        public ObservableCollection<Person> PersonCollection { get; } = new ObservableCollection<Person>();

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - MainPage()

        /// <summary>
        /// 생성자
        /// </summary>
        public MainPage()
        {
            InitializeComponent();

            ItemsReorderAnimation.SetDuration(this.gridView, TimeSpan.FromMilliseconds(400));
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Protected

        #region 탐색되는 경우 처리하기 - OnNavigatedTo(e)

        /// <summary>
        /// 탐색되는 경우 처리하기
        /// </summary>
        /// <param name="e">이벤트 인자</param>
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility = AppViewBackButtonVisibility.Collapsed;

            if(PersonCollection.Count == 0)
            {
                AddPersion(100);
            }

            base.OnNavigatedTo(e);
        }

        #endregion

        ////////////////////////////////////////////////////////////////////////////////////////// Private
        //////////////////////////////////////////////////////////////////////////////// Event

        #region 그리드 뷰 로드시 처리하기 - gridView_Loaded()

        /// <summary>
        /// 그리드 뷰 로드시 처리하기
        /// </summary>
        private async void gridView_Loaded()
        {
            if(this.currentPerson != null)
            {
                this.gridView.ScrollIntoView(this.currentPerson);

                ConnectedAnimation animation = ConnectedAnimationService.GetForCurrentView().GetAnimation("backAnimation");

                if(animation != null)
                {
                    await this.gridView.TryStartConnectedAnimationAsync(animation, this.currentPerson, "personGrid");
                }
            }
        }

        #endregion
        #region 그리드 뷰 항목 클릭시 처리하기 - gridView_ItemClick(sender, e)

        /// <summary>
        /// 그리드 뷰 항목 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void gridView_ItemClick(object sender, ItemClickEventArgs e)
        {
            this.currentPerson = e.ClickedItem as Person;

            this.gridView.PrepareConnectedAnimation("itemAnimation", e.ClickedItem, "personGrid");

            Frame.Navigate(typeof(DetailPage), e.ClickedItem);
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////// Function

        #region 사람 추가하기 - AddPersion(count)

        /// <summary>
        /// 사람 추가하기
        /// </summary>
        /// <param name="count">카운트</param>
        private void AddPersion(int count)
        {
            Random random = new Random();

            for(int i = 0; i < count; i++)
            {
                Color color = Color.FromArgb
                (
                    128,
                    (byte)random.Next(0, 255),
                    (byte)random.Next(0, 255),
                    (byte)random.Next(0, 255)
                );

                Person person = new Person
                (
                    i + 1,
                    $"사람 {i + 1}",
                    random.Next(0, 100),
                    new SolidColorBrush(color)
                );

                PersonCollection.Add(person);
            }
        }

        #endregion
    }
}

 

▶ DetailPage.xaml

<Page x:Class="TestProject.DetailPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    RequestedTheme="Dark">
    <Grid>
        <RelativePanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
            <Grid Name="personGrid"
                RelativePanel.AlignHorizontalCenterWithPanel="True"
                RelativePanel.AlignVerticalCenterWithPanel="True"
                Height="300"
                Width="300"
                Background="{x:Bind person.Brush}">
                <StackPanel
                    HorizontalAlignment="Center"
                    VerticalAlignment="Center">
                    <TextBlock
                        HorizontalAlignment="Center"
                        Text="{x:Bind person.ID}" />
                    <TextBlock
                        HorizontalAlignment="Center"
                        Text="{x:Bind person.Name}" />
                    <TextBlock
                        HorizontalAlignment="Center"
                        Text="{x:Bind person.Age}"  />
                </StackPanel>
            </Grid>
        </RelativePanel>
    </Grid>
</Page>

 

▶ DetailPage.xaml.cs

using Windows.UI.Core;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media.Animation;
using Windows.UI.Xaml.Navigation;

namespace TestProject
{
    /// <summary>
    /// 상세 페이지
    /// </summary>
    public sealed partial class DetailPage : Page
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 사람
        /// </summary>
        private Person person;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - DetailPage()

        /// <summary>
        /// 생성자
        /// </summary>
        public DetailPage()
        {
            InitializeComponent();
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Protected

        #region 탐색되는 경우 처리하기 - OnNavigatedTo(e)

        /// <summary>
        /// 탐색되는 경우 처리하기
        /// </summary>
        /// <param name="e">이벤트 인자</param>
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            this.person = e.Parameter as Person;

            if(this.person != null)
            {
                ConnectedAnimation animation = ConnectedAnimationService.GetForCurrentView().GetAnimation("itemAnimation");

                if(animation != null)
                {
                    animation.TryStart(this.personGrid);
                }
            }

            if(Frame.CanGoBack)
            {
                SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility = AppViewBackButtonVisibility.Visible;
            }
            else
            {
                SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility = AppViewBackButtonVisibility.Collapsed;
            }

            base.OnNavigatedTo(e);
        }

        #endregion
        #region 탐색하는 경우 처리하기 - OnNavigatingFrom(e)

        /// <summary>
        /// 탐색하는 경우 처리하기
        /// </summary>
        /// <param name="e">이벤트 인자</param>
        protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
        {
            if(e.NavigationMode == NavigationMode.Back)
            {
                ConnectedAnimationService.GetForCurrentView().PrepareToAnimate("backAnimation", this.personGrid);
            }

            base.OnNavigatingFrom(e);
        }

        #endregion
    }
}
728x90
반응형
그리드형
Posted by 사용자 icodebroker

댓글을 달아 주세요