728x90
반응형
728x170
■ Binding 태그 확장의 StringFormat 속성에서 포맷 문자열을 사용하는 방법을 보여준다.
▶ NamedColor.cs
using System.Reflection;
using System.Text;
namespace TestProject;
/// <summary>
/// 이름있는 색상
/// </summary>
public class NamedColor : IEquatable<NamedColor>, IComparable<NamedColor>
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Property
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Public
#region 이름있는 색상 리스트 - NamedColorList
/// <summary>
/// 이름있는 색상 리스트
/// </summary>
public static IList<NamedColor> NamedColorList { private set; get; }
#endregion
////////////////////////////////////////////////////////////////////////////////////////// Instance
//////////////////////////////////////////////////////////////////////////////// Public
#region 명칭 - Name
/// <summary>
/// 명칭
/// </summary>
public string Name { private set; get; }
#endregion
#region 친숙한 명칭 - FriendlyName
/// <summary>
/// 친숙한 명칭
/// </summary>
public string FriendlyName { private set; get; }
#endregion
#region 색상 - Color
/// <summary>
/// 색상
/// </summary>
public Color Color { private set; get; }
#endregion
#region RGB 디스플레이 - RGBDisplay
/// <summary>
/// RGB 디스플레이
/// </summary>
public string RGBDisplay { private set; get; }
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Static
#region 생성자 - NamedColor()
/// <summary>
/// 생성자
/// </summary>
static NamedColor()
{
List<NamedColor> namedColorList = new List<NamedColor>();
StringBuilder stringBuilder = new StringBuilder();
foreach(FieldInfo fieldInfo in typeof(Colors).GetRuntimeFields())
{
if(fieldInfo.IsPublic && fieldInfo.IsStatic && fieldInfo.FieldType == typeof(Color))
{
string name = fieldInfo.Name;
stringBuilder.Clear();
int index = 0;
foreach(char character in name)
{
if(index != 0 && Char.IsUpper(character))
{
stringBuilder.Append(' ');
}
stringBuilder.Append(character);
index++;
}
Color color = (Color)fieldInfo.GetValue(null);
NamedColor namedColor = new NamedColor
{
Name = name,
FriendlyName = stringBuilder.ToString(),
Color = color,
RGBDisplay = string.Format
(
"{0:X2}-{1:X2}-{2:X2}",
(int)(255 * color.Red ),
(int)(255 * color.Green),
(int)(255 * color.Blue )
)
};
namedColorList.Add(namedColor);
}
}
namedColorList.TrimExcess();
namedColorList.Sort();
NamedColorList = namedColorList;
}
#endregion
////////////////////////////////////////////////////////////////////////////////////////// Instance
//////////////////////////////////////////////////////////////////////////////// Private
#region 생성자 - NamedColor()
/// <summary>
/// 생성자
/// </summary>
private NamedColor()
{
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Public
#region 찾기 - Find(name)
/// <summary>
/// 찾기
/// </summary>
/// <param name="name">명칭</param>
/// <returns>이름있는 색상</returns>
public static NamedColor Find(string name)
{
return ((List<NamedColor>)NamedColorList).Find(nc => nc.Name == name);
}
#endregion
#region 최근접 색상명 구하기 - GetNearestColorName(color)
/// <summary>
/// 최근접 색상명 구하기
/// </summary>
/// <param name="color">색상</param>
/// <returns>최근접 색상명</returns>
public static string GetNearestColorName(Color color)
{
double shortestDistance = 1000;
NamedColor closestColor = null;
foreach(NamedColor namedColor in NamedColor.NamedColorList)
{
double distance = Math.Sqrt
(
Math.Pow(color.Red - namedColor.Color.Red , 2) +
Math.Pow(color.Green - namedColor.Color.Green, 2) +
Math.Pow(color.Blue - namedColor.Color.Blue , 2)
);
if(distance < shortestDistance)
{
shortestDistance = distance;
closestColor = namedColor;
}
}
return closestColor.Name;
}
#endregion
////////////////////////////////////////////////////////////////////////////////////////// Instance
//////////////////////////////////////////////////////////////////////////////// Public
#region 동일 여부 구하기 - Equals(other)
/// <summary>
/// 동일 여부 구하기
/// </summary>
/// <param name="other">다른 이름있는 색상</param>
/// <returns>동일 여부</returns>
public bool Equals(NamedColor other)
{
return Name.Equals(other.Name);
}
#endregion
#region 비교하기 - CompareTo(other)
/// <summary>
/// 비교하기
/// </summary>
/// <param name="other">다른 이름있는 색상</param>
/// <returns>비교 결과</returns>
public int CompareTo(NamedColor other)
{
return Name.CompareTo(other.Name);
}
#endregion
}
▶ HSLColorViewModel.cs
using System.ComponentModel;
namespace TestProject;
/// <summary>
/// HSL 색상 뷰 모델
/// </summary>
public class HSLColorViewModel : INotifyPropertyChanged
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Event
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 속성 변경시 - PropertyChanged
/// <summary>
/// 속성 변경시
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// 색상
/// </summary>
private Color color;
/// <summary>
/// 명칭
/// </summary>
private string name;
/// <summary>
/// 색조
/// </summary>
private float hue;
/// <summary>
/// 채도
/// </summary>
private float saturation;
/// <summary>
/// 명도
/// </summary>
private float luminosity;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Property
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 색조 - Hue
/// <summary>
/// 색조
/// </summary>
public float Hue
{
get
{
return this.hue;
}
set
{
if(this.hue != value)
{
Color = Color.FromHsla(value, this.saturation, this.luminosity);
}
}
}
#endregion
#region 채도 - Saturation
/// <summary>
/// 채도
/// </summary>
public float Saturation
{
get
{
return this.saturation;
}
set
{
if(this.saturation != value)
{
Color = Color.FromHsla(this.hue, value, this.luminosity);
}
}
}
#endregion
#region 명도 - Luminosity
/// <summary>
/// 명도
/// </summary>
public float Luminosity
{
get
{
return this.luminosity;
}
set
{
if(this.luminosity != value)
{
Color = Color.FromHsla(this.hue, this.saturation, value);
}
}
}
#endregion
#region 색상 - Color
/// <summary>
/// 색상
/// </summary>
public Color Color
{
get
{
return this.color;
}
set
{
if(this.color != value)
{
this.color = value;
this.hue = color.GetHue();
this.saturation = color.GetSaturation();
this.luminosity = color.GetLuminosity();
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Hue" ));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Saturation"));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Luminosity"));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Color" ));
Name = NamedColor.GetNearestColorName(this.color);
}
}
}
#endregion
#region 명칭 - Name
/// <summary>
/// 명칭
/// </summary>
public string Name
{
get
{
return this.name;
}
private set
{
if(this.name != value)
{
this.name = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Name"));
}
}
}
#endregion
}
▶ MainPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage x:Class="TestProject.MainPage"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:TestProject">
<ContentPage.BindingContext>
<local:HSLColorViewModel Color="Sienna" />
</ContentPage.BindingContext>
<ContentPage.Resources>
<ResourceDictionary>
<Style TargetType="Slider">
<Setter Property="VerticalOptions" Value="Center" />
</Style>
<Style TargetType="Label">
<Setter Property="HorizontalTextAlignment" Value="Center" />
</Style>
</ResourceDictionary>
</ContentPage.Resources>
<StackLayout
HorizontalOptions="Center"
VerticalOptions="Center">
<BoxView
HorizontalOptions="Center"
WidthRequest="300"
HeightRequest="300"
Color="{Binding Color}" />
<StackLayout
Margin="0,10,0,0">
<Label Text="{Binding Name}" />
<Slider
Margin="0,30,0,0"
Value="{Binding Hue}" />
<Label Text="{Binding Hue, StringFormat='색조 : {0:F2}'}" />
<Slider
Margin="0,10,0,0"
Value="{Binding Saturation}" />
<Label Text="{Binding Saturation, StringFormat='채도 : {0:F2}'}" />
<Slider
Margin="0,10,0,0"
Value="{Binding Luminosity}" />
<Label Text="{Binding Luminosity, StringFormat='명도 : {0:F2}'}" />
</StackLayout>
</StackLayout>
</ContentPage>
728x90
반응형
그리드형(광고전용)
'C# > MAUI' 카테고리의 다른 글
[C#/MAUI/.NET6] Binding 태그 확장 : FallbackValue 속성을 사용해 바인딩 오류시 대체 값 설정하기 (0) | 2022.03.11 |
---|---|
[C#/MAUI/.NET6] RelativeSource 태그 확장 : Mode 속성을 사용해 조상 엘리먼트 참조하기 (0) | 2022.03.11 |
[C#/MAUI/.NET6] Binding 클래스 : ConverterParameter 속성 사용하기 (0) | 2022.03.10 |
[C#/MAUI/.NET6] Binding 태그 확장 : Converter 속성에서 정수↔진리 값 변환자 사용하기 (0) | 2022.03.09 |
[C#/MAUI/.NET6] Binding 태그 확장 : Path 속성에서 바인딩 경로 사용하기 (0) | 2022.03.09 |
[C#/MAUI/.NET6] INotifyPropertyChanged 인터페이스 : HSL 색상 뷰 모델 바인딩하기 (0) | 2022.03.09 |
[C#/MAUI/.NET6] 비주얼 트리에서 바인딩 컨텍스트 상속하기 (0) | 2022.03.08 |
[C#/MAUI/.NET6] Binding 엘리먼트 : Source 속성을 사용해 바인딩 설정하기 (0) | 2022.03.08 |
[C#/MAUI/.NET6] Binding 엘리먼트 : Source/Path 속성을 사용해 바인딩 설정하기 (0) | 2022.03.08 |
[C#/MAUI/.NET6] BindableObjectExtensions 클래스 : SetBinding 확장 메소드를 사용해 바인딩 설정하기 (0) | 2022.03.08 |
댓글을 달아 주세요