개발노트

29. [.NET MAUI] CarouselView의 Item이 변경될 때 Command 및 Parameter 받기 본문

앱 개발/.NET MAUI

29. [.NET MAUI] CarouselView의 Item이 변경될 때 Command 및 Parameter 받기

mroh1226 2022. 11. 29. 11:58
반응형

CarouselView의 Item이 변경될 때 다른 컨트롤의 값이나 구성이 변경되는 기능이 필요할 때가 있다.

 

이 기능을 MVVM으로 작성하려면 다음과 같이 하면된다.

-  참고링크: https://learn.microsoft.com/en-us/dotnet/maui/user-interface/controls/carouselview/interaction?view=net-maui-7.0 

 

Configure CarouselView interaction - .NET MAUI

The currently displayed item in a .NET MAUI CarouselView can be accessed through the CurrentItem and Position properties.

learn.microsoft.com

 

예제로 CarouselView에 등록된 ItemSource가 변경될 때 CollectionView의 ItemSorce이 변경되는 화면을 만들어본다. 

 


1. ItemSource의 Model로 사용할 Plans, PlanItem 객체를 작성해준다.

Plans.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyMAUI.Models
{
    public class Plans
    {
        public string Title { get; set; }
        public string Thema { get; set; }
        public Plans(string _Title,string _Thema)
        {
            Title = _Title;
            Thema = _Thema;
        }
    }

    public class PlanItem
    {
        public string Title { get; set; }
        public string SubTitle { get; set; }
        public string Img_Path { get; set;}
        public string Description {  get; set; }
        public PlanItem(string _Title, string _SubTitle, string _Img_Path, string _Description)
        {
            Title = _Title;
            SubTitle = _SubTitle;
            Img_Path = _Img_Path;
            Description = _Description;
        }
    }
}

2. ViewModel로 사용할 PlanVM.cs를 작성한다.
(선택된 Plans의 Title에 따라서 PlanItem 의 ItemSource가 추가될 수 있도록 Command를 작성해준다.)

 

*CurrentItemChangedCommand 에 Binding된 cmd_ChangeItem는 생성자 안에 선언해줘야 동작했다.
생성자 밖에 선언해주면 돌아가지않았다.

PlanVM.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using System.Collections.ObjectModel;
using static MyMAUI.Models.Plans;
using Plugin.Maui.Audio;
using MyMAUI.Models;
using MyMAUI.Services;

namespace MyMAUI.ViewModels
{
    class PlanVM : Notify
    {
        
        public ICommand cmd_Share => new Command<string>(p=>SharePlan(p));
        public ICommand cmd_ChangeItem {get;set;}
        public IAudioManager audioManager { get; set; }
        public IAudioPlayer audioPlayer { get; set; }
        public ObservableCollection<Plans> _plans = new ObservableCollection<Plans>();
        public ObservableCollection<Plans> plans
        {
            get=> _plans;
            set
            {
                if(_plans != value)
                {
                    _plans = value;
                    OnPropertyChanged($"{nameof(plans)}");
                }
            }
        }
        public ObservableCollection<PlanItem> _planItems = new ObservableCollection<PlanItem>();
        public ObservableCollection<PlanItem> planItems
        {
            get => _planItems;
            set
            {
                if(_planItems != value)
                {
                    _planItems = value;
                    OnPropertyChanged($"{nameof(planItems)}");
                }
            }
        }
        public string _SelectedItem { get; set; }
        public string SelectedItem
        {
            get=> _SelectedItem;
            set
            {
                if(_SelectedItem != value)
                {
                    _SelectedItem = value;
                    OnPropertyChanged($"{nameof(SelectedItem)}");
                }
            }
        }
        public PlanVM()
        {
            AddPlan();
            PlaySound();

            cmd_ChangeItem = new Command((plans) =>
            {
                Plans plan = (Plans)plans;
                SetPlanItem(plan);

            });

        }

        

        public void AddPlan()
        {
            plans.Add(new Plans("태안", "바다"));
            plans.Add(new Plans("강화도", "바다"));
            plans.Add(new Plans("영국", "해외"));
        }

