using AuroraUIComponent.UserControls.Dialog; using System; using System.Globalization; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; namespace AuroraUIComponent.UserControls { public abstract class CustomControlBase : Control { static CustomControlBase() { DefaultStyleKeyProperty.OverrideMetadata(typeof(TSubClass), new FrameworkPropertyMetadata(typeof(TSubClass))); LoadResourceDictionary(); } private static void LoadResourceDictionary() { Uri resourceLocater = new Uri($"/AuroraUIComponent;component/UserControls/Input/{typeof(TSubClass).Name}Resources.xaml", UriKind.Relative); ResourceDictionary resourceDictionary = new ResourceDictionary { Source = resourceLocater }; Application.Current.Resources.MergedDictionaries.Add(resourceDictionary); } public override void OnApplyTemplate() { base.OnApplyTemplate(); InitializeControlReferences(); InitializeControls(); } protected abstract void InitializeControlReferences(); protected abstract void InitializeControls(); protected TType GetChild(string xamlElementName) { return (TType)Convert.ChangeType(GetTemplateChild(xamlElementName), typeof(TType)); } } public class UCNumericTextBox : UCKeyValueNumber { private static readonly Thickness UnitPadding = new Thickness(2, 0, 15, 0); private string _rangeStr; public static readonly DependencyProperty MaximumProperty = DependencyProperty.Register( nameof(Maximum), typeof(decimal), typeof(UCNumericTextBox), new PropertyMetadata( decimal.MaxValue, OnMaximumChanged, CoerceMaximumCallback) ); public decimal Maximum { get { return (decimal)GetValue(MaximumProperty); } set { SetValue(MaximumProperty, value); } } private static void OnMaximumChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var control = (UCNumericTextBox)d; var maxValue = (decimal)e.NewValue; // If maxValue steps over Minimum, shift it if (maxValue < control.Minimum) { control.Minimum = maxValue; } // desired 값이 경계 내에 존재하도록 강제하는 로직.. if (maxValue <= control.Value) { control.Value = maxValue; } } private static object CoerceMaximumCallback(DependencyObject d, object baseValue) { var control = (UCNumericTextBox)d; var maxValue = (decimal)baseValue; control.SetMaximum = true; return maxValue; } public static readonly DependencyProperty MinimumProperty = DependencyProperty.Register( nameof(Minimum), typeof(decimal), typeof(UCNumericTextBox), new PropertyMetadata( Decimal.MinValue, OnMinimumChanged, CoerceMinimumCallback) ); public decimal Minimum { get { return (decimal)GetValue(MinimumProperty); } set { SetValue(MinimumProperty, value); } } private static void OnMinimumChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var control = (UCNumericTextBox)d; var minValue = (decimal)e.NewValue; // If minValue steps over Maximum, shift it if (minValue > control.Maximum) { control.Maximum = minValue; } if (minValue >= control.Value) { control.Value = minValue; } } private static object CoerceMinimumCallback(DependencyObject d, object baseValue) { var control = (UCNumericTextBox)d; var minValue = (decimal)baseValue; control.SetMinimum = true; return minValue; } // min, max 둘 중 하나 이상 설정됐을 때만 Tooltip 보임 private bool _setMinimum; public bool SetMinimum { get => _setMinimum; set { _setMinimum = value; } } private bool _setMaximum; public bool SetMaximum { get => _setMaximum; set { _setMaximum = value; } } private void UpdateTooltipRange() { if (SetMinimum || SetMaximum) { StringBuilder range = new StringBuilder(); if (SetMinimum) range.Append("Min: ").Append(Minimum); if (SetMinimum && SetMaximum) range.Append(", "); if (SetMaximum) range.Append("Max: ").Append(Maximum); _rangeStr = range.ToString(); } } private Grid _gridParent; private TextBlock _textKey; private TextBox _textValue; private Button _buttonMouse; private ToolTip _tooltipRange; private Border _borderKey; private TextBlock _textUnit; private Border _valueBorder; public UCNumericTextBox() { Loaded += OnControlLoaded; DataContextChanged += OnDataContextChanged; } private void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e) { UpdateLayout(); } protected void OnControlLoaded(object sender, RoutedEventArgs e) { UpdateLayout(); } protected override void InitializeControlReferences() { // class 내에서 참조할 Control들의 레퍼런스를 업데이트 (미리 변수 선언 필요) _gridParent = GetChild("GridParent"); _textKey = GetChild("TextKey"); _textValue = GetChild("TextValue"); _buttonMouse = GetChild