Dreamine.UI.Wpf.Controls
1.0.1
Dreamine.UI.Wpf.Controls 사용자 인터페이스 기능과 구성 요소를 제공합니다.
Toggle main menu visibility
로딩중...
검색중...
일치하는것 없음
DreamineTextBox.cs
이 파일의 문서화 페이지로 가기
1
// =====================================================================
2
// \file DreamineTextBox.cs
3
// \brief VsLibrary용 커스텀 TextBox. Hint/Error + CommandTrigger + Enter Focus UX 지원.
4
// =====================================================================
5
6
using
System;
7
using
System.Linq;
8
using
System.Windows;
9
using
System.Windows.Controls;
10
using
System.Windows.Controls.Primitives;
11
using
System.Windows.Input;
12
using
System.Windows.Media;
13
14
namespace
Dreamine.UI.Wpf.Controls
15
{
24
public
class
DreamineTextBox
: TextBox
25
{
34
private
IInputElement?
_previousFocusedElement
;
35
44
static
DreamineTextBox
()
45
{
46
DefaultStyleKeyProperty.OverrideMetadata(typeof(
DreamineTextBox
),
47
new
FrameworkPropertyMetadata(typeof(
DreamineTextBox
)));
48
49
var uri =
new
Uri(
"/Dreamine.UI.Wpf.Themes;component/DreamineTextBoxStyle.xaml"
, UriKind.RelativeOrAbsolute);
50
51
if
(Application.Current !=
null
)
52
{
53
bool
alreadyAdded = Application.Current.Resources.MergedDictionaries
54
.OfType<ResourceDictionary>()
55
.Any(x => x.Source !=
null
&& x.Source.Equals(uri));
56
57
if
(!alreadyAdded)
58
{
59
var dict =
new
ResourceDictionary { Source = uri };
60
Application.Current.Resources.MergedDictionaries.Add(dict);
61
}
62
}
63
}
64
81
public
DreamineTextBox
()
82
{
83
// \brief Enter 복귀를 위해 이전 포커스 저장
84
GotKeyboardFocus +=
OnGotKeyboardFocus_StorePreviousFocus
;
85
}
86
111
private
void
OnGotKeyboardFocus_StorePreviousFocus
(
object
sender, KeyboardFocusChangedEventArgs e)
112
{
113
// \brief OldFocus가 Window/ContentControl로 들어오는 경우가 있으므로 교정
114
var old = e.OldFocus;
115
116
if
(old is
null
)
117
{
118
_previousFocusedElement
=
null
;
119
return
;
120
}
121
122
if
(ReferenceEquals(old,
this
))
123
{
124
// \brief 자기 자신이면 의미 없음
125
return
;
126
}
127
128
if
(old is DependencyObject dobj)
129
{
130
if
(old is Window || old is ContentControl)
131
{
132
var child =
FindFirstFocusableChild
(dobj);
133
_previousFocusedElement
= child ?? old;
134
return
;
135
}
136
}
137
138
_previousFocusedElement
= old;
139
}
140
173
protected
override
void
OnPreviewKeyDown
(KeyEventArgs e)
174
{
175
base.OnPreviewKeyDown(e);
176
177
if
(e.Key != Key.Enter)
178
return
;
179
180
var target =
_previousFocusedElement
;
181
182
if
(target ==
null
|| ReferenceEquals(target,
this
))
183
return
;
184
185
// \brief Enter 키 입력은 여기서 소비
186
e.Handled =
true
;
187
188
// \brief 이벤트 파이프라인/내부 TextBox 처리 후 포커스 이동
189
Dispatcher.BeginInvoke(
new
Action(() =>
190
{
191
try
192
{
193
// \brief UIElement이면 Focus()가 더 잘 먹는 경우가 많음
194
if
(target is UIElement uie)
195
{
196
uie.Focus();
197
Keyboard.Focus(uie);
198
return
;
199
}
200
201
Keyboard.Focus(target);
202
}
203
catch
204
{
205
// \brief 포커스 실패는 치명적이지 않으므로 무시(정책에 맞게 로그로 바꿔도 됨)
206
}
207
}), System.Windows.Threading.DispatcherPriority.Input);
208
}
209
242
private
UIElement?
FindFirstFocusableChild
(DependencyObject parent)
243
{
244
for
(
int
i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
245
{
246
var child = VisualTreeHelper.GetChild(parent, i);
247
248
if
(child is UIElement uie && uie.Focusable && uie.IsVisible && uie.IsEnabled)
249
return
uie;
250
251
var result =
FindFirstFocusableChild
(child);
252
if
(result !=
null
)
253
return
result;
254
}
255
return
null
;
256
}
257
258
// =====================================================================
259
// Attached Command: Command / CommandParameter / CommandTriggerName
260
// =====================================================================
261
270
public
static
readonly DependencyProperty
CommandProperty
=
271
DependencyProperty.RegisterAttached(
272
"Command"
,
273
typeof(ICommand),
274
typeof(
DreamineTextBox
),
275
new
PropertyMetadata(
null
,
OnCommandChanged
));
276
285
public
static
readonly DependencyProperty
CommandParameterProperty
=
286
DependencyProperty.RegisterAttached(
287
"CommandParameter"
,
288
typeof(
object
),
289
typeof(
DreamineTextBox
),
290
new
PropertyMetadata(
null
));
291
300
public
static
readonly DependencyProperty
CommandTriggerNameProperty
=
301
DependencyProperty.RegisterAttached(
302
"CommandTriggerName"
,
303
typeof(
string
),
304
typeof(
DreamineTextBox
),
305
new
PropertyMetadata(
null
));
306
339
public
static
void
SetCommandTriggerName
(DependencyObject obj,
string
value)
340
=> obj.SetValue(
CommandTriggerNameProperty
, value);
341
374
public
static
string
GetCommandTriggerName
(DependencyObject obj)
375
=> (string)obj.GetValue(
CommandTriggerNameProperty
);
376
409
public
static
void
SetCommand
(DependencyObject obj, ICommand value)
410
=> obj.SetValue(
CommandProperty
, value);
411
452
public
static
ICommand
GetCommand
(DependencyObject obj)
453
=> (ICommand)obj.GetValue(
CommandProperty
);
454
487
public
static
void
SetCommandParameter
(DependencyObject obj,
object
value)
488
=> obj.SetValue(
CommandParameterProperty
, value);
489
522
public
static
object
GetCommandParameter
(DependencyObject obj)
523
=> obj.GetValue(
CommandParameterProperty
);
524
557
private
static
void
OnCommandChanged
(DependencyObject d, DependencyPropertyChangedEventArgs e)
558
{
559
if
(d is not UIElement element)
560
return
;
561
562
element.AddHandler(UIElement.PreviewMouseUpEvent,
new
MouseButtonEventHandler((s, args) =>
563
{
564
TryExecuteCommand
(d,
"PreviewMouseUp"
, args);
565
}),
true
);
566
567
element.AddHandler(Control.MouseDoubleClickEvent,
new
MouseButtonEventHandler((s, args) =>
568
{
569
TryExecuteCommand
(d,
"MouseDoubleClick"
, args);
570
}),
true
);
571
572
element.AddHandler(UIElement.PreviewKeyDownEvent,
new
KeyEventHandler((s, args) =>
573
{
574
// \brief 기존 규칙 유지: PreviewKeyDown 훅이지만 이름은 "PreviewKeyUp"
575
TryExecuteCommand
(d,
"PreviewKeyUp"
, args);
576
}),
true
);
577
578
element.AddHandler(UIElement.TouchUpEvent,
new
EventHandler<TouchEventArgs>((s, args) =>
579
{
580
TryExecuteCommand(d,
"TouchUp"
, args);
581
}));
582
583
element.AddHandler(ButtonBase.ClickEvent,
new
RoutedEventHandler((s, args) =>
584
{
585
TryExecuteCommand
(d,
"Click"
, args);
586
}));
587
588
element.AddHandler(TextBox.TextChangedEvent,
new
TextChangedEventHandler((s, args) =>
589
{
590
TryExecuteCommand
(d,
"TextChanged"
, args);
591
}));
592
}
593
634
private
static
void
TryExecuteCommand
(DependencyObject d,
string
eventName, RoutedEventArgs eventArgs)
635
{
636
var rawTrigger =
GetCommandTriggerName
(d);
637
if
(
string
.IsNullOrEmpty(rawTrigger))
638
return
;
639
640
var triggerList = rawTrigger.Split(
','
)
641
.Select(x => x.Trim())
642
.Where(x => !
string
.IsNullOrEmpty(x));
643
644
if
(!triggerList.Contains(eventName, StringComparer.OrdinalIgnoreCase))
645
return
;
646
647
var command =
GetCommand
(d);
648
var parameter =
GetCommandParameter
(d) ?? eventArgs;
649
650
if
(command?.CanExecute(parameter) ==
true
)
651
command.Execute(parameter);
652
}
653
654
// =====================================================================
655
// Hint / Error
656
// =====================================================================
657
666
public
static
readonly DependencyProperty
HintProperty
=
667
DependencyProperty.Register(nameof(
Hint
), typeof(
string
), typeof(
DreamineTextBox
),
new
PropertyMetadata(
string
.Empty));
668
677
public
string
Hint
678
{
679
get
=> (string)GetValue(
HintProperty
);
680
set
=> SetValue(
HintProperty
, value);
681
}
682
691
public
static
readonly DependencyProperty
ErrorProperty
=
692
DependencyProperty.Register(nameof(
Error
), typeof(
string
), typeof(
DreamineTextBox
),
new
PropertyMetadata(
string
.Empty));
693
702
public
string
Error
703
{
704
get
=> (string)GetValue(
ErrorProperty
);
705
set
=> SetValue(
ErrorProperty
, value);
706
}
707
}
708
}
Dreamine.UI.Wpf.Controls
Definition
DreamineCheckSelector.xaml.cs:6
Dreamine.UI.Wpf.Controls.DreamineTextBox.HintProperty
static readonly DependencyProperty HintProperty
Definition
DreamineTextBox.cs:666
Dreamine.UI.Wpf.Controls.DreamineTextBox.GetCommand
static ICommand GetCommand(DependencyObject obj)
Definition
DreamineTextBox.cs:452
Dreamine.UI.Wpf.Controls.DreamineTextBox.CommandParameterProperty
static readonly DependencyProperty CommandParameterProperty
Definition
DreamineTextBox.cs:285
Dreamine.UI.Wpf.Controls.DreamineTextBox.Error
string Error
Definition
DreamineTextBox.cs:703
Dreamine.UI.Wpf.Controls.DreamineTextBox.DreamineTextBox
DreamineTextBox()
Definition
DreamineTextBox.cs:81
Dreamine.UI.Wpf.Controls.DreamineTextBox.OnGotKeyboardFocus_StorePreviousFocus
void OnGotKeyboardFocus_StorePreviousFocus(object sender, KeyboardFocusChangedEventArgs e)
Definition
DreamineTextBox.cs:111
Dreamine.UI.Wpf.Controls.DreamineTextBox.DreamineTextBox
static DreamineTextBox()
Definition
DreamineTextBox.cs:44
Dreamine.UI.Wpf.Controls.DreamineTextBox.GetCommandTriggerName
static string GetCommandTriggerName(DependencyObject obj)
Definition
DreamineTextBox.cs:374
Dreamine.UI.Wpf.Controls.DreamineTextBox.TryExecuteCommand
static void TryExecuteCommand(DependencyObject d, string eventName, RoutedEventArgs eventArgs)
Definition
DreamineTextBox.cs:634
Dreamine.UI.Wpf.Controls.DreamineTextBox.SetCommandParameter
static void SetCommandParameter(DependencyObject obj, object value)
Definition
DreamineTextBox.cs:487
Dreamine.UI.Wpf.Controls.DreamineTextBox.Hint
string Hint
Definition
DreamineTextBox.cs:678
Dreamine.UI.Wpf.Controls.DreamineTextBox.CommandTriggerNameProperty
static readonly DependencyProperty CommandTriggerNameProperty
Definition
DreamineTextBox.cs:300
Dreamine.UI.Wpf.Controls.DreamineTextBox._previousFocusedElement
IInputElement? _previousFocusedElement
Definition
DreamineTextBox.cs:34
Dreamine.UI.Wpf.Controls.DreamineTextBox.OnCommandChanged
static void OnCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
Definition
DreamineTextBox.cs:557
Dreamine.UI.Wpf.Controls.DreamineTextBox.GetCommandParameter
static object GetCommandParameter(DependencyObject obj)
Definition
DreamineTextBox.cs:522
Dreamine.UI.Wpf.Controls.DreamineTextBox.FindFirstFocusableChild
UIElement? FindFirstFocusableChild(DependencyObject parent)
Definition
DreamineTextBox.cs:242
Dreamine.UI.Wpf.Controls.DreamineTextBox.CommandProperty
static readonly DependencyProperty CommandProperty
Definition
DreamineTextBox.cs:270
Dreamine.UI.Wpf.Controls.DreamineTextBox.OnPreviewKeyDown
override void OnPreviewKeyDown(KeyEventArgs e)
Definition
DreamineTextBox.cs:173
Dreamine.UI.Wpf.Controls.DreamineTextBox.SetCommandTriggerName
static void SetCommandTriggerName(DependencyObject obj, string value)
Definition
DreamineTextBox.cs:339
Dreamine.UI.Wpf.Controls.DreamineTextBox.ErrorProperty
static readonly DependencyProperty ErrorProperty
Definition
DreamineTextBox.cs:691
Dreamine.UI.Wpf.Controls.DreamineTextBox.SetCommand
static void SetCommand(DependencyObject obj, ICommand value)
Definition
DreamineTextBox.cs:409
Controls
DreamineTextBox.cs
다음에 의해 생성됨 :
1.17.0