        public void SetPlanItem(Plans plan)
        {
            planItems.Clear();
            if (plan == null) return;
            switch (plan.Title)
            {
                case "태안":
                    planItems.Add(new PlanItem("태안", "SubTitle1", "Img_Path1", "Description1"));
                    planItems.Add(new PlanItem("태안", "SubTitle2", "Img_Path2", "Description2"));
                    planItems.Add(new PlanItem("태안", "SubTitle3", "Img_Path3", "Description3"));
                    planItems.Add(new PlanItem("태안", "SubTitle4", "Img_Path4", "Description4"));
                    planItems.Add(new PlanItem("태안", "SubTitle1", "Img_Path1", "Description1"));
                    break;
                case "강화도":
                    planItems.Add(new PlanItem("강화도", "SubTitle2", "Img_Path2", "Description2"));
                    planItems.Add(new PlanItem("강화도", "SubTitle3", "Img_Path3", "Description3"));
                    planItems.Add(new PlanItem("강화도", "SubTitle4", "Img_Path4", "Description4"));
                    planItems.Add(new PlanItem("강화도", "SubTitle1", "Img_Path1", "Description1"));
                    planItems.Add(new PlanItem("강화도", "SubTitle2", "Img_Path2", "Description2"));
                    planItems.Add(new PlanItem("강화도", "SubTitle3", "Img_Path3", "Description3"));
                    break;
                case "영국":
                    planItems.Add(new PlanItem("영국", "SubTitle4", "Img_Path4", "Description4"));
                    planItems.Add(new PlanItem("영국", "SubTitle1", "Img_Path1", "Description1"));
                    planItems.Add(new PlanItem("영국", "SubTitle2", "Img_Path2", "Description2"));
                    planItems.Add(new PlanItem("영국", "SubTitle3", "Img_Path3", "Description3"));
                    planItems.Add(new PlanItem("영국", "SubTitle4", "Img_Path4", "Description4"));
                    break;
            }
        }

        public async void PlaySound()
        {
            this.audioManager = new AudioManager();
            audioPlayer = audioManager.CreatePlayer(await FileSystem.OpenAppPackageFileAsync("fly_sound.mp3"));
            audioPlayer.Play();

        }

        public async void SharePlan(string Title)
        {
            await Share.Default.RequestAsync(new ShareTextRequest(Title + " 여기어때"));    //Text 공유하기
        }
    }
}

 

 


3. View로 사용될 PlanPage.xaml을 아래와 같이 작성해준다.

- CurrentItem : 변경된 Item을 가져온다.

- CurrentItemChangedCommand : Item 변경 시, 동작할 Command를 바인딩한다.

- CurrentItemChangedCommandParameter : Item 변경 시, 넘겨줄 Parameter를 바인딩한다.

PlanPage.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"
             xmlns:skia="clr-namespace:SkiaSharp.Extended.UI.Controls;assembly=SkiaSharp.Extended.UI"
             xmlns:vm="clr-namespace:MyMAUI.ViewModels"
             x:Class="MyMAUI.Views.PlanPage"
             Title="PlanPage">
    <ContentPage.Resources>
        <vm:PlanVM x:Key="planvm"/>
    </ContentPage.Resources>
    <Grid RowDefinitions="*" ColumnDefinitions="*">
        <skia:SKLottieView Grid.Row="0" Grid.Column="0" ZIndex="2"
                           RepeatCount="0"
                           Source="hearttravel.json"
                           />
        <Grid Grid.Row="0" Grid.Column="0" ZIndex="1" RowDefinitions="*,*,*,*,*,*,*">
            <CarouselView x:Name="carview" ItemsSource="{Binding plans}" Grid.Row="0" Grid.RowSpan="2" IndicatorView="indicatorview" Margin="20"
                          CurrentItem="{Binding Source={x:StaticResource planvm},Path=SelectedItem,Mode=TwoWay}"
                          CurrentItemChangedCommand="{Binding cmd_ChangeItem}"
                          CurrentItemChangedCommandParameter="{Binding Source={x:Reference carview},Path=CurrentItem}">
                <CarouselView.ItemTemplate>
                    <DataTemplate>
                        <Grid RowDefinitions="*,*" ColumnDefinitions="*,*">
                            <Label x:Name="lb_Title" Text="{Binding Title}" Grid.Row="0" Grid.Column="0" FontSize="32" HorizontalOptions="Center"/>
                            <Label Text="{Binding Thema}" Grid.Row="0" Grid.Column="1" FontSize="20" HorizontalOptions="Center" TextColor="Green"/>
                            <Button Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Text="GoToShare" FontSize="32" FontAttributes="Bold"
                                    Command="{Binding Source={x:StaticResource planvm},Path=cmd_Share}" 
                                    CommandParameter="{Binding Source={x:Reference lb_Title},Path=Text}"/>
                        </Grid>
                    </DataTemplate>
                </CarouselView.ItemTemplate>
            </CarouselView>
            <IndicatorView x:Name="indicatorview" Grid.Row="2" IndicatorColor="Green" Margin="20"
                           SelectedIndicatorColor="YellowGreen" HorizontalOptions="Center"/>
            <CollectionView ItemsSource="{Binding planItems}" Grid.Row="3" Grid.RowSpan="4">
                <CollectionView.ItemTemplate>
                    <DataTemplate>
                        <Grid RowDefinitions="*,*">
                            <Label x:Name="lb_Title2" Text="{Binding Title}" Grid.Row="0" FontSize="32"/>
                            <Label Text="{Binding SubTitle}" Grid.Row="1" FontSize="32"/>
                        </Grid>
                    </DataTemplate>
                </CollectionView.ItemTemplate>
            </CollectionView>
        </Grid>
    </Grid>
    
</ContentPage>

 

 


4. 빌드된모습

반응형
Comments