첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
728x90
반응형
728x170

TestProject.zip
0.16MB

▶ VIEWMODEL/BaseViewModel.cs

using CommunityToolkit.Mvvm.ComponentModel;

namespace TestProject;

/// <summary>
/// 베이스 뷰 모델
/// </summary>
[INotifyPropertyChanged]
public abstract partial class BaseViewModel
{
}

 

300x250

 

▶ VIEWMODEL/MainPageViewModel.cs

using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;

namespace TestProject
{
    /// <summary>
    /// 메인 페이지 뷰 모델
    /// </summary>
    public partial class MainPageViewModel : BaseViewModel
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 입력 텍스트
        /// </summary>
        [ObservableProperty]
        private string inputText = null;

        #endregion

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

        #region 생성자 - MainPageViewModel()

        /// <summary>
        /// 생성자
        /// </summary>
        public MainPageViewModel()
        {
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region 초기화하기 - Reset()

        /// <summary>
        /// 초기화하기
        /// </summary>
        [RelayCommand]
        private void Reset()
        {
            InputText = string.Empty;
        }

        #endregion
        #region 상세 페이지로 이동하기 - MoveDetailPage()

        /// <summary>
        /// 상세 페이지로 이동하기
        /// </summary>
        [RelayCommand]
        private async Task MoveDetailPage()
        {
            await Shell.Current.GoToAsync("//메인페이지/메인상세페이지");
        }

        #endregion
    }
}

 

728x90

 

▶ VIEWMODEL/MainDetailPageViewMode.cs

using CommunityToolkit.Mvvm.Input;

namespace TestProject
{
    /// <summary>
    /// 메인 상세 페이지 뷰 모델
    /// </summary>
    public partial class MainDetailPageViewModel : BaseViewModel
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - MainDetailPageViewModel()

        /// <summary>
        /// 생성자
        /// </summary>
        public MainDetailPageViewModel()
        {
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region 부모 페이지로 이동하기 - MoveParentPage()

        /// <summary>
        /// 부모 페이지로 이동하기
        /// </summary>
        [RelayCommand]
        private async Task MoveParentPage()
        {
            await Shell.Current.GoToAsync("..");
        }

        #endregion
    }
}

 

반응형

 

▶ VIEWMODEL/SecondPageViewModel.cs

using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;

namespace TestProject
{
    /// <summary>
    /// 두번째 페이지 뷰 모델
    /// </summary>
    public partial class SecondPageViewModel : BaseViewModel
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 입력 텍스트
        /// </summary>
        [ObservableProperty]
        private string inputText = null;

        #endregion

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

        #region 생성자 - SecondPageViewModel()

        /// <summary>
        /// 생성자
        /// </summary>
        public SecondPageViewModel()
        {
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region 초기화하기 - Reset()

        /// <summary>
        /// 초기화하기
        /// </summary>
        [RelayCommand]
        private void Reset()
        {
            InputText = string.Empty;
        }

        #endregion
    }
}

 

▶ VIEW/BasePage.cs

namespace TestProject;

/// <summary>
/// 베이스 페이지
/// </summary>
public abstract class BasePage : ContentPage
{
    //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
    ////////////////////////////////////////////////////////////////////////////////////////// Protected

    #region 생성자 - BasePage(viewModel)

    /// <summary>
    /// 생성자
    /// </summary>
    /// <param name="viewModel">뷰 모델</param>
    protected BasePage(object viewModel = null)
    {
        BindingContext = viewModel;

        if(string.IsNullOrWhiteSpace(Title))
        {
            Title = GetType().Name;
        }
    }

    #endregion

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

    #region 페이지가 나타나는 경우 처리하기 - OnAppearing()

    /// <summary>
    /// 페이지가 나타나는 경우 처리하기
    /// </summary>
    protected override void OnAppearing()
    {
        base.OnAppearing();

        // 추후 기능을 추가한다.
    }

