355 lines
14 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|