하아찡
[C#/WPF/수정] PublicColor프로젝트 색변경 추가 본문
ColorView.xaml
<UserControl x:Class="PublicColor.View.ColorView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:colorpicker="clr-namespace:ColorPicker;assembly=ColorPicker"
xmlns:local="clr-namespace:PublicColor.View"
xmlns:vm="clr-namespace:PublicColor.Model"
mc:Ignorable="d" >
<UserControl.DataContext>
<vm:ColorModel/>
</UserControl.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="20"/>
</Grid.RowDefinitions>
<ListView Grid.Row="0" ItemsSource="{Binding MyColors}">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Margin" Value="0"/>
<Setter Property="Padding" Value="2"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<TextBlock Text="{Binding Name}" HorizontalAlignment="Left"/>
<colorpicker:PortableColorPicker SelectedColor="{Binding Clr}" HorizontalAlignment="Right" ColorState="{Binding ClrState, Mode=TwoWay}" Width="50" Height="20"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Button Grid.Row="1" Command="{Binding CommandSaveColors}" Content="저장"/>
</Grid>
</UserControl>
해당 ColorPicker는 Nuget에서 PixiEditor.ColorPicker추가하여 사용했습니다.
ColorModel.cs
using ColorPicker.Models;
using Prism.Commands;
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;
using static System.Net.Mime.MediaTypeNames;
namespace PublicColor.Model
{
public class StructColor : BindableBase
{
private string name;
public string Name
{
get { return name; }
set { SetProperty(ref name, value); }
}
private string key;
public string Key
{
get { return key; }
set { SetProperty(ref key, value); }
}
private bool ischanged;
public bool IsChanged
{
get
{
return ischanged;
}
set
{
SetProperty(ref ischanged, value);
}
}
private string precolor;
public string PreColor
{
get { return precolor; }
set { SetProperty(ref precolor, value); }
}
private string nowcolor;
public string NowColor
{
get { return nowcolor; }
set { SetProperty(ref nowcolor, value); }
}
private ColorState clrstate;
public ColorState ClrState
{
get { return clrstate; }
set { SetProperty(ref clrstate, value); }
}
private Color clr;
public Color Clr
{
get { return clr; }
set { SetProperty(ref clr, value); }
}
}
public class ColorModel : BindableBase
{
#region Model
private List<StructColor> mycolors;
public List<StructColor> MyColors
{
get { return mycolors; }
set { SetProperty(ref mycolors, value); }
}
//Colors.cs에서 color값을 받아와서 현재 View에 저장
private Dictionary<string, string> diccolors;
public Dictionary<string, string> DicColors
{
get { return diccolors; }
set { SetProperty(ref diccolors, value); }
}
#endregion Model
#region Events
private DelegateCommand commandsavecolors;
public DelegateCommand CommandSaveColors =>
commandsavecolors ?? (commandsavecolors = new DelegateCommand(ExecuteCommandSaveColors));
void ExecuteCommandSaveColors()
{
for(int i = 0; i < MyColors.Count; i++)
{
MyColors[i].NowColor = ColorToString(ColorStateToColor(MyColors[i].ClrState));
if (MyColors[i].NowColor != MyColors[i].PreColor)
MyColors[i].IsChanged = true;
}
bool _b = false;
foreach(var v in MyColors)
{
if (v.IsChanged)
{
_b = true;
PublicColor.Colors.Colorinstance.SetColor(v.Key, v.NowColor);
}
}
if (_b)
{
PublicColor.Colors.Colorinstance.SetColor();
MessageBox.Show("변경완료");
}
}
#endregion Events
#region Functions
/// <summary>
/// DirColors값을 받아옴.
/// </summary>
private Dictionary<string, string> GetColors()
{
return PublicColor.Colors.Colorinstance.DirColors;
}
private ColorState StringToColorState(string color)
{
ColorState val = new ColorState();
Color clr = StringToColor(color);
val.RGB_R = clr.R / 255.0;
val.RGB_G = clr.G / 255.0;
val.RGB_B = clr.B / 255.0;
val.A = clr.A / 255.0;
return val;
}
private Color ColorStateToColor(ColorState cst)
{
Color val = new Color();
val.R = (byte)Math.Round(255 * cst.RGB_R);
val.G = (byte)Math.Round(255 * cst.RGB_G);
val.B = (byte)Math.Round(255 * cst.RGB_B);
val.A = (byte)Math.Round(255 * cst.A);
return val;
}
private Color StringToColor(string color)
{
Color clr;
byte A = Convert.ToByte((color[0].ToString() + color[1].ToString()), 16);
byte R = Convert.ToByte((color[2].ToString() + color[3].ToString()), 16);
byte G = Convert.ToByte((color[4].ToString() + color[5].ToString()), 16);
byte B = Convert.ToByte((color[6].ToString() + color[7].ToString()), 16);
clr = Color.FromArgb(
A,
R,
G,
B);
return clr;
}
private Brush ColorToBrush(Color clr)
{
Brush br;
var bc = new BrushConverter();
return (Brush)bc.ConvertFrom($"#{ColorToString(clr)}");
}
private string ColorToString(Color clr)
{
string val = "";
byte A = clr.A;
byte G = clr.G;
byte B = clr.B;
byte R = clr.R;
val = $"{A:X2}{R:X2}{G:X2}{B:X2}";
return val;
}
#endregion Functions
public ColorModel()
{
DicColors = GetColors();
MyColors = new List<StructColor>();
foreach (KeyValuePair<string,string> k in DicColors)
{
StructColor st = new StructColor();
st.Name = k.Key;
st.PreColor = k.Value;
st.NowColor = k.Value;
st.Key = k.Key;
st.Clr = StringToColor(k.Value);
st.IsChanged = false;
st.ClrState = StringToColorState(k.Value);
MyColors.Add(st);
}
}
}
}
ColorPicker를 사용하는데 있어서 문제는 현재 색상 처리방식은 Brush로 처리하고 저장은 "#FFFFFFFF"이런식으로 저장하여 변환해서 사용했는데 ColorPicker에서 ColorState에 데이터를 바인딩시킬땐 ColorState를 사용해야해서 내가 가진 색상값을 변경해줘야 함.
그래서 생성자쪽을보면 내가 가진 컬러값을 아래 코드로 정제시키는 과정을 진행함.
foreach (KeyValuePair<string,string> k in DicColors)
{
StructColor st = new StructColor();
st.Name = k.Key;
st.PreColor = k.Value;
st.NowColor = k.Value;
st.Key = k.Key;
st.Clr = StringToColor(k.Value);
st.IsChanged = false;
st.ClrState = StringToColorState(k.Value);
MyColors.Add(st);
}
위 코드는 내가 가진 색상값을 UI쪽에서 사용하기위해 데이터를 가공함.
private ColorState StringToColorState(string color)
{
ColorState val = new ColorState();
Color clr = StringToColor(color);
val.RGB_R = clr.R / 255.0;
val.RGB_G = clr.G / 255.0;
val.RGB_B = clr.B / 255.0;
val.A = clr.A / 255.0;
return val;
}
StringToColorState함수를 호출하는데 문자열로 저장한 색상값 정수를 실수로 변경하는 과정이 들어감.
내 "색상값 / 255" 즉, 0~1 사이의 값으로 변환.
해당 ColorPicker에서 ColorChanged 이벤트가 있는데 Mvvm패턴을 사용해서 사용하는 방법을 몰라서 버튼을 눌렀을때 데이터를 저장하는 방식으로 사용하였습니다.
private DelegateCommand commandsavecolors;
public DelegateCommand CommandSaveColors =>
commandsavecolors ?? (commandsavecolors = new DelegateCommand(ExecuteCommandSaveColors));
void ExecuteCommandSaveColors()
{
for(int i = 0; i < MyColors.Count; i++)
{
MyColors[i].NowColor = ColorToString(ColorStateToColor(MyColors[i].ClrState));
if (MyColors[i].NowColor != MyColors[i].PreColor)
MyColors[i].IsChanged = true;
}
bool _b = false;
foreach(var v in MyColors)
{
if (v.IsChanged)
{
_b = true;
PublicColor.Colors.Colorinstance.SetColor(v.Key, v.NowColor);
}
}
if (_b)
{
PublicColor.Colors.Colorinstance.SetColor();
MessageBox.Show("변경완료");
}
}
구조를 만들때 저장되기 전값과 현재값을 동시에 저장해놓고 색을 변경했을때 현재값을 변경하는 방식을 사용해서 변경된 데이터만 따로 수정해서 저장함.
반응형
'C# > 코인프로그램 - 코드' 카테고리의 다른 글
[C#/WPF/수정] Upbit 프로젝트 Chart 매수 매도 선 추가 (1) | 2023.12.08 |
---|---|
[C#/WPF/수정] Upbit프로젝트 Balance 타이머 추가 (1) | 2023.12.08 |
[C#/WPF/수정] Upbit프로젝트 Balance (1) | 2023.12.05 |
[C#/WPF] Upbit 프로젝트 JWT (2) | 2023.12.03 |
[C#/WPF] Upbit 프로젝트 Chart - 7(Converter) (0) | 2023.12.03 |