    #endregion
    #region 페이지가 사라지는 경우 처리하기 - OnDisappearing()

    /// <summary>
    /// 페이지가 사라지는 경우 처리하기
    /// </summary>
    protected override void OnDisappearing()
    {
        base.OnDisappearing();

        // 추후 기능을 추가한다.
    }

    #endregion
}

/// <summary>
/// 베이스 페이지
/// </summary>
/// <typeparam name="TViewModel">뷰 모델 타입</typeparam>
public abstract class BasePage<TViewModel> : BasePage where TViewModel : BaseViewModel
{
    //////////////////////////////////////////////////////////////////////////////////////////////////// Property
    ////////////////////////////////////////////////////////////////////////////////////////// Public

    #region 바인딩 컨텍스트 - BindingContext

    /// <summary>
    /// 바인딩 컨텍스트
    /// </summary>
    public new TViewModel BindingContext => (TViewModel)base.BindingContext;

    #endregion

    //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
    ////////////////////////////////////////////////////////////////////////////////////////// Protected

    #region 생성자 - BasePage(viewModel)

    /// <summary>
    /// 생성자
    /// </summary>
    /// <param name="viewModel">뷰 모델</param>
    protected BasePage(TViewModel viewModel) : base(viewModel)
    {
    }

    #endregion
}

 

▶ VIEW/MainPage.xaml

<?xml version="1.0" encoding="utf-8" ?>
<local:BasePage x:Class="TestProject.MainPage"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:local="clr-namespace:TestProject"
    x:TypeArguments="local:MainPageViewModel"
    Title="메인 페이지">
    <VerticalStackLayout 
        HorizontalOptions="Center"
        VerticalOptions="Center"
        Spacing="10">
        <Entry
            HorizontalOptions="Center"
            Placeholder="텍스트를 입력해 주시기 바랍니다."
            FontSize="16"
            Text="{Binding InputText}" />
        <Button
            HorizontalOptions="Center"
            Text="초기화"
            Command="{Binding ResetCommand}" />
        <Button
            HorizontalOptions="Center"
            Text="상세 페이지 이동하기"
            Command="{Binding MoveDetailPageCommand}" />
    </VerticalStackLayout>
</local:BasePage>

 

▶ VIEW/MainPage.xaml.cs

namespace TestProject;

/// <summary>
/// 메인 페이지
/// </summary>
public partial class MainPage : BasePage<MainPageViewModel>
{
    //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
    ////////////////////////////////////////////////////////////////////////////////////////// Public

    #region 생성자 - MainPage()

    /// <summary>
    /// 생성자
    /// </summary>
    public MainPage(MainPageViewModel viewModel) : base(viewModel)
    {
        InitializeComponent();
    }

    #endregion
}

 

▶ VIEW/MainDetailPage.xaml

<?xml version="1.0" encoding="utf-8" ?>
<local:BasePage x:Class="TestProject.MainDetailPage"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:local="clr-namespace:TestProject"
    x:TypeArguments="local:MainDetailPageViewModel"
    Title="메인 상세 페이지">
    <VerticalStackLayout 
        HorizontalOptions="Center"
        VerticalOptions="Center"
        Spacing="10">
        <Label
            HorizontalOptions="Center"
            FontSize="24"
            Text="메인 상세 페이지" />
        <Button
            HorizontalOptions="Center"
            Text="부모 페이지로 이동하기"
            Command="{Binding MoveParentPageCommand}" />
    </VerticalStackLayout>
</local:BasePage>

 

▶ VIEW/MainDetailPage.xaml.cs

namespace TestProject;

/// <summary>
/// 메인 상세 페이지
/// </summary>
public partial class MainDetailPage : BasePage<MainDetailPageViewModel>
{
    //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
    ////////////////////////////////////////////////////////////////////////////////////////// Public

    #region 생성자 - MainPage()

