개발노트

22. [.NET MAUI] ItemsSource에 설정된 Binding 이외의 Binding이 필요할 때 본문

앱 개발/.NET MAUI

22. [.NET MAUI] ItemsSource에 설정된 Binding 이외의 Binding이 필요할 때

mroh1226 2022. 8. 26. 14:42
반응형

ObservableCollection<> 을 CarouselView나 CollectionView 등 에서 사용하려면,

ItemsSource = {Binding ObservableCollection명} 을 선언해주게 된다.


이 선언 때문에 CarouselView 나 CollectionView 내부의 Binding은 ItemsSource에서 Binding한 ObservableCollection에 포함된 값만 Binding 할수 있게된다.

 

하지만, CarouselView 나 CollectionView 안에 Button이라도 넣어야하는 상황이 오면 추가적으로 Command를 바인딩해야하는 상황이 생긴다.

 

위와같은 상황을 해결하기 위해서 이번 시간에는 ItemsSource에 포함되지 않은 요소를 Binding하는 법을 알아본다.

 


 

RewardVM.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MyMAUI.Services;
using System.Collections.ObjectModel;
using System.Windows.Input;
using static MyMAUI.Models.QuizEntity;

namespace MyMAUI.ViewModels
{
    class RewardVM : Notify
    {
        public ObservableCollection<FoodQuiz> _Food = new ObservableCollection<FoodQuiz>();
        public ICommand cmd_GoToMozza { get; set; }
        public RewardVM()
        {
            AddFood();
            cmd_GoToMozza = new Command(() =>
            {
                Shell.Current.GoToAsync("//App/MozzaPage");
            });
        }
        public void AddFood()
        {
            Food.Add(new FoodQuiz("Name1", 111, "Path1"));
            Food.Add(new FoodQuiz("Name2", 222, "Path2"));
            Food.Add(new FoodQuiz("Name3", 333, "Path3"));
        }

        public ObservableCollection<FoodQuiz> Food
        {
            get => _Food;
            set
            {
                if(_Food != value)
                {
                    _Food = value;
                    OnPropertyChanged("Food");
                }
            }

        }

    }
}

- RewardVM 이라는 RewardPage(View)의 ViewModel에서 아래와 같이 2가지를 CarouselView 내부에 Binding 할것이다.
1. public ObservableCollection<FoodQuiz> Food
2. public Command cmd_GoToMozza

 


 

RewardPage.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="MyMAUI.Views.RewardPage"
             xmlns:vm="clr-namespace:MyMAUI.ViewModels"
             Title="RewardPage">
    <ContentPage.Resources>
        <ResourceDictionary>
            <vm:RewardVM x:Key="RewardVM"/>
        </ResourceDictionary>
    </ContentPage.Resources>
    <StackLayout>
        <ScrollView>
            <CarouselView ItemsSource="{Binding Food}">
                <CarouselView.ItemTemplate>
                    <DataTemplate>
                        <ImageButton Source="dotnet_bot.svg" Command="{Binding Source={x:StaticResource RewardVM},Path=cmd_GoToMozza}"/>
                    </DataTemplate>
                </CarouselView.ItemTemplate>
            </CarouselView>
        </ScrollView>
    </StackLayout>
</ContentPage>

- 위 소스와같이 이미 <CarouselView ItemsSource="{Binding Food}"> 를 통해 CarouselView의 ItemsSource는 Food로 이미 바인딩 되어있다. 이 상태에서 내부의 ImageButton의 Command를 사용하려면 아래와 같이 소스를 작성한다.

1. xmlns:vm="clr-namespace:MyMAUI.ViewModels" 으로 ViewModels 디렉토리를 네임스페이스에 vm 이라는 이름으로 등록한다.

2. ContentPage.Resources의 ResourceDictionary에 vm에 있는 RewardVM를 키값 RewardVM로 등록한다.

3. <ImageButton  Command="{Binding Source={x:StaticResource RewardVM},Path=cmd_GoToMozza}"/> 와 같이 2번에 등록한 RewardVM을 StaticResource로 바인딩해주고 Path에 Command명을 연결해준다.

 

이로서 ItemsSource와 상관없는 외부 Command를 바인딩할 수 있다.

 


 

빌드된 모습

 

반응형
Comments