WPF拼写检查未在标签

时间:2018-05-17 16:19:26

标签: wpf spell-checking

如果我在App.xaml中全局启用拼写检查...

<Application.Resources>
  <Style TargetType="TextBox">
    <Setter Property="SpellCheck.IsEnabled"
            Value="True" />
  </Style>
</Application.Resources>

...然后我会在应用程序的所有文本框中获得红色下划线和拼写检查,无论它们在何处。

如果我想添加自定义词典,那么我必须使用类似于this SO answer中显示的代码,然后按如下方式调用它...

public MainWindow() {
  InitializeComponent();
  Loaded += (_, __) => Helpers.SetCustomDictionary(this);
}

(下方显示的辅助方法代码)

这适用于首次加载窗口时显示的文本框,但如果我有一个选项卡控件,并且默认选项卡有一个文本框,则不会应用自定义词典。

我在加载标签时尝试调用Helpers.SetCustomDictionary(this),但这也无效。我可以看到在窗口加载时调用该方法,我的猜测是在该阶段,尚未创建选项卡的内容,因此该方法找不到它们来设置自定义字典。

我发现唯一有效的方法是在加载单个文本框时调用它。但是,这很痛苦,因为我必须单独为每个文本框执行此操作。

任何人都知道如何让自定义词典适用于首次加载窗口时不可见的文本框?

由于

P.S。以下是帮助方法的代码,它使用链接的SO回复中显示的FindAllChildren()方法...

public static void SetCustomDictionary(DependencyObject parent) {
  Uri uri = new Uri("pack://application:,,,/CustomDictionary.lex");
  List<TextBox> textBoxes = new List<TextBox>();
  FindAllChildren(parent, ref textBoxes);
  foreach (TextBox tb in textBoxes) {
    if (tb.SpellCheck.IsEnabled && !tb.SpellCheck.CustomDictionaries.Contains(uri)) {
      tb.SpellCheck.CustomDictionaries.Add(uri);
    }
  }
}

2 个答案:

答案 0 :(得分:1)

可能有更好的解决方案,但您可以使用App.xaml.cs的OnStartup事件为每个TextBox设置字典,当它加载单个事件处理程序时:

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
            base.OnStartup(e);
            EventManager.RegisterClassHandler(typeof(TextBox), FrameworkElement.LoadedEvent, new RoutedEventHandler(TextBox_OnLoaded));
    }

    private void TextBox_OnLoaded(object sender, RoutedEventArgs e)
    {
            // Set custom dictionary here.
    }
}

答案 1 :(得分:0)

虽然Dean Kuga的回答很有希望,但对我来说并没有用。经过一些搜索后,似乎有一个错误阻止Loaded事件在大多数情况下被触发。在对SO question where I saw this mentioned的答案的评论中,Marcin Wisnicki与some code he wrote相关联,可以解决这个问题。

因为我只想让它适用于文本框,所以我简化了他的代码。万一它可以帮助任何人,这是我的简化代码...

public partial class App {
  protected override void OnStartup(StartupEventArgs e) {
    base.OnStartup(e);
    EventManager.RegisterClassHandler(typeof(Window),
      FrameworkElement.SizeChangedEvent, new RoutedEventHandler(OnSizeChanged));
    EventManager.RegisterClassHandler(typeof(TextBox),
      FrameworkElement.LoadedEvent, new RoutedEventHandler(OnLoaded), true);
  }

  private static void OnSizeChanged(object sender, RoutedEventArgs e) {
    SetMyInitialised((Window)sender, true);
  }

  private static void OnLoaded(object sender, RoutedEventArgs e) {
    if (e.OriginalSource is TextBox) {
      TextBox tb = (TextBox)e.OriginalSource;
      Helpers.SetCustomDictionaryTextBox(tb);
    }
  }

  #region MyInitialised dependency property

  public static readonly DependencyProperty MyInitialisedProperty =
    DependencyProperty.RegisterAttached("MyInitialised",
      typeof(bool),
      typeof(App),
      new FrameworkPropertyMetadata(false,
        FrameworkPropertyMetadataOptions.Inherits,
        OnMyInitialisedChanged));

  private static void OnMyInitialisedChanged(DependencyObject dpo,
    DependencyPropertyChangedEventArgs ev) {
    if ((bool)ev.NewValue && dpo is FrameworkElement) {
      (dpo as FrameworkElement).Loaded += delegate { };
    }
  }

  public static void SetMyInitialised(UIElement element, bool value) {
    element.SetValue(MyInitialisedProperty, value);
  }

  public static bool GetMyInitialised(UIElement element) {
    return (bool)element.GetValue(MyInitialisedProperty);
  }

  #endregion MyInitialised
}

英语,我改变了#34;初始化&#34;到&#34;已初始化&#34;,但除此之外,DP代码是相同的。

希望这有助于某人。

相关问题