일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 닷넷
- Maui
- 오류
- AnimationController
- GitHub
- Firebase
- .NET
- typescript
- 깃허브
- MS-SQL
- MVVM
- 플러터
- 바인딩
- 함수
- Binding
- 자바스크립트
- JavaScript
- 애니메이션
- MSSQL
- Flutter
- 파이어베이스
- 마우이
- listview
- HTML
- page
- db
- 리엑트
- spring boot
- React JS
- Animation
- Today
- Total
개발노트
24. [.NET MAUI] IMultiValueConverter 사용하기(CommandParameter 에MultiBinding 하기) 본문
24. [.NET MAUI] IMultiValueConverter 사용하기(CommandParameter 에MultiBinding 하기)
mroh1226 2022. 9. 14. 11:36하나의 컨트롤에 2가지 값을 넘겨주고싶을 때 MultiBinding을 사용하여 이를 해결 할 수 있다.
같은 컨트롤의 여러 값이 필요한 상황이라면 {Binding .} 이나 ObservationCollection<>을 사용하면 해결된다.
하지만, 다른 컨트롤의 여러값이 필요한 상황이라면 이야기가 달라진다.
예를 들어 하나의 Button에 여러개의 CommandParameter를 줘야하는 상황이 온다면, IMultiValueConverter 를 이용하여 MultiBinding을 할 수 있다.
Button에 버튼클릭 Command도 Binding하고, CommandParameter로 2개 이상의 Parameter 값을 전달 받아보자.
1. 자신이 원하는 Parameter들을 받을 수 있는 객체를 Model에 생성한다.
QuizEntity.cs
using SkiaSharp.Extended.UI.Controls;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MyMAUI.Models
{
class QuizEntity
{
public class PriorityQuiz
{
public string Name { get; set; }
public string Path { get; set; }
public int Priority { get; set; }
public PriorityQuiz(string _Name, string _Path, int _Priority)
{
Name = _Name;
Path = _Path;
Priority = _Priority;
}
}
public class PrioritySkia
{
public SKLottieView Skia { get; set; }
public PriorityQuiz Priority { get; set; }
public PrioritySkia(PriorityQuiz _Priority, SKLottieView _Skia)
{
this.Priority = _Priority;
this.Skia = _Skia;
}
}
}
}
PriorityQuiz 와 SKLottieview 이 2가지의 Parameter를 받을 PrioritySkia 라는 객체를 생성하였다.
PriorityQuiz 객체는 위에서 확인가능하고, SKLottieview는 이전 포스터를 확인 하시면됩니다.
https://mroh1226.tistory.com/35
2. IMultiValueConverter 를 상속받는 Class를 생성하여 Convert 인터페이스를 작성한다.
PrioritySkiaMultiConverter.cs
using SkiaSharp.Extended.UI.Controls;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static MyMAUI.Models.QuizEntity;
namespace MyMAUI.Services
{
public class PrioritySkiaMultiConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
//PriorityQuiz, SKLottieView 순서대로 values 배열에 넣음
return new PrioritySkia((PriorityQuiz)values[0], (SKLottieView)values[1]);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
//Mode = "TwoWay" 일때 사용
throw new NotImplementedException();
}
}
}
values[0] 에는 PriorityQuiz 객체를, values[1]에는 SKLottieView 객체를 넣기 위해 (변수형)values[] 로 미리 변수형을 정해준다.
3. 마크업 소스 작성 ResourceDictionary에 PrioritySkiaMultiConverter를 추가해주고 컨트롤.CommandParameter를 통해 <MultiBinding의 Converter>를 연결한다.
4. <Binding Path와 Source>를 이용하여 위에서 정해줬던 values[0], values[1] 순서대로 바인딩해준다.
PriorityQuizPage.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:service="clr-namespace:MyMAUI.Services"
x:Class="MyMAUI.Views.PriorityQuizPage"
Title="PriorityQuizPage">
<ContentPage.Resources>
<ResourceDictionary>
<service:PrioritySkiaMultiConverter x:Key="convert"/>
</ResourceDictionary>
</ContentPage.Resources>
<Grid RowDefinitions="*,*,*,*,*" ColumnDefinitions="*,*">
<ImageButton x:Name="Image_A"
Grid.Row="0"
Grid.RowSpan="3"
Grid.Column="0"
Source="{Binding priorityA.Path}"
Command="{Binding cmd_Select}"/>
<skia:SKLottieView x:Name="pick_A"
Grid.Row="0"
Grid.RowSpan="3"
Grid.Column="0"
IsAnimationEnabled="False"
RepeatCount="0"
Source="pop_like.json"/>
<ImageButton x:Name="Image_B"
Grid.Row="0"
Grid.RowSpan="3"
Grid.Column="1"
Source="{Binding priorityB.Path}"
Command="{Binding cmd_Select}"/>
<skia:SKLottieView x:Name="pick_B"
Grid.Row="0"
Grid.RowSpan="3"
Grid.Column="1"
IsAnimationEnabled="False"
RepeatCount="0"
Source="pop_like.json"/>
<Label Text="{Binding priorityA.Name}"
Grid.Row="3"
Grid.Column="0"/>
<Label Text="{Binding priorityB.Name}"
Grid.Row="3"
Grid.Column="1"/>
<Button Text="A"
Grid.Row="4"
Grid.Column="0"
Command="{Binding cmd}">
<Button.CommandParameter>
<MultiBinding Converter="{StaticResource convert}">
<Binding Path="priorityA"/>
<Binding Source="{x:Reference pick_A}"/>
</MultiBinding>
</Button.CommandParameter>
</Button>
<Button Text="B"
Grid.Row="4"
Grid.Column="1"
Command="{Binding cmd}">
<Button.CommandParameter>
<MultiBinding Converter="{StaticResource convert}">
<Binding Path="priorityB"/>
<Binding Source="{x:Reference pick_B}"/>
</MultiBinding>
</Button.CommandParameter>
</Button>
</Grid>
</ContentPage>
*ViewModel에 있는 PriorityQuiz를 Source로 바인딩시켜줬을 때 엉뚱한 값이 들어가거나 초기 값만 들어간다. 또한, ViewModel에서 변경되어 OnPropertyChange("PriorityQuiz")를 타고 변경되어도 이상하게 마크업에서 바인딩된 값은 안변한다... Command에 바인딩된 소스에서도 값이 바뀌지 않고 초기값만 가져옴..
(ViewModel에서 바인딩 할 변수는 위 마크업 소스와 같이 Path로 연결시켜주니 잘 작동한다.
x:Reference 로 연결한 값은 Source로 잘 바인딩 됨.! 차이점이 뭔지 공부 필요)
5. ViewModel을 아래와 같이 작성한다.
Command<> 에 Converter에 사용한 객체(PrioritySkia)를 넣어준다. → Command<PrioritySkia>
6. Parameter로 받은 object를 o라고 정하고 임의로 받아 안에 있는 객체를 각각 사용할 수 있다.
PriorityQuizVM.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;
using SkiaSharp.Extended.UI.Controls;
namespace MyMAUI.ViewModels
{
class PriorityQuizVM : Notify
{
public ICommand cmd_pick { get; set; }
public ICommand cmd_Select { get; set; }
public ICommand cmd { get; set; }
int RandomNumA;
int RandomNumB;
public PriorityQuiz _priorityA { get; set; }
public PriorityQuiz priorityA
{
get => _priorityA;
set
{
if(_priorityA != value)
{
_priorityA = value;
OnPropertyChanged("priorityA");
}
}
}
public PriorityQuiz _priorityB { get; set; }
public PriorityQuiz priorityB
{
get => _priorityB;
set
{
if (_priorityB != value)
{
_priorityB = value;
OnPropertyChanged("priorityB");
}
}
}
public ObservableCollection<PriorityQuiz> _priorityQuiz = new ObservableCollection<PriorityQuiz>();
public ObservableCollection<PriorityQuiz> priorityQuiz
{
get => _priorityQuiz;
set
{
if(_priorityQuiz != value)
{
_priorityQuiz = value;
OnPropertyChanged("priorityQuiz");
}
}
}
public PriorityQuizVM()
{
AddPriorityQuiz();
SetPriorityQuiz();
cmd_Select = new Command(() =>
{
SetPriorityQuiz();
});
//MultiConverter로 받아오기
cmd = new Command<PrioritySkia>(async(o) =>
{
PriorityQuiz pp = o.Priority;
SKLottieView ss = o.Skia;
ss.IsAnimationEnabled = true;
await Task.Delay(700);
await App.Current.MainPage.DisplayAlert("확인", pp.Name, "OK");
});
}
public void AddPriorityQuiz()
{
priorityQuiz.Add(new PriorityQuiz("Name0", "dotnet_bot.svg", 0));
priorityQuiz.Add(new PriorityQuiz("Name1", "dotnet_bot.svg", 1));
priorityQuiz.Add(new PriorityQuiz("Name2", "dotnet_bot.svg", 2));
priorityQuiz.Add(new PriorityQuiz("Name3", "dotnet_bot.svg", 3));
priorityQuiz.Add(new PriorityQuiz("Name4", "dotnet_bot.svg", 4));
priorityQuiz.Add(new PriorityQuiz("Name5", "dotnet_bot.svg", 5));
}
public void SetPriorityQuiz()
{
if (priorityQuiz.Count == 1) return;
Random random = new Random();
do
{
RandomNumA = random.Next(0,priorityQuiz.Count);
RandomNumB = random.Next(0,priorityQuiz.Count);
} while (RandomNumA == RandomNumB); //난수끼리 같다면 다시 난수발생 시키기
priorityA = priorityQuiz[RandomNumA];
priorityB = priorityQuiz[RandomNumB];
}
}
}
PriorityQuiz pp = o.Priority;
SKLottieView ss = o.Skia;
위 소스로 pp와 ss로 값을 받아 이용할 수 있다.
*테스트를 위해 ss.IsAnimationEnabled = true; 로 Lottie 이미지를 실행하고,
await App.Current.MainPage.DisplayAlert("확인", pp.Name, "OK"); 를 통해 바인딩된 PriorityQuiz의 Name을 확인한다.
'앱 개발 > .NET MAUI' 카테고리의 다른 글
26. [.NET MAUI] xaml에서 컨트롤 맨 앞으로 보내기 (0) | 2022.09.15 |
---|---|
25. [.NET MAUI] AudioPlayer 로 소리 재생하기 (0) | 2022.09.15 |
23. [.NET MAUI] ObservationCollection의 Item랜덤하게 가져오기(with Random) (0) | 2022.08.31 |
22. [.NET MAUI] ItemsSource에 설정된 Binding 이외의 Binding이 필요할 때 (0) | 2022.08.26 |
21. [.NET MAUI] MAUI에 DevExpress 컨트롤 사용하기 (0) | 2022.08.10 |