■ Binding 엘리먼트의 Source/Path 속성을 사용해 ObjectDataProvider 객체의 메소드를 바인딩하는 방법을 보여준다.
▶ DoubleToStringConverter.cs
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
using System; using System.Globalization; using System.Windows.Data; namespace TestProject { /// <summary> /// 실수↔문자열 변환자 /// </summary> public class DoubleToStringConverter : IValueConverter { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Public #region 변환하기 - Convert(sourceValue, targetType, parameter, cultureInfo) /// <summary> /// 변환하기 /// </summary> /// <param name="sourceValue">소스 값</param> /// <param name="targetType">타겟 타입</param> /// <param name="parameter">매개 변수</param> /// <param name="cultureInfo">문화 정보</param> /// <returns>변환 값</returns> public object Convert(object sourceValue, Type targetType, object parameter, CultureInfo cultureInfo) => sourceValue?.ToString(); #endregion #region 역변환하기 - ConvertBack(sourceValue, targetType, parameter, cultureInfo) /// <summary> /// 역변환하기 /// </summary> /// <param name="sourceValue">소스 값</param> /// <param name="targetType">타겟 타입</param> /// <param name="parameter">매개 변수</param> /// <param name="cultureInfo">문화 정보</param> /// <returns>역변환 값</returns> public object ConvertBack(object sourceValue, Type targetType, object parameter, CultureInfo cultureInfo) { if(sourceValue is string value) { double result; bool converted = double.TryParse(value, out result); if(converted) { return result; } } return null; } #endregion } } |
▶ InvalidCharacterRule.cs
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 32 33 34 35 36 37 38 39 40 41 42 43 44 |
using System; using System.Globalization; using System.Windows.Controls; namespace TestProject { /// <summary> /// 무효한 문자 규칙 /// </summary> public class InvalidCharacterRule : ValidationRule { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Public #region 검증하기 - Validate(value, cultureInfo) /// <summary> /// 검증하기 /// </summary> /// <param name="value">값</param> /// <param name="cultureInfo">문화 정보</param> /// <returns>검증 결과</returns> public override ValidationResult Validate(object value, CultureInfo cultureInfo) { try { if(((string)value).Length > 0) { double.Parse((string)value); } } catch(Exception exception) { return new ValidationResult(false, "Illegal characters or " + exception.Message); } return new ValidationResult(true, null); } #endregion } } |
▶ TemperatureType.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
namespace TestProject { /// <summary> /// 온도 타입 /// </summary> public enum TemperatureType { /// <summary> /// 섭씨 /// </summary> Celsius, /// <summary> /// 화씨 /// </summary> Fahrenheit } } |
▶ TemperatureScale.cs
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
using System.ComponentModel; using System.Globalization; namespace TestProject { /// <summary> /// 온도 스케일 /// </summary> public class TemperatureScale : INotifyPropertyChanged { //////////////////////////////////////////////////////////////////////////////////////////////////// Event ////////////////////////////////////////////////////////////////////////////////////////// Public #region 속성 변경시 - PropertyChanged /// <summary> /// 속성 변경시 /// </summary> public event PropertyChangedEventHandler PropertyChanged; #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Private #region Field /// <summary> /// 온도 타입 /// </summary> private TemperatureType type; #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Property ////////////////////////////////////////////////////////////////////////////////////////// Public #region 온도 타입 - Type /// <summary> /// 온도 타입 /// </summary> public TemperatureType Type { get { return this.type; } set { this.type = value; FirePropertyChangedEvent("Type"); } } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - TemperatureScale() /// <summary> /// 생성자 /// </summary> public TemperatureScale() { } #endregion #region 생성자 - TemperatureScale(type) /// <summary> /// 생성자 /// </summary> /// <param name="type">온도 타입</param> public TemperatureScale(TemperatureType type) { this.type = type; } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Public #region 변환하기 - Convert(degree, type) /// <summary> /// 변환하기 /// </summary> /// <param name="degree">도</param> /// <param name="type">온도 타입</param> /// <returns>변환 결과</returns> public string Convert(double degree, TemperatureType type) { Type = type; switch(type) { case TemperatureType.Celsius : return (degree*9/5 + 32).ToString(CultureInfo.InvariantCulture) + " " + "Fahrenheit"; case TemperatureType.Fahrenheit : return ((degree - 32)/9*5).ToString(CultureInfo.InvariantCulture) + " " + "Celsius"; } return "Unknown Type"; } #endregion ////////////////////////////////////////////////////////////////////////////////////////// Protected #region 속성 변경시 이벤트 발생시키기 - FirePropertyChangedEvent(propteryName) /// <summary> /// 속성 변경시 이벤트 발생시키기 /// </summary> /// <param name="propteryName">속성명</param> protected void FirePropertyChangedEvent(string propteryName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propteryName)); } #endregion } } |
▶ MainWindow.xaml
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
<Window x:Class="TestProject.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:system="clr-namespace:System;assembly=mscorlib" xmlns:local="clr-namespace:TestProject" Width="800" Height="600" Title="TestProject" FontFamily="나눔고딕코딩" FontSize="16"> <Window.Resources> <ObjectDataProvider x:Key="ObjectDataProviderKey" ObjectType="{x:Type local:TemperatureScale}" MethodName="Convert"> <ObjectDataProvider.MethodParameters> <system:Double>0</system:Double> <local:TemperatureType>Celsius</local:TemperatureType> </ObjectDataProvider.MethodParameters> </ObjectDataProvider> <local:DoubleToStringConverter x:Key="DoubleToStringConverterKey" /> </Window.Resources> <Border Margin="10" CornerRadius="10" BorderThickness="5" BorderBrush="RoyalBlue"> <Grid HorizontalAlignment="Center" VerticalAlignment="Center"> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions> <Label Grid.Row="0" HorizontalAlignment="Right"> Enter the degree to convert : </Label> <TextBox Name="tb" Grid.Row="0" Grid.Column="1" Width="100" Height="25" VerticalContentAlignment="Center"> <TextBox.Text> <Binding Source="{StaticResource ObjectDataProviderKey}" Path="MethodParameters[0]" BindsDirectlyToSource="true" UpdateSourceTrigger="PropertyChanged" Converter="{StaticResource DoubleToStringConverterKey}"> <Binding.ValidationRules> <local:InvalidCharacterRule /> </Binding.ValidationRules> </Binding> </TextBox.Text> </TextBox> <ComboBox Grid.Row="0" Grid.Column="2" Width="100" Height="25" VerticalContentAlignment="Center" SelectedValue="{Binding Source={StaticResource ObjectDataProviderKey}, Path=MethodParameters[1], BindsDirectlyToSource=true}"> <local:TemperatureType>Celsius</local:TemperatureType> <local:TemperatureType>Fahrenheit</local:TemperatureType> </ComboBox> <Label Grid.Row="1" HorizontalAlignment="Right">Result :</Label> <Label Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2" Content="{Binding Source={StaticResource ObjectDataProviderKey}}" /> </Grid> </Border> </Window> |