[MAUI] MVVM에서 이벤트는 어떻게 하나요?

이벤트를 ViewModel에서 사용하고 싶으면 어떻게 해야하는 걸까요?
CollectionView에서 SelectionChanged 이벤트를 사용하려고 보니…
Maui에서 한 번도 이벤트를 사용 해본적이 없더라구요 (버튼 제외)

(StackOverflow answer에서 해결하긴 했지만 궁금한게 많네요.)

1 Like

MAUI는 해보진 않았지만

기본적으로 SelectedItem에 바인딩 걸면 그것이 SelectionChanged 아닌가요?

SelectedItem 바인딩 지원만 된다면 딱히 SelectionChanged 이벤트는 필요 없을 것 같은 생각입니다.ㅎㅎ

3 Likes

영어로 'Maui에서 mvvm 어떻게합니까?'라는 식으로 검색 했는데 안나오더라구요…

여기 Community.Toolkit에서 어떻게 이벤트를 바인딩해서? 가져오는지? 나와있네요.

@aroooong 맞습니다. 굳이 필요는 없을 것 같네요.
그냥 학구열??같은 거 랄까요

2 Likes

이벤트는 뷰 종속 인자 타입이 있기 때문에 직접 만든다면 가능은 하지만 지양해야 합니다.

학구열 때문이라면 이벤트를 커맨드로 변환하는 클래스 하나 만들고 적용해보아요.

2 Likes

Behavior를 사용합니다.

MainPage.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="MauiApp1.MainPage"
             Title="SAMPLE"
             xmlns:behavior="clr-namespace:MauiApp1.Behaviors"
             BindingContext="{Binding Source={RelativeSource Mode=Self}}">

    <CollectionView ItemsSource="{Binding ItemsList}"
                    SelectionMode="Single"
                    ItemsLayout="VerticalGrid, 3"
                    VerticalOptions="Center">
        <CollectionView.Behaviors>
            <behavior:CollectionViewBehavior/>
        </CollectionView.Behaviors>

        <CollectionView.ItemTemplate>
            <DataTemplate>
                <Border Stroke="#212121"
                        StrokeThickness="2"
                        StrokeShape="RoundRectangle 40,0,0,40"
                        Background="#01579B"
                        Padding="16,8">
                    <Label Text="{Binding ., StringFormat='item:{0}'}"
                           TextColor="#FFFFFF"
                           Margin="0,5,0,0"
                           HorizontalOptions="Center"
                           VerticalOptions="Center"
                           FontAttributes="Bold"
                           FontSize="20"/>
                </Border>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>
</ContentPage>

MainPage.cs

using System.Collections.ObjectModel;

namespace MauiApp1;

public partial class MainPage : ContentPage
{
    public static readonly BindableProperty ItemsListProperty =
        BindableProperty.Create(nameof(ItemsList), typeof(ObservableCollection<int>), typeof(MainPage), null);

    public ObservableCollection<int> ItemsList
	{
		get { return (ObservableCollection<int>)GetValue(ItemsListProperty); }
		set { SetValue(ItemsListProperty, value); }
	}

	public MainPage()
	{
		InitializeComponent();
		Load();
	}

	private void Load()
	{
		ItemsList = new();

        foreach (var item in Enumerable.Range(1, 9))
		{
			ItemsList.Add(item);
        }
	}
}

CollectionViewBehavior.cs

namespace MauiApp1.Behaviors
{
    public class CollectionViewBehavior : Behavior<CollectionView>
    {
        protected override void OnAttachedTo(CollectionView bindable)
        {
            bindable.SelectionChanged += Bindable_SelectionChanged;
            base.OnAttachedTo(bindable);
        }

        protected override void OnDetachingFrom(CollectionView bindable)
        {
            bindable.SelectionChanged -= Bindable_SelectionChanged;
            base.OnDetachingFrom(bindable);
        }

        private void Bindable_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (sender is CollectionView collectionView && collectionView.SelectedItem is int value && value == 9)
            {
                //TODO:
            }
        }
    }
}

22
123

3 Likes

MAUI Community Toolkit의 다음의 EventToCommandBehavior를 사용하면 원하는 것을 달성할 수 있습니다.

(그런데 그냥 사용하는 것 보다 아래 @Nobody 님의 코드와 아래 EventToCommandBehavior의 소스코드를 참고하는 것이 좀 더 좋을 것 같습니다.)

이제 Command를 쓸 수 있게 되었으므로 뷰에 종속적인 EventArgs를 종속적이지 않도록 변환하는 ItemTappedEventArgsConverterSelectedItemEventArgsConverter등을 쓸 수 있을 텐데요, 물론 직접 만들 수도 있습니다.

4 Likes

@dimohy @Nobody 좋은 의견 감사합니다.
무언가를 직접 만들어서 사용한적이 없네요.
의존적이라고 해야하나요, 검색하고 찾아서 적용하려다가 없으니까
'이거 없어서 못해’라는 식으로 흘러갑니다.


CollectionView의 경우 ItemTapped를 이용해서 사용하고 싶은데, 해당 이벤트를 못 찾겠습니다.
이러한 것에 대해 질문을하면 ‘아니 그냥 만들어서 쓰면 되잖아?’ 이런식의 반응입니다.

여기서 생기는 충돌점이 저는 만드는 법을 모릅니다. 질문을 받은 사람은 ‘~~~ 이렇게 만들면 될 것 같은데, 이 걸 설명하려니 좀 난감한데~~?’ 라는 느낌인 것 같아요.

방향, 학습 방법을 알 것 같기도 하구요, 이제 필요한 것을 만드는 것에 대해서 연습해야겠습니다.

감사합니다.

5 Likes