이벤트를 ViewModel에서 사용하고 싶으면 어떻게 해야하는 걸까요?
CollectionView
에서 SelectionChanged 이벤트를 사용하려고 보니…
Maui에서 한 번도 이벤트를 사용 해본적이 없더라구요 (버튼 제외)
(StackOverflow answer에서 해결하긴 했지만 궁금한게 많네요.)
이벤트를 ViewModel에서 사용하고 싶으면 어떻게 해야하는 걸까요?
CollectionView
에서 SelectionChanged 이벤트를 사용하려고 보니…
Maui에서 한 번도 이벤트를 사용 해본적이 없더라구요 (버튼 제외)
(StackOverflow answer에서 해결하긴 했지만 궁금한게 많네요.)
MAUI는 해보진 않았지만
기본적으로 SelectedItem에 바인딩 걸면 그것이 SelectionChanged 아닌가요?
SelectedItem 바인딩 지원만 된다면 딱히 SelectionChanged 이벤트는 필요 없을 것 같은 생각입니다.ㅎㅎ
영어로 'Maui에서 mvvm 어떻게합니까?'라는 식으로 검색 했는데 안나오더라구요…
여기 Community.Toolkit에서 어떻게 이벤트를 바인딩해서? 가져오는지? 나와있네요.
@aroooong 맞습니다. 굳이 필요는 없을 것 같네요.
그냥 학구열??같은 거 랄까요
이벤트는 뷰 종속 인자 타입이 있기 때문에 직접 만든다면 가능은 하지만 지양해야 합니다.
학구열 때문이라면 이벤트를 커맨드로 변환하는 클래스 하나 만들고 적용해보아요.
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:
}
}
}
}
MAUI Community Toolkit의 다음의 EventToCommandBehavior
를 사용하면 원하는 것을 달성할 수 있습니다.
(그런데 그냥 사용하는 것 보다 아래 @Nobody 님의 코드와 아래 EventToCommandBehavior의 소스코드를 참고하는 것이 좀 더 좋을 것 같습니다.)
이제 Command를 쓸 수 있게 되었으므로 뷰에 종속적인 EventArgs를 종속적이지 않도록 변환하는 ItemTappedEventArgsConverter나 SelectedItemEventArgsConverter등을 쓸 수 있을 텐데요, 물론 직접 만들 수도 있습니다.
@dimohy @Nobody 좋은 의견 감사합니다.
무언가를 직접 만들어서 사용한적이 없네요.
의존적이라고 해야하나요, 검색하고 찾아서 적용하려다가 없으니까
'이거 없어서 못해’라는 식으로 흘러갑니다.
CollectionView의 경우 ItemTapped를 이용해서 사용하고 싶은데, 해당 이벤트를 못 찾겠습니다.
이러한 것에 대해 질문을하면 ‘아니 그냥 만들어서 쓰면 되잖아?’ 이런식의 반응입니다.
여기서 생기는 충돌점이 저는 만드는 법을 모릅니다. 질문을 받은 사람은 ‘~~~ 이렇게 만들면 될 것 같은데, 이 걸 설명하려니 좀 난감한데~~?’ 라는 느낌인 것 같아요.
방향, 학습 방법을 알 것 같기도 하구요, 이제 필요한 것을 만드는 것에 대해서 연습해야겠습니다.
감사합니다.