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 ;
6
5
7
6
namespace MaterialDesignThemes . Wpf
8
7
{
@@ -64,9 +63,122 @@ public static void SetDecorationVisibility(DependencyObject element, Visibility
64
63
/// <returns></returns>
65
64
public static Visibility GetDecorationVisibility ( DependencyObject element )
66
65
{
67
- return ( Visibility ) element . GetValue ( DecorationVisibilityProperty ) ;
66
+ return ( Visibility ) element . GetValue ( DecorationVisibilityProperty ) ;
68
67
}
69
-
68
+
69
+ /// <summary>
70
+ /// Automatially inserts spelling suggestions into the text box context menu.
71
+ /// </summary>
72
+ public static readonly DependencyProperty IncludeSpellingSuggestionsProperty = DependencyProperty . RegisterAttached (
73
+ "IncludeSpellingSuggestions" , typeof ( bool ) , typeof ( TextFieldAssist ) , new PropertyMetadata ( default ( bool ) , IncludeSpellingSuggestionsChanged ) ) ;
74
+
75
+ public static void SetIncludeSpellingSuggestions ( TextBoxBase element , bool value )
76
+ {
77
+ element . SetValue ( IncludeSpellingSuggestionsProperty , value ) ;
78
+ }
79
+
80
+ public static bool GetIncludeSpellingSuggestions ( TextBoxBase element )
81
+ {
82
+ return ( bool ) element . GetValue ( IncludeSpellingSuggestionsProperty ) ;
83
+ }
84
+
85
+ private static void IncludeSpellingSuggestionsChanged ( DependencyObject element , DependencyPropertyChangedEventArgs e )
86
+ {
87
+ var textBox = element as TextBoxBase ;
88
+ if ( textBox != null )
89
+ {
90
+ if ( ( bool ) e . NewValue )
91
+ {
92
+ textBox . ContextMenuOpening += TextBoxOnContextMenuOpening ;
93
+ textBox . ContextMenuClosing += TextBoxOnContextMenuClosing ;
94
+ }
95
+ else
96
+ {
97
+ textBox . ContextMenuOpening -= TextBoxOnContextMenuOpening ;
98
+ textBox . ContextMenuClosing -= TextBoxOnContextMenuClosing ;
99
+ }
100
+ }
101
+ }
102
+
103
+ private static void TextBoxOnContextMenuOpening ( object sender , ContextMenuEventArgs e )
104
+ {
105
+ var textBoxBase = sender as TextBoxBase ;
106
+
107
+ ContextMenu contextMenu = textBoxBase ? . ContextMenu ;
108
+ if ( contextMenu == null ) return ;
109
+
110
+ RemoveSpellingSuggestions ( contextMenu ) ;
111
+
112
+ if ( ! SpellCheck . GetIsEnabled ( textBoxBase ) ) return ;
113
+
114
+ SpellingError spellingError = GetSpellingError ( textBoxBase ) ;
115
+ if ( spellingError != null )
116
+ {
117
+ int insertionIndex = 0 ;
118
+ bool hasSuggestion = false ;
119
+ foreach ( string suggestion in spellingError . Suggestions )
120
+ {
121
+ hasSuggestion = true ;
122
+ var menuItem = new SpellingSuggestionMenuItem ( suggestion )
123
+ {
124
+ CommandTarget = textBoxBase
125
+ } ;
126
+ contextMenu . Items . Insert ( insertionIndex ++ , menuItem ) ;
127
+ }
128
+ if ( ! hasSuggestion )
129
+ {
130
+ contextMenu . Items . Insert ( insertionIndex ++ , new SpellingNoSuggestionsMenuItem ( ) ) ;
131
+ }
132
+
133
+ contextMenu . Items . Insert ( insertionIndex ++ , new Separator { Tag = typeof ( SpellingSuggestionMenuItem ) } ) ;
134
+
135
+ contextMenu . Items . Insert ( insertionIndex ++ , new SpellingIgnoreAllMenuItem
136
+ {
137
+ CommandTarget = textBoxBase
138
+ } ) ;
139
+
140
+ contextMenu . Items . Insert ( insertionIndex , new Separator { Tag = typeof ( SpellingSuggestionMenuItem ) } ) ;
141
+ }
142
+ }
143
+
144
+ private static SpellingError GetSpellingError ( TextBoxBase textBoxBase )
145
+ {
146
+ var textBox = textBoxBase as TextBox ;
147
+ if ( textBox != null )
148
+ {
149
+ return textBox . GetSpellingError ( textBox . CaretIndex ) ;
150
+ }
151
+ var richTextBox = textBoxBase as RichTextBox ;
152
+ if ( richTextBox != null )
153
+ {
154
+ return richTextBox . GetSpellingError ( richTextBox . CaretPosition ) ;
155
+ }
156
+ return null ;
157
+ }
158
+
159
+ private static void TextBoxOnContextMenuClosing ( object sender , ContextMenuEventArgs e )
160
+ {
161
+ var contextMenu = ( sender as TextBoxBase ) ? . ContextMenu ;
162
+ if ( contextMenu != null )
163
+ {
164
+ RemoveSpellingSuggestions ( contextMenu ) ;
165
+ }
166
+ }
167
+
168
+ private static void RemoveSpellingSuggestions ( ContextMenu menu )
169
+ {
170
+ foreach ( object item in ( from item in menu . Items . OfType < object > ( )
171
+ let separator = item as Separator
172
+ where item is SpellingSuggestionMenuItem ||
173
+ item is SpellingIgnoreAllMenuItem ||
174
+ item is SpellingNoSuggestionsMenuItem ||
175
+ ReferenceEquals ( separator ? . Tag , typeof ( SpellingSuggestionMenuItem ) )
176
+ select item ) . ToList ( ) )
177
+ {
178
+ menu . Items . Remove ( item ) ;
179
+ }
180
+ }
181
+
70
182
#region Methods
71
183
72
184
/// <summary>
@@ -84,7 +196,7 @@ private static void ApplyTextBoxViewMargin(Control textBox, Thickness margin)
84
196
var frameworkElement = ( textBox . Template . FindName ( "PART_ContentHost" , textBox ) as ScrollViewer ) ? . Content as FrameworkElement ;
85
197
if ( frameworkElement != null )
86
198
{
87
- frameworkElement . Margin = margin ;
199
+ frameworkElement . Margin = margin ;
88
200
}
89
201
}
90
202
@@ -105,12 +217,12 @@ private static void TextBoxViewMarginPropertyChangedCallback(
105
217
106
218
if ( box . IsLoaded )
107
219
{
108
- ApplyTextBoxViewMargin ( box , ( Thickness ) dependencyPropertyChangedEventArgs . NewValue ) ;
220
+ ApplyTextBoxViewMargin ( box , ( Thickness ) dependencyPropertyChangedEventArgs . NewValue ) ;
109
221
}
110
222
111
223
box . Loaded += ( sender , args ) =>
112
224
{
113
- var textBox = ( Control ) sender ;
225
+ var textBox = ( Control ) sender ;
114
226
ApplyTextBoxViewMargin ( textBox , GetTextBoxViewMargin ( textBox ) ) ;
115
227
} ;
116
228
}
0 commit comments