일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- IValueConverter
- convert
- logging
- Coding
- csharp
- nullable
- C#
- windows
- Process
- WPF
- string
- programmers
- Microsoft
- tls
- Binding
- coding-test
- Visual Studio
- commit
- chashtag
- log
- .net
- mysql
- 코딩테스트
- File
- windows10
- algorithm
- git
- ListView
- dotNET
- Github
- Today
- Total
CHashtag
[C# WPF] Binding 값 자동 변환 Converter (IValueConverter, IMultiValueConverter) 본문
[C# WPF] Binding 값 자동 변환 Converter (IValueConverter, IMultiValueConverter)
HyoSeong 2021. 2. 23. 01:51WPF 프로그래밍 중 바인딩될 값에 따라 다른 값을 지정해 주어야 할 때가 종종 있습니다.
(예를 들면 입력받은 text가 10자 이상이면 background color가 변한다. 같은 느낌으로요.)
(Binding StringFormat의 상위 호환이라고 생각하시면 편할 것 같습니다.)
이럴 때 사용할 수 있는 것이 바로 IValueConverter, IMultiValueConverter입니다.
이해를 돕기위해 예제 프로그램을 제작해 보도록 하겠습니다.
Converter
Binding이 기본적으로 2 way를 지원하듯, Converter도 2 way converting을 지원합니다.
ViewModel -> View로 가는 Convert 함수와 View -> ViewModel로 가는 ConverterBack 함수를 IValueConverter가 지원합니다.
(IMultiValueConverter의 경우에도 인자가 다른 동일 함수를 제공합니다.)
IValueConverter
[Convert] 코로나 극복을 기원하며 사람 수를 입력받아 5명 이상일 경우 배경화면이 붉게 변하는 프로그램을 제작해 보도록 하겠습니다.
// IntToColorConverter.cs
using System;
using System.Globalization;
using System.Windows.Data;
using System.Windows.Media;
namespace WPF_Converter
{
public class IntToColorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
SolidColorBrush color = new SolidColorBrush(Colors.Transparent);
if(value == null)
{
return color;
}
int personCount = (int)value;
// 5인 이상 집합 금지!
if (personCount >= 5)
{
color = new SolidColorBrush(Colors.Red);
}
return color;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
<!-- MainWindow.xaml -->
<Window x:Class="WPF_Converter.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WPF_Converter"
mc:Ignorable="d"
Title="MainWindow" Height="200" Width="400">
<Window.Resources>
<local:IntToColorConverter x:Key="IntToColorConverter"/>
</Window.Resources>
<Grid Background="{Binding PersonCount, Converter={StaticResource IntToColorConverter}}">
<TextBox HorizontalAlignment="Center" VerticalAlignment="Center" Width="80" Height="50" FontSize="25" Text="{Binding PersonCount, UpdateSourceTrigger=PropertyChanged}"/>
</Grid>
</Window>
// MainWindowViewModel.cs
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace WPF_Converter
{
public class MainWindowViewModel : INotifyPropertyChanged
{
private int _personCount;
public int PersonCount
{
get => _personCount;
set
{
_personCount = value;
NotifyPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged([CallerMemberName] string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
}
// MainWindow.xaml.cs
using System.Windows;
namespace WPF_Converter
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private MainWindowViewModel _viewModel;
public MainWindow()
{
InitializeComponent();
_viewModel = new MainWindowViewModel();
this.DataContext = _viewModel;
}
}
}
Converter를 사용하여 string을 color로 변환하는 프로그램을 제작해 보았습니다.
이제 ConvertBack을 사용해 볼 차례입니다.
위 프로그램의 TextBox에 숫자가 아닌 값이 들어가면 0으로 바꿔주도록 하는 Converter를 제작하여 적용해 보도록 하겠습니다.
// StringToIntConverter.cs
using System;
using System.Globalization;
using System.Windows.Data;
namespace WPF_Converter
{
public class StringToIntConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
// ViewModel -> View의 경우 기본값 그대로 return 하도록 한다.
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
int result = 0;
Int32.TryParse((string)value, out result);
return result;
}
}
}
<!-- MainWindow.xaml -->
<Window x:Class="WPF_Converter.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WPF_Converter"
mc:Ignorable="d"
Title="MainWindow" Height="200" Width="400">
<Window.Resources>
<local:IntToColorConverter x:Key="IntToColorConverter"/>
<local:StringToIntConverter x:Key="StringToIntConverter"/>
</Window.Resources>
<Grid Background="{Binding PersonCount, Converter={StaticResource IntToColorConverter}}">
<TextBox HorizontalAlignment="Center" VerticalAlignment="Center" Width="80" Height="50" FontSize="25" Text="{Binding PersonCount, Converter={StaticResource StringToIntConverter}, UpdateSourceTrigger=PropertyChanged}"/>
</Grid>
</Window>
실행 결과는 다음과 같습니다.
IMultiValueConverter
IMultiValueConverter는 동작 구조는 기존의 IValueConverter와 동일합니다.
다만 차이점은 함수의 첫번째 인자인 value가 object[] values로 변한다는 점뿐입니다.
IMultiValueConverter 실습을 위해 현재 2단계 거리두기인지에 대한 값을 입력받는 CheckBox를 이용하여 2단계 이상일 때에만 5명 이상 모일 수 없도록 프로그램을 변경해보도록 하겠습니다.
<!-- MainWindow.xaml -->
<Window x:Class="WPF_Converter.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WPF_Converter"
mc:Ignorable="d"
Title="MainWindow" Height="200" Width="400">
<Window.Resources>
<local:IntToColorConverter x:Key="IntToColorConverter"/>
<local:IntAndBoolToColorConverter x:Key="IntAndBoolToColorConverter"/>
<local:StringToIntConverter x:Key="StringToIntConverter"/>
</Window.Resources>
<Grid>
<Grid.Background>
<MultiBinding Converter="{StaticResource IntAndBoolToColorConverter}" >
<Binding Path="PersonCount"/>
<Binding Path="CheckBoxIsChecked"/>
</MultiBinding>
</Grid.Background>
<StackPanel Orientation="Horizontal">
<CheckBox Content="거리두기 2단계" VerticalAlignment="Center" IsChecked="{Binding CheckBoxIsChecked}"/>
<TextBox HorizontalAlignment="Center" VerticalAlignment="Center" Width="80" Height="50" FontSize="25" Text="{Binding PersonCount, Converter={StaticResource StringToIntConverter}, UpdateSourceTrigger=PropertyChanged}"/>
</StackPanel>
</Grid>
</Window>
// MainViewModel.cs
private bool _checkBoxIsChecked;
public bool CheckBoxIsChecked
{
get => _checkBoxIsChecked;
set
{
_checkBoxIsChecked = value;
NotifyPropertyChanged();
}
}
// IntAndBoolToColorConverter.cs
using System;
using System.Globalization;
using System.Windows.Data;
using System.Windows.Media;
namespace WPF_Converter
{
public class IntAndBoolToColorConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
SolidColorBrush color = new SolidColorBrush(Colors.Transparent);
if (values == null)
{
return color;
}
int personCount = (int)values[0];
bool isSecond = (bool)values[1];
// 거리두기 2단계 이상일 때에는 5인 이상 집합 금지!
if (isSecond && personCount >= 5)
{
color = new SolidColorBrush(Colors.Red);
}
return color;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
실행결과는 다음과 같습니다.
전체 코드는 아래 링크에서 확인하실 수 있습니다.
https://github.com/Hyo-Seong/CHashtag/tree/master/WPF_Converter
나중에 이 게시글을 보며 그땐 그랬었지 하며 웃을 수 있는 날이 왔으면 좋겠습니다.
모두들 파이팅입니다.
감사합니다.
'C# > WPF' 카테고리의 다른 글
[C# WPF] MVVM패턴 TextBox Enter눌렀을 때 Command (KeyBinding) (0) | 2021.03.29 |
---|---|
[C#] [WPF] DispatcherTimer 사용방법 (0) | 2021.02.24 |
[C#] [WPF] MultiBinding StringFormat (여러개 동시 바인딩) (0) | 2021.02.21 |
[C#][WPF] MVVM패턴 CheckBox 양방향 Binding (0) | 2021.02.19 |
[C# WPF] MVVM 패턴 ListView Filter (Binding) (2) | 2021.02.09 |