    /// <summary>
    /// 생성자
    /// </summary>
    public MainDetailPage(MainDetailPageViewModel viewModel) : base(viewModel)
    {
        InitializeComponent();
    }

    #endregion
}

 

▶ VIEW/SecondPage.xaml

<?xml version="1.0" encoding="utf-8" ?>
<local:BasePage x:Class="TestProject.SecondPage"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:local="clr-namespace:TestProject"
    x:TypeArguments="local:SecondPageViewModel"
    Title="두번째 페이지">
    <VerticalStackLayout 
        HorizontalOptions="Center"
        VerticalOptions="Center"
        Spacing="10">
        <Entry
            HorizontalOptions="Center"
            Placeholder="텍스트를 입력해 주시기 바랍니다."
            FontSize="16"
            Text="{Binding InputText}" />
        <Button
            HorizontalOptions="Center"
            Text="초기화"
            Command="{Binding ResetCommand}" />
    </VerticalStackLayout>
</local:BasePage>

 

▶ VIEW/SecondPage.xaml.cs

namespace TestProject;

/// <summary>
/// 두번째 페이지
/// </summary>
public partial class SecondPage : BasePage<SecondPageViewModel>
{
    //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
    ////////////////////////////////////////////////////////////////////////////////////////// Public

    #region 생성자 - SecondPage()

    /// <summary>
    /// 생성자
    /// </summary>
    public SecondPage(SecondPageViewModel viewModel) : base(viewModel)
    {
        InitializeComponent();
    }

    #endregion
}

 

▶ AppShell.xaml

<?xml version="1.0" encoding="UTF-8" ?>
<Shell x:Class="TestProject.AppShell"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:local="clr-namespace:TestProject">
    <FlyoutItem
        Title="메인 페이지"
        Route="메인페이지">
        <ShellContent ContentTemplate="{DataTemplate local:MainPage}" />
    </FlyoutItem>
    <FlyoutItem
        Title="두번째 페이지"
        Route="두번째페이지">
        <ShellContent ContentTemplate="{DataTemplate local:SecondPage}" />
    </FlyoutItem>
</Shell>

 

▶ AppShell.xaml.cs

namespace TestProject;

/// <summary>
/// 앱 셸
/// </summary>
public partial class AppShell : Shell
{
    //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
    ////////////////////////////////////////////////////////////////////////////////////////// Public

    #region 생성자 - AppShell()

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

        Routing.RegisterRoute("메인페이지/메인상세페이지", typeof(MainDetailPage));
    }

    #endregion
}

 

▶ MauiProgram.cs

using CommunityToolkit.Maui;

namespace TestProject;

/// <summary>
/// MAUI 프로그램
/// </summary>
public static class MauiProgram
{
    //////////////////////////////////////////////////////////////////////////////////////////////////// Method
    ////////////////////////////////////////////////////////////////////////////////////////// Static
    //////////////////////////////////////////////////////////////////////////////// Public

    #region MAUI 앱 생성하기 - CreateMauiApp()

    /// <summary>
    /// MAUI 앱 생성하기
    /// </summary>
    /// <returns>MAUI 앱</returns>
    public static MauiApp CreateMauiApp()
    {
        MauiAppBuilder builder = MauiApp.CreateBuilder();

        builder
            .UseMauiApp<App>()
            .UseMauiCommunityToolkit()
            .ConfigureFonts
            (
                fontCollection =>
                {
                    fontCollection.AddFont("OpenSans-Regular.ttf" , "OpenSansRegular" );
                    fontCollection.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
                }
            );

        builder.Services.AddTransient<MainPage      , MainPageViewModel      >();
        builder.Services.AddTransient<MainDetailPage, MainDetailPageViewModel>();
        builder.Services.AddTransient<SecondPage    , SecondPageViewModel    >();

        return builder.Build();
    }

    #endregion
}
728x90
반응형
그리드형(광고전용)
Posted by icodebroker

댓글을 달아 주세요