2026-01-26 18:56:53 +09:00

355 lines
14 KiB
C#

using AuroraUIComponent.Dialog;
using System;
using System.Globalization;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace AuroraUIComponent.UserControls
{
public abstract class UCKeyValueBase<TSubClass> : CustomControlBase<TSubClass>
{
public static readonly DependencyProperty KeyHorizontalAlignmentProperty
= DependencyProperty.Register(
nameof(KeyHorizontalAlignment),
typeof(HorizontalAlignment),
typeof(UCKeyValueBase<TSubClass>),
new PropertyMetadata(HorizontalAlignment.Left));
public HorizontalAlignment KeyHorizontalAlignment {
get { return (HorizontalAlignment)GetValue(KeyHorizontalAlignmentProperty); }
set { SetValue(KeyHorizontalAlignmentProperty, value); }
}
public static readonly DependencyProperty KeyTextProperty
= DependencyProperty.Register(
nameof(KeyText),
typeof(string),
typeof(UCKeyValueBase<TSubClass>),
new PropertyMetadata(null, OnKeyTextChanged));
public string KeyText {
get { return (string)GetValue(KeyTextProperty); }
set { SetValue(KeyTextProperty, value); }
}
private static void OnKeyTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = d as UCKeyValueBase<TSubClass>;
control?.KeyTextChanged((string)e.NewValue);
}
public static readonly DependencyProperty KeyTextSizeProperty
= DependencyProperty.Register(
nameof(KeyTextSize),
typeof(double),
typeof(UCKeyValueBase<TSubClass>),
new FrameworkPropertyMetadata(
UCCommonDef.UCKeyValueCommon.DEFAULT_FONTSIZE_KEY,
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
public double KeyTextSize {
get { return (double)GetValue(KeyTextSizeProperty); }
set { SetValue(KeyTextSizeProperty, value); }
}
public static readonly DependencyProperty ValueTextSizeProperty
= DependencyProperty.Register(
nameof(ValueTextSize),
typeof(double),
typeof(UCKeyValueBase<TSubClass>),
new FrameworkPropertyMetadata(
UCCommonDef.UCKeyValueCommon.DEFAULT_FONTSIZE_VALUE,
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
public double ValueTextSize {
get { return (double)GetValue(ValueTextSizeProperty); }
set { SetValue(ValueTextSizeProperty, value); }
}
public static readonly DependencyProperty KeyTextWidthProperty
= DependencyProperty.Register(
nameof(KeyTextWidth),
typeof(string),
typeof(UCKeyValueBase<TSubClass>),
new FrameworkPropertyMetadata(
UCCommonDef.UCKeyValueCommon.DEFAULT_WIDTH_KEY,
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
public string KeyTextWidth {
get { return (string)GetValue(KeyTextWidthProperty); }
set { SetValue(KeyTextWidthProperty, value); }
}
public static readonly DependencyProperty ValueTextWidthProperty
= DependencyProperty.Register(
nameof(ValueTextWidth),
typeof(string),
typeof(UCKeyValueBase<TSubClass>),
new FrameworkPropertyMetadata(
UCCommonDef.UCKeyValueCommon.DEFAULT_WIDTH_VALUE,
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
public string ValueTextWidth {
get { return (string)GetValue(ValueTextWidthProperty); }
set { SetValue(ValueTextWidthProperty, value); }
}
public static readonly DependencyProperty KeyTextFgColorProperty
= DependencyProperty.Register(
nameof(KeyTextFgColor),
typeof(SolidColorBrush),
typeof(UCKeyValueBase<TSubClass>),
new PropertyMetadata((SolidColorBrush)Application.Current.Resources["DefaultKeyTextColor"], OnKeyTextFGColorChanged));
protected abstract void KeyTextFGColorChanged(Brush brush);
private static void OnKeyTextFGColorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as UCKeyValueBase<TSubClass>)?.KeyTextFGColorChanged(e.NewValue as Brush);
}
public SolidColorBrush KeyTextFgColor {
get { return (SolidColorBrush)GetValue(KeyTextFgColorProperty); }
set { SetValue(KeyTextFgColorProperty, value); }
}
public static readonly DependencyProperty ValueTextFgColorProperty
= DependencyProperty.Register(
nameof(ValueTextFgColor),
typeof(SolidColorBrush),
typeof(UCKeyValueBase<TSubClass>),
new FrameworkPropertyMetadata(
Brushes.White,
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
public SolidColorBrush ValueTextFgColor {
get { return (SolidColorBrush)GetValue(ValueTextFgColorProperty); }
set { SetValue(ValueTextFgColorProperty, value); }
}
public static readonly DependencyProperty KeyTextBgColorProperty
= DependencyProperty.Register(
nameof(KeyTextBgColor),
typeof(SolidColorBrush),
typeof(UCKeyValueBase<TSubClass>),
new FrameworkPropertyMetadata(
Brushes.Transparent,
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
public SolidColorBrush KeyTextBgColor {
get { return (SolidColorBrush)GetValue(KeyTextBgColorProperty); }
set { SetValue(KeyTextBgColorProperty, value); }
}
public static readonly DependencyProperty ValueTextBgColorProperty
= DependencyProperty.Register(
nameof(ValueTextBgColor),
typeof(SolidColorBrush),
typeof(UCKeyValueBase<TSubClass>),
new FrameworkPropertyMetadata(
Brushes.Transparent,
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
public SolidColorBrush ValueTextBgColor {
get { return (SolidColorBrush)GetValue(ValueTextBgColorProperty); }
set { SetValue(ValueTextBgColorProperty, value); }
}
public static readonly DependencyProperty IsReadOnlyProperty
= DependencyProperty.Register(
nameof(IsReadOnly),
typeof(bool),
typeof(UCKeyValueBase<TSubClass>),
new FrameworkPropertyMetadata(
false,
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
public bool IsReadOnly {
get { return (bool)GetValue(IsReadOnlyProperty); }
set { SetValue(IsReadOnlyProperty, value); }
}
protected abstract void KeyTextChanged(string newValue);
}
public abstract class UCKeyValueNumber<TSubClass> : UCKeyValueBase<TSubClass>
{
protected readonly CultureInfo Culture;
public static readonly DependencyProperty ValueProperty
= DependencyProperty.Register(
nameof(Value),
typeof(decimal),
typeof(UCKeyValueNumber<TSubClass>),
new FrameworkPropertyMetadata(
0m, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, null, CoerceValueCallback)
);
public decimal Value {
get { return (decimal)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
private static object CoerceValueCallback(DependencyObject d, object baseValue)
{
var control = (UCKeyValueNumber<TSubClass>)d;
var value = (decimal)baseValue;
return control.CoerceValueAndUpdate(value);
}
protected decimal CoerceValueAndUpdate(decimal value)
{
CoerceValue2Bounds(ref value);
// Get the text representation of Value
var valueString = value.ToString(Culture);
// Count all decimal places
var decimalPlaces = GetDecimalPlacesCount(valueString);
if (decimalPlaces > DecimalPlaces) {
// Remove all overflowing decimal places
value = TruncateValue(valueString, decimalPlaces);
}
ChangeThousandSeparator(value);
return value;
}
public static readonly DependencyProperty DecimalPlacesProperty =
DependencyProperty.Register(
nameof(DecimalPlaces),
typeof(int),
typeof(UCKeyValueNumber<TSubClass>),
new PropertyMetadata(
0, OnDecimalPlacesChanged, CoerceDecimalPlacesCallback)
);
private static object CoerceDecimalPlacesCallback(DependencyObject d, object baseValue)
{
var decimalPlaces = (int)baseValue;
if (decimalPlaces < 0) {
decimalPlaces = 0;
} else if (decimalPlaces > 28) {
decimalPlaces = 28;
}
return decimalPlaces;
}
public int DecimalPlaces {
get { return (int)GetValue(DecimalPlacesProperty); }
set { SetValue(DecimalPlacesProperty, value); }
}
private static void OnDecimalPlacesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = (UCKeyValueNumber<TSubClass>)d;
var decimalPlaces = (int)e.NewValue;
control.Culture.NumberFormat.NumberDecimalDigits = decimalPlaces;
// tell Value to invalidate itself (run the CoerceValueCallback() method again)
control.InvalidateProperty(ValueProperty);
}
public static readonly DependencyProperty ThousandSeparatorProperty =
DependencyProperty.Register(
nameof(ThousandSeparator),
typeof(bool),
typeof(UCKeyValueNumber<TSubClass>),
new PropertyMetadata(
false, OnIsThousandSeperatorVisibleChanged)
);
public bool ThousandSeparator {
get { return (bool)GetValue(ThousandSeparatorProperty); }
set { SetValue(ThousandSeparatorProperty, value); }
}
private static void OnIsThousandSeperatorVisibleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = (UCKeyValueNumber<TSubClass>)d;
control.InvalidateProperty(ValueProperty);
}
public static readonly DependencyProperty UnitProperty
= DependencyProperty.Register(nameof(Unit),
typeof(string),
typeof(UCKeyValueNumber<TSubClass>),
new FrameworkPropertyMetadata(
null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
public string Unit {
get { return (string)GetValue(UnitProperty); }
set { SetValue(UnitProperty, value); }
}
public static readonly DependencyProperty ShowKeypadProperty
= DependencyProperty.Register(nameof(ShowKeypad), typeof(bool), typeof(UCKeyValueNumber<TSubClass>),
new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
public bool ShowKeypad {
get { return (bool)GetValue(ShowKeypadProperty); }
set { SetValue(ShowKeypadProperty, value); }
}
public UCKeyValueNumber()
{
//===============
// 국가마다 숫자 표기 (특히 소수점)가 다르므로, 소수점 표기 관련
Culture = (CultureInfo)CultureInfo.CurrentCulture.Clone(); // 복사
// 소수점 속성 변경
Culture.NumberFormat.NumberDecimalDigits = DecimalPlaces;
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
CoerceValueAndUpdate(Value); // TextValue.Text Update
}
public int GetDecimalPlacesCount(String valueString)
{
// 첫번째 소수점을 찾은 후, counts all characters that follow
return valueString.SkipWhile(c => c.ToString(Culture) != Culture.NumberFormat.NumberDecimalSeparator).Skip(1).Count();
}
private decimal TruncateValue(string valueString, int decimalPlaces)
{
var endPoint = valueString.Length - (decimalPlaces - DecimalPlaces);
var tempValueString = valueString.Substring(0, endPoint);
return decimal.Parse(tempValueString, Culture);
}
protected abstract void ChangeThousandSeparator(decimal value);
private void KBDWindowResult(string strValue)
{
Value = Convert.ToDecimal(strValue);
}
private void CoerceValue2Bounds(ref decimal value)
{
}
protected decimal ParseString2Decimal(string source)
{
_ = decimal.TryParse(source, out decimal value);
return value;
}
}
}