1
- using System ;
1
+ using System . Linq ;
2
2
using System . Windows ;
3
3
using System . Windows . Controls ;
4
4
using System . Windows . Controls . Primitives ;
5
- using System . Windows . Media ;
5
+ using System . Windows . Documents ;
6
6
7
7
namespace MaterialDesignThemes . Wpf
8
8
{
@@ -47,7 +47,7 @@ public static Thickness GetTextBoxViewMargin(DependencyObject element)
47
47
/// Controls the visibility of the underline decoration.
48
48
/// </summary>
49
49
public static readonly DependencyProperty DecorationVisibilityProperty = DependencyProperty . RegisterAttached (
50
- "DecorationVisibility" , typeof ( Visibility ) , typeof ( TextFieldAssist ) , new PropertyMetadata ( default ( Visibility ) ) ) ;
50
+ "DecorationVisibility" , typeof ( Visibility ) , typeof ( TextFieldAssist ) , new PropertyMetadata ( default ( Visibility ) ) ) ;
51
51
52
52
/// <summary>
53
53
/// Controls the visibility of the underline decoration.
@@ -64,9 +64,140 @@ public static void SetDecorationVisibility(DependencyObject element, Visibility
64
64
/// <returns></returns>
65
65
public static Visibility GetDecorationVisibility ( DependencyObject element )
66
66
{
67
- return ( Visibility ) element . GetValue ( DecorationVisibilityProperty ) ;
67
+ return ( Visibility ) element . GetValue ( DecorationVisibilityProperty ) ;
68
68
}
69
-
69
+
70
+ /// <summary>
71
+ /// Automatially inserts spelling suggestions into the text box context menu.
72
+ /// </summary>
73
+ public static readonly DependencyProperty IncludeSpellingSuggestionsProperty = DependencyProperty . RegisterAttached (
74
+ "IncludeSpellingSuggestions" , typeof ( bool ) , typeof ( TextFieldAssist ) , new PropertyMetadata ( default ( bool ) , IncludeSpellingSuggestionsChanged ) ) ;
75
+
76
+ public static void SetIncludeSpellingSuggestions ( TextBoxBase element , bool value )
77
+ {
78
+ element . SetValue ( IncludeSpellingSuggestionsProperty , value ) ;
79
+ }
80
+
81
+ public static bool GetIncludeSpellingSuggestions ( TextBoxBase element )
82
+ {
83
+ return ( bool ) element . GetValue ( IncludeSpellingSuggestionsProperty ) ;
84
+ }
85
+
86
+ private static void IncludeSpellingSuggestionsChanged ( DependencyObject element , DependencyPropertyChangedEventArgs e )
87
+ {
88
+ var textBox = element as TextBoxBase ;
89
+ if ( textBox != null )
90
+ {
91
+ if ( ( bool ) e . NewValue )
92
+ {
93
+ textBox . ContextMenuOpening += TextBoxOnContextMenuOpening ;
94
+ textBox . ContextMenuClosing += TextBoxOnContextMenuClosing ;
95
+ }
96
+ else
97
+ {
98
+ textBox . ContextMenuOpening -= TextBoxOnContextMenuOpening ;
99
+ textBox . ContextMenuClosing -= TextBoxOnContextMenuClosing ;
100
+ }
101
+ }
102
+ }
103
+
104
+ private static void TextBoxOnContextMenuOpening ( object sender , ContextMenuEventArgs e )
105
+ {
106
+ var textBoxBase = sender as TextBoxBase ;
107
+
108
+ ContextMenu contextMenu = textBoxBase ? . ContextMenu ;
109
+ if ( contextMenu == null ) return ;
110
+
111
+ RemoveSpellingSuggestions ( contextMenu ) ;
112
+
113
+ if ( ! SpellCheck . GetIsEnabled ( textBoxBase ) ) return ;
114
+
115
+ SpellingError spellingError = GetSpellingError ( textBoxBase ) ;
116
+ if ( spellingError != null )
117
+ {
118
+ Style spellingSuggestionStyle =
119
+ contextMenu . TryFindResource ( Spelling . SpellingSuggestionMenuItemStyleKey ) as Style ;
120
+
121
+ int insertionIndex = 0 ;
122
+ bool hasSuggestion = false ;
123
+ foreach ( string suggestion in spellingError . Suggestions )
124
+ {
125
+ hasSuggestion = true ;
126
+ var menuItem = new MenuItem
127
+ {
128
+ CommandTarget = textBoxBase ,
129
+ Command = EditingCommands . CorrectSpellingError ,
130
+ CommandParameter = suggestion ,
131
+ Style = spellingSuggestionStyle ,
132
+ Tag = typeof ( Spelling )
133
+ } ;
134
+ contextMenu . Items . Insert ( insertionIndex ++ , menuItem ) ;
135
+ }
136
+ if ( ! hasSuggestion )
137
+ {
138
+ contextMenu . Items . Insert ( insertionIndex ++ , new MenuItem
139
+ {
140
+ Style = contextMenu . TryFindResource ( Spelling . SpellingNoSuggestionsMenuItemStyleKey ) as Style ,
141
+ Tag = typeof ( Spelling )
142
+ } ) ;
143
+ }
144
+
145
+ contextMenu . Items . Insert ( insertionIndex ++ , new Separator
146
+ {
147
+ Style = contextMenu . TryFindResource ( Spelling . SpellingSeparatorStyleKey ) as Style ,
148
+ Tag = typeof ( Spelling )
149
+ } ) ;
150
+
151
+ contextMenu . Items . Insert ( insertionIndex ++ , new MenuItem
152
+ {
153
+ Command = EditingCommands . IgnoreSpellingError ,
154
+ CommandTarget = textBoxBase ,
155
+ Style = contextMenu . TryFindResource ( Spelling . SpellingIgnoreAllMenuItemStyleKey ) as Style ,
156
+ Tag = typeof ( Spelling )
157
+ } ) ;
158
+
159
+ contextMenu . Items . Insert ( insertionIndex , new Separator
160
+ {
161
+ Style = contextMenu . TryFindResource ( Spelling . SpellingSeparatorStyleKey ) as Style ,
162
+ Tag = typeof ( Spelling )
163
+ } ) ;
164
+ }
165
+ }
166
+
167
+ private static SpellingError GetSpellingError ( TextBoxBase textBoxBase )
168
+ {
169
+ var textBox = textBoxBase as TextBox ;
170
+ if ( textBox != null )
171
+ {
172
+ return textBox . GetSpellingError ( textBox . CaretIndex ) ;
173
+ }
174
+ var richTextBox = textBoxBase as RichTextBox ;
175
+ if ( richTextBox != null )
176
+ {
177
+ return richTextBox . GetSpellingError ( richTextBox . CaretPosition ) ;
178
+ }
179
+ return null ;
180
+ }
181
+
182
+ private static void TextBoxOnContextMenuClosing ( object sender , ContextMenuEventArgs e )
183
+ {
184
+ var contextMenu = ( sender as TextBoxBase ) ? . ContextMenu ;
185
+ if ( contextMenu != null )
186
+ {
187
+ RemoveSpellingSuggestions ( contextMenu ) ;
188
+ }
189
+ }
190
+
191
+ private static void RemoveSpellingSuggestions ( ContextMenu menu )
192
+ {
193
+ foreach ( FrameworkElement item in ( from item in menu . Items . OfType < FrameworkElement > ( )
194
+ where ReferenceEquals ( item . Tag , typeof ( Spelling ) )
195
+ select item ) . ToList ( ) )
196
+ {
197
+ menu . Items . Remove ( item ) ;
198
+ }
199
+ }
200
+
70
201
#region Methods
71
202
72
203
/// <summary>
@@ -84,7 +215,7 @@ private static void ApplyTextBoxViewMargin(Control textBox, Thickness margin)
84
215
var frameworkElement = ( textBox . Template . FindName ( "PART_ContentHost" , textBox ) as ScrollViewer ) ? . Content as FrameworkElement ;
85
216
if ( frameworkElement != null )
86
217
{
87
- frameworkElement . Margin = margin ;
218
+ frameworkElement . Margin = margin ;
88
219
}
89
220
}
90
221
@@ -105,12 +236,12 @@ private static void TextBoxViewMarginPropertyChangedCallback(
105
236
106
237
if ( box . IsLoaded )
107
238
{
108
- ApplyTextBoxViewMargin ( box , ( Thickness ) dependencyPropertyChangedEventArgs . NewValue ) ;
239
+ ApplyTextBoxViewMargin ( box , ( Thickness ) dependencyPropertyChangedEventArgs . NewValue ) ;
109
240
}
110
241
111
242
box . Loaded += ( sender , args ) =>
112
243
{
113
- var textBox = ( Control ) sender ;
244
+ var textBox = ( Control ) sender ;
114
245
ApplyTextBoxViewMargin ( textBox , GetTextBoxViewMargin ( textBox ) ) ;
115
246
} ;
116
247
}
0 commit comments