일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 오류
- db
- JavaScript
- Flutter
- 플러터
- 자바스크립트
- 닷넷
- 깃허브
- 애니메이션
- 바인딩
- listview
- HTML
- 함수
- Animation
- 리엑트
- MS-SQL
- GitHub
- Firebase
- AnimationController
- React JS
- Maui
- .NET
- MSSQL
- 마우이
- Binding
- spring boot
- 파이어베이스
- page
- typescript
- MVVM
- Today
- Total
개발노트
19. [.NET MAUI] Shell 사용하여 다른 Page에 값 넘기기 (With CollectionView) 본문
19. [.NET MAUI] Shell 사용하여 다른 Page에 값 넘기기 (With CollectionView)
mroh1226 2022. 5. 30. 15:58이번 시간에는 Shell을 사용하여 CollectionView에 있는 데이터들을 검색하는 기능과 데이터를 클릭했을 때, 상세페이지로 넘어가는 기능을 구현해 보겠습니다.
CollectionView 및 ListView 차이점
- CollectionView 에는 데이터를 목록이나 그리드에서 세로 또는 가로로 표시할 수 있다.
- CollectionView 는 단일 및 다중 선택을 지원한다.
- CollectionView 에는 셀 개념이 없습니다. 대신 데이터 템플릿으로 목록에 있는 각 항목의 모양을 정의한다.
- CollectionView 기본 네이티브 컨트롤에서 제공하는 가상화를 자동으로 활용한다.
- CollectionView 의 API 표면을 줄인다. ListView. 의 많은 속성과 이벤트가 ListView 없다 CollectionView.
- CollectionView 에는 기본 제공 구분 기호가 포함되지 않습니다.
- CollectionView 는 UI 스레드에서 업데이트되는 경우 ItemsSource 예외를 throw합니다.
- 참고링크: https://docs.microsoft.com/ko-kr/dotnet/maui/user-interface/controls/collectionview/
Shell
.NET 다중 플랫폼 앱 UI(.NET MAUI) 셸은 다음을 포함하여 대부분의 앱에 필요한 기본 기능을 제공하여 앱 개발의 복잡성을 줄입니다.
- 앱의 시각적 계층 구조를 설명하는 단일 위치입니다.
- 일반적인 탐색 사용자 환경입니다.
- 앱의 모든 페이지에 대한 탐색을 허용하는 URI 기반 탐색 체계입니다.
- 통합된 검색 처리기입니다.
- 참조링크: https://docs.microsoft.com/ko-kr/dotnet/maui/fundamentals/shell/
1. Model로 사용할 Monkeys.cs를 아래와같이 작성해준다.
Monkeys.cs
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AppMaui.Models
{
public class Monkeys
{
[JsonProperty("Name")]
public string Name { get; set; }
[JsonProperty("Location")]
public string Location { get; set; }
[JsonProperty("Details")]
public string Details { get; set; }
[JsonProperty("Image")]
public string Image { get; set; }
[JsonProperty("Population")]
public string Population { get; set; }
[JsonProperty("Latitude")]
public string Latitude { get; set; }
[JsonProperty("Longitude")]
public string Longitude { get; set; }
}
}
2. AppShell.xaml 파일을 생성하고 아래와같이 마크업 소스를 작성한다.
AppShell.xaml
<?xml version="1.0" encoding="utf-8" ?>
<Shell xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="AppMaui.AppShell"
xmlns:local="clr-namespace:AppMaui"
xmlns:vm="clr-namespace:AppMaui.Views"
Shell.FlyoutBehavior="Disabled">
<ShellContent
Title="Home"
ContentTemplate="{DataTemplate local:MainPage}"/>
</Shell>
3. AppShell의 코드비하인드에 Routing.RegusterRoute로 연결할 페이지 이름을 추가한다.
AppShell.xaml.cs
using AppMaui.Views;
namespace AppMaui;
public partial class AppShell : Shell
{
public AppShell()
{
InitializeComponent();
Routing.RegisterRoute(nameof(MonkeyDetailsPage),typeof(MonkeyDetailsPage));
Routing.RegisterRoute(nameof(Page40), typeof(Page40));
}
}
4. App.xaml.cs(코드 비하인드)에 MainPage를 AppShell로 연결한다.
App.xaml.cs
namespace AppMaui;
public partial class App : Application
{
public App()
{
InitializeComponent();
MainPage = new AppShell();
//MainPage = new NavigationPage(new MainPage());
//MainPage = new NavigationPage(new TabPage());
}
}
5. View로 사용할 Page40을 아래와 같이 작성해준다.
6. <GestureRecognizers> 로 <TapGestureRecognizer> 태핑 제스처가 있을 때 이벤트를 발생시킨다.
(CommandParameter에 {Binding .} 을 줘서 Property 전체를 파라값으로 넘긴다.)
Page40.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="AppMaui.Views.Page40"
xmlns:vm="clr-namespace:AppMaui.ViewModels"
Title="Page40"
x:Name="page40">
<ContentPage.Resources>
<Style TargetType="Label">
<Setter Property="FontSize" Value="Medium"/>
<Setter Property="TextColor" Value="Gray"/>
</Style>
</ContentPage.Resources>
<Grid ColumnDefinitions="*,*" ColumnSpacing="5" RowDefinitions="*,Auto" RowSpacing="0">
<CollectionView Grid.Column="0" Grid.ColumnSpan="2" ItemsSource="{Binding Monkey}"
SelectionMode="Single">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Padding="10">
<Frame HeightRequest="125" Padding="0">
<Grid Padding="0" ColumnDefinitions="125,*">
<Grid.GestureRecognizers>
<TapGestureRecognizer Command="{Binding Source ={x:Reference page40},Path=BindingContext.GoToDetailsAsync}"
CommandParameter="{Binding .}"/>
</Grid.GestureRecognizers>
<Image Source="{Binding Image}" Aspect="AspectFill" WidthRequest="125" HeightRequest="125"/>
<VerticalStackLayout Grid.Column="1" Padding="10" VerticalOptions="CenterAndExpand">
<Label Text="{Binding Name}"/>
<Label Text="{Binding Location}"/>
</VerticalStackLayout>
</Grid>
</Frame>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</Grid>
</ContentPage>
7. View의 코드비하인드에 ViewModel 을 Binding 시켜준다.
Page40,xaml.cs
using AppMaui.ViewModels;
namespace AppMaui.Views;
public partial class Page40 : ContentPage
{
public Page40()
{
InitializeComponent();
BindingContext = new Page40_ViewModel(Navigation);
}
}
8. 받아온 CommandParameter 값을 obj로 받고 Monkeys 객체라는 것을 명시해준다.
9. Shell로 AppShell에 정의했던 라우팅 MonkeyDetailsPage를 연결시키고 Monkeys 값을 다음 Shell에 넘긴다.
Page40_ViewModel.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using AppMaui.Models;
using Newtonsoft.Json;
using System.Collections.ObjectModel;
using AppMaui.Services;
using AppMaui.Views;
namespace AppMaui.ViewModels
{
class Page40_ViewModel : Notify
{
public ICommand GoToDetailsAsync { get; set; }
private const string MonkeyURL = "https://montemagno.com/monkeys.json";
private readonly HttpClient httpClient = new HttpClient();
public ObservableCollection<Monkeys> _Monkeys { get; set; } = new ObservableCollection<Monkeys>();
public Page40_ViewModel()
{
}
public Page40_ViewModel(INavigation navigation)
{
GetMonkeys();
//obj를 CommandParameter로 받음({Binding .}으로 전체를 받음)
GoToDetailsAsync = new Command(async(obj) =>
{
Monkeys monkeys = (Monkeys)obj; //obj가 Monkeys Class라는 것을 명시해줌
if(monkeys != null)
{
//MonkeyDetailPage 로 Shell 이동, Animate 를 True로 줘서 넘어가는 모션을 줌
//Dictinary를 파라미터로 넘김 Dictionary< Key 이름, 데이터 값 >
await Shell.Current.GoToAsync($"{nameof(MonkeyDetailsPage)}",true,
new Dictionary<string, object>
{
{"Monkeys",monkeys }
});
}
},
(obj) =>
{
return true;
});
}
protected async void GetMonkeys()
{
var monkeyJson = await httpClient.GetStringAsync(MonkeyURL);
var monkeys = JsonConvert.DeserializeObject<Monkeys[]>(monkeyJson);
foreach(var Monkeys in monkeys)
{
Monkey.Add(Monkeys);
}
}
public ObservableCollection<Monkeys> Monkey
{
get => _Monkeys;
set
{
if(_Monkeys != value)
{
_Monkeys = value;
OnPropertyChanged("Monkey");
}
}
}
}
}
- 참조링크: https://docs.microsoft.com/ko-kr/dotnet/maui/fundamentals/shell/navigation
10. Page40의 다음 Shell인 MonkeyDetailsPage.xaml을 아래와 같이 작성한다.
11. StringFormat을 사용하여 값을 의미하는 {0}과 추가하고싶은 문자들을 같이 입력해준다.
MonkeyDetailsPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="AppMaui.Views.MonkeyDetailsPage"
Title="{Binding Monkeys.Name}">
<ContentPage.Resources>
<Style TargetType="Label">
<Setter Property="Padding" Value="20"/>
<Setter Property="TextColor" Value="Black"/>
</Style>
</ContentPage.Resources>
<ScrollView>
<VerticalStackLayout>
<Grid ColumnDefinitions="*,auto,*" RowDefinitions="160,Auto">
<BoxView Grid.ColumnSpan="3" HeightRequest="160" HorizontalOptions="FillAndExpand" BackgroundColor="Orange"/>
<Frame Grid.Row="0" Grid.RowSpan="2" Grid.Column="1" CornerRadius="90">
<Image Source="{Binding Monkeys.Image}" Aspect="AspectFill" Scale="1.4"/>
</Frame>
</Grid>
<VerticalStackLayout Padding="30">
<Label Text="{Binding Monkeys.Location, StringFormat= '1. 서식지: {0}'}"/>
<Label Text="{Binding Monkeys.Population, StringFormat= '2. 개체수: {0}'}"/>
<Label Text="{Binding Monkeys.Latitude, StringFormat= '3. 위도: {0}'}"/>
<Label Text="{Binding Monkeys.Longitude, StringFormat= '4. 경도: {0}'}"/>
<Label Text="{Binding Monkeys.Details, StringFormat= '{0}'}"/>
</VerticalStackLayout>
<Button Text="Page40으로 이동" Command="{Binding btn_Click}"/>
</VerticalStackLayout>
</ScrollView>
</ContentPage>
12. MonkeyDetailsPage 의 코드비하인드에 ViewModel을 바인딩 시킨다.
13. 네비게이트에 사용할 수 있는 생명주기 3개를 작성한다.
MonkeyDetailsPage.xaml.cs
using AppMaui.ViewModels;
namespace AppMaui.Views;
public partial class MonkeyDetailsPage : ContentPage
{
public MonkeyDetailsPage()
{
InitializeComponent();
BindingContext = new MonkeyDetails_ViewModel();
}
protected override void OnNavigatedTo(NavigatedToEventArgs args)
{
base.OnNavigatedTo(args);
Shell.Current.DisplayAlert("OnNavigatedTo 발생", args.ToString(), "OK");
}
protected override void OnNavigatedFrom(NavigatedFromEventArgs args)
{
base.OnNavigatedFrom(args);
Shell.Current.DisplayAlert("OnNavigatedFrom 발생", args.ToString(), "OK");
}
protected override void OnNavigatingFrom(NavigatingFromEventArgs args)
{
base.OnNavigatingFrom(args);
Shell.Current.DisplayAlert("OnNavigatingFrom 발생", args.ToString(), "OK");
}
}
- OnNavigatingTo is called when navigating ‘forward’ to a View(Model). It accepts a parameter of type object which allows us to pass a parameter from one ViewModel to another.
- OnNavigatedFrom is called when we navigate away from a View(Model). The parameter isForwardNavigation indicates if we’re navigating forward from this view to another (true), or if we navigate back from this view to the previous one (false). The later is particularly interesting to clean-up stuff as the page is no longer in the NavigationStack.
- OnNavigatedTo is called when we have navigated to a View(Model). This method is called when we navigate to a new View (forward navigation) AND also when we navigate back to a View (back navigation)
14. ViewModel에 QueryProperty를 이용하여 Page40에서 넘겨준 Monkeys 키를 Attribute로 정의한다.
15. Page40으로 돌아가는 버튼 Command를 작성한다.
MonkeyDetails_ViewModel.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AppMaui.Models;
using AppMaui.Views;
using AppMaui.Services;
using System.Collections.ObjectModel;
using System.Windows.Input;
namespace AppMaui.ViewModels
{
[QueryProperty("Monkeys", "Monkeys")]
class MonkeyDetails_ViewModel : Notify
{
public Monkeys _Monkeys { get; set; }
public ICommand btn_Click { get; set; }
public MonkeyDetails_ViewModel()
{
btn_Click = new Command (async() =>
{
await Shell.Current.GoToAsync($"../{nameof(Page40)}");
});
}
public Monkeys Monkeys
{
get => _Monkeys;
set
{
if(_Monkeys != value)
{
_Monkeys = value;
OnPropertyChanged("Monkeys");
}
}
}
}
}
'앱 개발 > .NET MAUI' 카테고리의 다른 글
21. [.NET MAUI] MAUI에 DevExpress 컨트롤 사용하기 (0) | 2022.08.10 |
---|---|
20. [.NET MAUI] SkiaSharp로 Lottie 사용하기(애니메이션 효과) (0) | 2022.07.26 |
18. [.NET MAUI] 트리거(Trigger) 사용하기 (0) | 2022.05.19 |
17. [.NET MAUI] Tabbed Page 만들기 (0) | 2022.04.27 |
16. [.NET MAUI] SecureStorage 사용하기(기기에 Key 값 저장) (0) | 2022.04.26 |