@@ -20,40 +20,42 @@ public static class TextBoxEx
2020 typeof ( TextBoxEx ) ,
2121 new ( default ( bool ) , OnUpdateBindingOnEnterChanged ) ) ;
2222
23+ /// <summary>Обработчик изменения свойства UpdateBindingSourceOnEnter</summary>
2324 private static void OnUpdateBindingOnEnterChanged ( DependencyObject sender , DependencyPropertyChangedEventArgs e )
2425 {
25- if ( sender is not TextBox text_box || e . NewValue is not bool value ) return ;
26+ if ( sender is not TextBox text_box || e . NewValue is not bool value ) return ;
2627
2728 if ( value )
2829 text_box . KeyDown += OnTextBoxKeyDown ;
2930 else
3031 text_box . KeyDown -= OnTextBoxKeyDown ;
3132 }
3233
34+ /// <summary>Обработчик события нажатия клавиши в TextBox</summary>
3335 private static void OnTextBoxKeyDown ( object Sender , KeyEventArgs E )
3436 {
35- if ( E . Key != Key . Enter ) return ;
37+ if ( E . Key != Key . Enter ) return ;
3638
3739 var text_box = ( TextBox ) Sender ;
3840
39- if ( text_box . AcceptsReturn && ! E . KeyboardDevice . IsKeyDown ( Key . LeftCtrl ) )
41+ if ( text_box . AcceptsReturn && ! E . KeyboardDevice . IsKeyDown ( Key . LeftCtrl ) )
4042 return ;
4143
42- if ( BindingOperations . GetBindingExpression ( text_box , TextBox . TextProperty ) is not { } binding )
44+ if ( BindingOperations . GetBindingExpression ( text_box , TextBox . TextProperty ) is not { } binding )
4345 return ;
4446
45- if ( binding . ParentBinding . UpdateSourceTrigger != UpdateSourceTrigger . Explicit && ! E . KeyboardDevice . IsKeyDown ( Key . LeftCtrl ) )
47+ if ( binding . ParentBinding . UpdateSourceTrigger != UpdateSourceTrigger . Explicit && ! E . KeyboardDevice . IsKeyDown ( Key . LeftCtrl ) )
4648 return ;
4749
4850 binding . UpdateSource ( ) ;
4951 E . Handled = true ;
5052 }
5153
52- /// <summary>Обновить привязку при нажатии Enter </summary>
54+ /// <summary>Установить значение свойства UpdateBindingSourceOnEnter </summary>
5355 [ AttachedPropertyBrowsableForType ( typeof ( TextBox ) ) ]
5456 public static void SetUpdateBindingSourceOnEnter ( DependencyObject d , bool value ) => d . SetValue ( UpdateBindingSourceOnEnterProperty , value ) ;
5557
56- /// <summary>Обновить привязку при нажатии Enter </summary>
58+ /// <summary>Получить значение свойства UpdateBindingSourceOnEnter </summary>
5759 public static bool GetUpdateBindingSourceOnEnter ( DependencyObject d ) => ( bool ) d . GetValue ( UpdateBindingSourceOnEnterProperty ) ;
5860
5961 #endregion
@@ -66,21 +68,23 @@ private static void OnTextBoxKeyDown(object Sender, KeyEventArgs E)
6668 "ValidateInputScope" ,
6769 typeof ( bool ) ,
6870 typeof ( TextBoxEx ) ,
69- new ( default ( bool ) , OnValidateInputScopeChanged ) ) ;
71+ new ( false , OnValidateInputScopeChanged ) ) ;
7072
73+ /// <summary>Обработчик изменения свойства ValidateInputScope</summary>
7174 private static void OnValidateInputScopeChanged ( DependencyObject obj , DependencyPropertyChangedEventArgs e )
7275 {
73- if ( obj is not TextBox text_box || e . NewValue is not bool value ) return ;
76+ if ( obj is not TextBox text_box || e . NewValue is not bool value ) return ;
7477
7578 if ( value )
7679 text_box . PreviewTextInput += ValidateScopes_OnPreviewTextInput ;
7780 else
7881 text_box . PreviewTextInput -= ValidateScopes_OnPreviewTextInput ;
7982 }
8083
84+ /// <summary>Обработчик события предварительного ввода текста в TextBox</summary>
8185 private static void ValidateScopes_OnPreviewTextInput ( object Sender , TextCompositionEventArgs E )
8286 {
83- if ( Sender is not TextBox { InputScope : { } input_scope , Text : var current_text } text_box ) return ;
87+ if ( Sender is not TextBox { InputScope : { } input_scope , Text : var current_text } text_box ) return ;
8488
8589 var input_text = E . Text ;
8690 var full_text = current_text + input_text ;
@@ -95,20 +99,20 @@ private static void ValidateScopes_OnPreviewTextInput(object Sender, TextComposi
9599 case InputScopeNameValue . FullFilePath when Path . GetInvalidPathChars ( ) . Any ( c => input_text . Contains ( c ) ) :
96100 case InputScopeNameValue . FileName when Path . GetInvalidFileNameChars ( ) . Any ( c => input_text . Contains ( c ) ) :
97101 case InputScopeNameValue . DateDayName when full_text . ToLower ( ) is not (
98- "sunday" or "sun" or "su" or
102+ "sunday" or "sun" or "su" or
99103 "monday" or "mon" or "mo" or
100104 "tuesday" or "tue" or "tu" or
101105 "wednesday" or "wed" or "wd" or
102106 "thursday" or "thu" or "th" or
103107 "friday" or "fri" or "fr" or
104- "saturday" or "sat" or "st" or
108+ "saturday" or "sat" or "st" or
105109 "понедельник" or "пон" or "пн" or
106110 "вторник" or "втр" or "вт" or
107111 "среда" or "срд" or "ср" or
108112 "четверг" or "чет" or "чт" or
109113 "пятница" or "пят" or "пт" or
110114 "суббота" or "суб" or "сб" or
111- "воскресенье" or "вос" or "вс"
115+ "воскресенье" or "вос" or "вс"
112116 ) :
113117 case InputScopeNameValue . DateDay when ! int . TryParse ( full_text , out var day ) && day is not ( >= 1 and <= 31 ) :
114118 case InputScopeNameValue . DateMonth when ! int . TryParse ( full_text , out var month ) && month is not ( >= 1 and <= 12 ) :
@@ -120,15 +124,15 @@ private static void ValidateScopes_OnPreviewTextInput(object Sender, TextComposi
120124 return ;
121125 }
122126
123- if ( full_text . Length > 0 && input_scope . RegularExpression is { Length : > 0 } regex_str && ! Regex . IsMatch ( full_text , regex_str ) )
127+ if ( full_text . Length > 0 && input_scope . RegularExpression is { Length : > 0 } regex_str && ! Regex . IsMatch ( full_text , regex_str ) )
124128 E . Handled = true ;
125129 }
126130
127- /// <summary>Проверять корректность правил InputScope </summary>
131+ /// <summary>Установить значение свойства ValidateInputScope </summary>
128132 [ AttachedPropertyBrowsableForType ( typeof ( TextBox ) ) ]
129133 public static void SetValidateInputScope ( DependencyObject d , bool value ) => d . SetValue ( ValidateInputScopeProperty , value ) ;
130134
131- /// <summary>Проверять корректность правил InputScope </summary>
135+ /// <summary>Получить значение свойства ValidateInputScope </summary>
132136 public static bool GetValidateInputScope ( DependencyObject d ) => ( bool ) d . GetValue ( ValidateInputScopeProperty ) ;
133137
134138 #endregion
@@ -143,19 +147,25 @@ private static void ValidateScopes_OnPreviewTextInput(object Sender, TextComposi
143147 typeof ( TextBoxEx ) ,
144148 new ( decimal . Zero , OnMouseWheelIncrementChanged ) ) ;
145149
150+ /// <summary>Обработчик изменения свойства MouseWheelIncrement</summary>
146151 private static void OnMouseWheelIncrementChanged ( DependencyObject s , DependencyPropertyChangedEventArgs e )
147152 {
148- if ( e is { OldValue : decimal . Zero , NewValue : not decimal . Zero } )
149- ( ( TextBox ) s ) . MouseWheel += OnMouseWheel ;
150- else if ( e is { OldValue : not decimal . Zero , NewValue : decimal . Zero } )
151- ( ( TextBox ) s ) . MouseWheel -= OnMouseWheel ;
153+ switch ( e )
154+ {
155+ case { OldValue : decimal . Zero , NewValue : not decimal . Zero } :
156+ ( ( TextBox ) s ) . MouseWheel += OnMouseWheel ;
157+ break ;
158+ case { OldValue : not decimal . Zero , NewValue : decimal . Zero } :
159+ ( ( TextBox ) s ) . MouseWheel -= OnMouseWheel ;
160+ break ;
161+ }
152162 }
153163
154- /// <summary>Инкремент колёсика мышки </summary>
164+ /// <summary>Установить значение свойства MouseWheelIncrement </summary>
155165 [ AttachedPropertyBrowsableForType ( typeof ( TextBox ) ) ]
156166 public static void SetMouseWheelIncrement ( DependencyObject d , decimal value ) => d . SetValue ( MouseWheelIncrementProperty , value ) ;
157167
158- /// <summary>Инкремент колёсика мышки </summary>
168+ /// <summary>Получить значение свойства MouseWheelIncrement </summary>
159169 public static decimal GetMouseWheelIncrement ( DependencyObject d ) => ( decimal ) d . GetValue ( MouseWheelIncrementProperty ) ;
160170
161171 #endregion
@@ -170,15 +180,16 @@ private static void OnMouseWheelIncrementChanged(DependencyObject s, DependencyP
170180 typeof ( TextBoxEx ) ,
171181 new ( 0.1m ) ) ;
172182
173- /// <summary>Инкремент колёсика мышки </summary>
183+ /// <summary>Установить значение свойства MouseWheelIncrementCtrlRatio </summary>
174184 [ AttachedPropertyBrowsableForType ( typeof ( TextBox ) ) ]
175185 public static void SetMouseWheelIncrementCtrlRatio ( DependencyObject d , decimal value ) => d . SetValue ( MouseWheelIncrementCtrlRatioProperty , value ) ;
176186
177- /// <summary>Инкремент колёсика мышки </summary>
187+ /// <summary>Получить значение свойства MouseWheelIncrementCtrlRatio </summary>
178188 public static decimal GetMouseWheelIncrementCtrlRatio ( DependencyObject d ) => ( decimal ) d . GetValue ( MouseWheelIncrementCtrlRatioProperty ) ;
179189
180190 #endregion
181191
192+ /// <summary>Обработчик события прокрутки колёсика мыши в TextBox</summary>
182193 private static void OnMouseWheel ( object Sender , MouseWheelEventArgs E )
183194 {
184195 if ( Sender is not TextBox { Text : var text } text_block ) return ;
@@ -195,4 +206,58 @@ private static void OnMouseWheel(object Sender, MouseWheelEventArgs E)
195206 var new_value_text = new_value . ToString ( CultureInfo . InvariantCulture ) ;
196207 text_block . Text = new_value_text ;
197208 }
209+
210+ #region Attached property AutoSelectAll : bool - Автовыбор всего содержимого TextBox
211+
212+ /// <summary>Авто выбор всего содержимого TextBox</summary>
213+ public static readonly DependencyProperty AutoSelectAllProperty =
214+ DependencyProperty . RegisterAttached (
215+ "AutoSelectAll" ,
216+ typeof ( bool ) ,
217+ typeof ( TextBoxEx ) ,
218+ new ( false , OnAutoSelectAllChanged ) ) ;
219+
220+ /// <summary>Обработчик изменения свойства AutoSelectAll</summary>
221+ private static void OnAutoSelectAllChanged ( DependencyObject d , DependencyPropertyChangedEventArgs e )
222+ {
223+ if ( d is not TextBox text_box ) return ;
224+
225+ if ( ( bool ) e . NewValue )
226+ {
227+ text_box . PreviewMouseDown += OnTextBoxPreviewMouseDown ;
228+ text_box . GotKeyboardFocus += OnTextBoxGotKeyboardFocus ;
229+ }
230+ else
231+ {
232+ text_box . PreviewMouseDown -= OnTextBoxPreviewMouseDown ;
233+ text_box . GotKeyboardFocus -= OnTextBoxGotKeyboardFocus ;
234+ }
235+ }
236+
237+ /// <summary>Обработчик события предварительного нажатия мыши в TextBox</summary>
238+ private static void OnTextBoxPreviewMouseDown ( object sender , MouseButtonEventArgs e )
239+ {
240+ if ( sender is not TextBox text_box || text_box . IsKeyboardFocusWithin ) return ;
241+
242+ text_box . Focus ( ) ;
243+ e . Handled = true ;
244+ }
245+
246+ /// <summary>Обработчик события получения фокуса клавиатуры в TextBox</summary>
247+ private static void OnTextBoxGotKeyboardFocus ( object sender , RoutedEventArgs e )
248+ {
249+ if ( sender is not TextBox text_box ) return ;
250+
251+ text_box . SelectAll ( ) ;
252+ e . Handled = true ;
253+ }
254+
255+ /// <summary>Установить значение свойства AutoSelectAll</summary>
256+ [ AttachedPropertyBrowsableForType ( typeof ( TextBox ) ) ]
257+ public static void SetAutoSelectAll ( DependencyObject d , bool value ) => d . SetValue ( AutoSelectAllProperty , value ) ;
258+
259+ /// <summary>Получить значение свойства AutoSelectAll</summary>
260+ public static bool GetAutoSelectAll ( DependencyObject d ) => ( bool ) d . GetValue ( AutoSelectAllProperty ) ;
261+
262+ #endregion
198263}
0 commit comments