15
15
16
16
namespace MahApps . Metro . Controls
17
17
{
18
- public interface ISpellCheckMenuItem
18
+ internal enum SpellingResourceKeyId
19
19
{
20
+ SuggestionMenuItemStyle ,
21
+ IgnoreAllMenuItemStyle ,
22
+ NoSuggestionsMenuItemStyle ,
23
+ SeparatorStyle ,
20
24
}
21
25
22
- public class SpellCheckMenuItem : MenuItem , ISpellCheckMenuItem
23
- {
24
- public SpellCheckMenuItem ( )
25
- {
26
- this . SetResourceReference ( FrameworkElement . StyleProperty , "MetroMenuItem" ) ;
27
- }
28
- }
29
-
30
- public class SpellCheckSeparator : Separator , ISpellCheckMenuItem
26
+ public static class Spelling
31
27
{
28
+ public static ResourceKey SuggestionMenuItemStyleKey { get ; } = new ComponentResourceKey ( typeof ( Spelling ) , SpellingResourceKeyId . SuggestionMenuItemStyle ) ;
29
+ public static ResourceKey IgnoreAllMenuItemStyleKey { get ; } = new ComponentResourceKey ( typeof ( Spelling ) , SpellingResourceKeyId . IgnoreAllMenuItemStyle ) ;
30
+ public static ResourceKey NoSuggestionsMenuItemStyleKey { get ; } = new ComponentResourceKey ( typeof ( Spelling ) , SpellingResourceKeyId . NoSuggestionsMenuItemStyle ) ;
31
+ public static ResourceKey SeparatorStyleKey { get ; } = new ComponentResourceKey ( typeof ( Spelling ) , SpellingResourceKeyId . SeparatorStyle ) ;
32
32
}
33
33
34
34
/// <summary>
@@ -69,7 +69,7 @@ public class TextBoxHelper
69
69
70
70
public static readonly DependencyProperty HasTextProperty = DependencyProperty . RegisterAttached ( "HasText" , typeof ( bool ) , typeof ( TextBoxHelper ) , new FrameworkPropertyMetadata ( false , FrameworkPropertyMetadataOptions . AffectsMeasure | FrameworkPropertyMetadataOptions . AffectsArrange | FrameworkPropertyMetadataOptions . AffectsRender ) ) ;
71
71
72
- public static readonly DependencyProperty IsSpellCheckContextMenuEnabledProperty = DependencyProperty . RegisterAttached ( "IsSpellCheckContextMenuEnabled" , typeof ( bool ) , typeof ( TextBoxHelper ) , new FrameworkPropertyMetadata ( false , UseSpellCheckContextMenuChanged ) ) ;
72
+ public static readonly DependencyProperty IsSpellCheckContextMenuEnabledProperty = DependencyProperty . RegisterAttached ( "IsSpellCheckContextMenuEnabled" , typeof ( bool ) , typeof ( TextBoxHelper ) , new FrameworkPropertyMetadata ( default ( bool ) , IsSpellCheckContextMenuEnabledChanged ) ) ;
73
73
74
74
/// <summary>
75
75
/// This property can be used to retrieve the watermark using the <see cref="DisplayAttribute"/> of bound property.
@@ -252,7 +252,7 @@ private static Type ResolveBinding(Type type, string[] paths)
252
252
}
253
253
#endif
254
254
255
- private static void UseSpellCheckContextMenuChanged ( DependencyObject d , DependencyPropertyChangedEventArgs e )
255
+ private static void IsSpellCheckContextMenuEnabledChanged ( DependencyObject d , DependencyPropertyChangedEventArgs e )
256
256
{
257
257
var tb = d as TextBoxBase ;
258
258
if ( null == tb )
@@ -262,16 +262,15 @@ private static void UseSpellCheckContextMenuChanged(DependencyObject d, Dependen
262
262
263
263
if ( e . OldValue != e . NewValue )
264
264
{
265
+ tb . SetValue ( SpellCheck . IsEnabledProperty , ( bool ) e . NewValue ) ;
265
266
if ( ( bool ) e . NewValue )
266
267
{
267
- tb . SetValue ( SpellCheck . IsEnabledProperty , true ) ;
268
268
tb . ContextMenuOpening += TextBoxBaseContextMenuOpening ;
269
269
tb . LostFocus += TextBoxBaseLostFocus ;
270
270
tb . ContextMenuClosing += TextBoxBaseContextMenuClosing ;
271
271
}
272
272
else
273
273
{
274
- tb . SetValue ( SpellCheck . IsEnabledProperty , false ) ;
275
274
tb . ContextMenuOpening -= TextBoxBaseContextMenuOpening ;
276
275
tb . LostFocus -= TextBoxBaseLostFocus ;
277
276
tb . ContextMenuClosing -= TextBoxBaseContextMenuClosing ;
@@ -281,70 +280,99 @@ private static void UseSpellCheckContextMenuChanged(DependencyObject d, Dependen
281
280
282
281
private static void TextBoxBaseLostFocus ( object sender , RoutedEventArgs e )
283
282
{
284
- RemoveSpellCheckMenuItems ( ( FrameworkElement ) sender ) ;
283
+ RemoveSpellCheckMenuItems ( ( ( FrameworkElement ) sender ) . ContextMenu ) ;
285
284
}
286
285
287
286
private static void TextBoxBaseContextMenuClosing ( object sender , ContextMenuEventArgs e )
288
287
{
289
- RemoveSpellCheckMenuItems ( ( FrameworkElement ) sender ) ;
288
+ RemoveSpellCheckMenuItems ( ( ( FrameworkElement ) sender ) . ContextMenu ) ;
290
289
}
291
290
292
291
private static void TextBoxBaseContextMenuOpening ( object sender , ContextMenuEventArgs e )
293
292
{
294
293
var tbBase = ( TextBoxBase ) sender ;
295
- var textBox = tbBase as TextBox ;
296
- var richTextBox = tbBase as RichTextBox ;
294
+ var contextMenu = tbBase . ContextMenu ;
295
+ if ( contextMenu == null )
296
+ {
297
+ return ;
298
+ }
297
299
298
- RemoveSpellCheckMenuItems ( ( FrameworkElement ) sender ) ;
300
+ RemoveSpellCheckMenuItems ( contextMenu ) ;
299
301
300
- // the default item comes normally through the styles, so I think we don't need to do this
301
- /*if (tbBase.ContextMenu == null)
302
+ if ( ! SpellCheck . GetIsEnabled ( tbBase ) )
302
303
{
303
- tbBase.ContextMenu = GetDefaultTextBoxBaseContextMenu() ;
304
- }*/
304
+ return ;
305
+ }
305
306
306
307
var cmdIndex = 0 ;
308
+ var textBox = tbBase as TextBox ;
309
+ var richTextBox = tbBase as RichTextBox ;
307
310
var spellingError = textBox != null
308
311
? textBox . GetSpellingError ( textBox . CaretIndex )
309
312
: richTextBox ? . GetSpellingError ( richTextBox . CaretPosition ) ;
310
- if ( spellingError != null ) {
313
+ if ( spellingError != null )
314
+ {
315
+ var spellingSuggestionStyle = contextMenu . TryFindResource ( Spelling . SuggestionMenuItemStyleKey ) as Style ;
311
316
var suggestions = spellingError . Suggestions . ToList ( ) ;
312
- if ( suggestions . Any ( ) ) {
313
- foreach ( var suggestion in suggestions ) {
314
- var mi = new SpellCheckMenuItem ( ) ;
315
- mi . Header = suggestion ;
316
- mi . FontWeight = FontWeights . Bold ;
317
- mi . Command = EditingCommands . CorrectSpellingError ;
318
- mi . CommandParameter = suggestion ;
319
- mi . CommandTarget = tbBase ;
320
- tbBase . ContextMenu . Items . Insert ( cmdIndex , mi ) ;
321
- cmdIndex ++ ;
317
+ if ( suggestions . Any ( ) )
318
+ {
319
+ foreach ( var suggestion in suggestions )
320
+ {
321
+ var mi = new MenuItem
322
+ {
323
+ Command = EditingCommands . CorrectSpellingError ,
324
+ CommandParameter = suggestion ,
325
+ CommandTarget = tbBase ,
326
+ Style = spellingSuggestionStyle ,
327
+ Tag = typeof ( Spelling )
328
+ } ;
329
+ contextMenu . Items . Insert ( cmdIndex ++ , mi ) ;
322
330
}
323
- // add a separator
324
- tbBase . ContextMenu . Items . Insert ( cmdIndex , new SpellCheckSeparator ( ) ) ;
325
- cmdIndex ++ ;
326
- }
327
- var ignoreAllMI = new SpellCheckMenuItem ( ) ;
328
- ignoreAllMI . Header = "Ignore All" ;
329
- ignoreAllMI . Command = EditingCommands . IgnoreSpellingError ;
330
- ignoreAllMI . CommandTarget = tbBase ;
331
- tbBase . ContextMenu . Items . Insert ( cmdIndex , ignoreAllMI ) ;
332
- cmdIndex ++ ;
331
+ }
332
+ else
333
+ {
334
+ contextMenu . Items . Insert ( cmdIndex ++ , new MenuItem
335
+ {
336
+ Style = contextMenu . TryFindResource ( Spelling . NoSuggestionsMenuItemStyleKey ) as Style ,
337
+ Tag = typeof ( Spelling )
338
+ } ) ;
339
+ }
340
+
341
+ // add a separator
342
+ contextMenu . Items . Insert ( cmdIndex ++ , new Separator
343
+ {
344
+ Style = contextMenu . TryFindResource ( Spelling . SeparatorStyleKey ) as Style ,
345
+ Tag = typeof ( Spelling )
346
+ } ) ;
347
+
348
+ // ignore all
349
+ var ignoreAllMI = new MenuItem
350
+ {
351
+ Command = EditingCommands . IgnoreSpellingError ,
352
+ CommandTarget = tbBase ,
353
+ Style = contextMenu . TryFindResource ( Spelling . IgnoreAllMenuItemStyleKey ) as Style ,
354
+ Tag = typeof ( Spelling )
355
+ } ;
356
+ contextMenu . Items . Insert ( cmdIndex ++ , ignoreAllMI ) ;
357
+
333
358
// add another separator
334
- tbBase . ContextMenu . Items . Insert ( cmdIndex , new SpellCheckSeparator ( ) ) ;
359
+ contextMenu . Items . Insert ( cmdIndex , new Separator
360
+ {
361
+ Style = contextMenu . TryFindResource ( Spelling . SeparatorStyleKey ) as Style ,
362
+ Tag = typeof ( Spelling )
363
+ } ) ;
335
364
}
336
365
}
337
366
338
- private static void RemoveSpellCheckMenuItems ( [ CanBeNull ] FrameworkElement tbBase )
367
+ private static void RemoveSpellCheckMenuItems ( [ CanBeNull ] ContextMenu contextMenu )
339
368
{
340
- if ( tbBase ? . ContextMenu = = null )
369
+ if ( contextMenu ! = null )
341
370
{
342
- return ;
343
- }
344
- var spellCheckItems = tbBase . ContextMenu . Items . OfType < ISpellCheckMenuItem > ( ) . ToList ( ) ;
345
- foreach ( var item in spellCheckItems )
346
- {
347
- tbBase . ContextMenu . Items . Remove ( item ) ;
371
+ var spellCheckItems = contextMenu . Items . OfType < FrameworkElement > ( ) . Where ( item => ReferenceEquals ( item . Tag , typeof ( Spelling ) ) ) . ToList ( ) ;
372
+ foreach ( var item in spellCheckItems )
373
+ {
374
+ contextMenu . Items . Remove ( item ) ;
375
+ }
348
376
}
349
377
}
350
378
0 commit comments