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 : CustomControlBase { public static readonly DependencyProperty KeyHorizontalAlignmentProperty = DependencyProperty.Register( nameof(KeyHorizontalAlignment), typeof(HorizontalAlignment), typeof(UCKeyValueBase), 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), 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; control?.KeyTextChanged((string)e.NewValue); } public static readonly DependencyProperty KeyTextSizeProperty = DependencyProperty.Register( nameof(KeyTextSize), typeof(double), typeof(UCKeyValueBase), 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), 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), 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), 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), 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)?.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), 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), 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), 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), 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 : UCKeyValueBase { protected readonly CultureInfo Culture; public static readonly DependencyProperty ValueProperty = DependencyProperty.Register( nameof(Value), typeof(decimal), typeof(UCKeyValueNumber), 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)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), 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)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), 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)d; control.InvalidateProperty(ValueProperty); } public static readonly DependencyProperty UnitProperty = DependencyProperty.Register(nameof(Unit), typeof(string), typeof(UCKeyValueNumber), 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), 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; } } }