Проверка орфографии в WPF без загрузки пользовательского словаря во вкладке - PullRequest
0 голосов
/ 17 мая 2018

Если я глобально включаю проверку орфографии в App.xaml ...

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

... тогда я получаю красные подчеркивания и проверку орфографии во всех текстовых полях приложения, независимо от того, где они находятся.

Если я хочу добавить пользовательский словарь, я должен использовать код, подобный показанному в этом SO-ответе , а затем вызвать его следующим образом ...

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

(код для вспомогательного метода показан внизу)

Это прекрасно работает для текстовых полей, которые отображаются при первой загрузке окна, но если у меня есть элемент управления с вкладками, а на вкладке по умолчанию есть текстовое поле, то пользовательский словарь не применяется.

Я пытался вызвать Helpers.SetCustomDictionary(this), когда вкладка загрузилась, но это тоже не сработало. Я вижу, что метод вызывается при загрузке окна, и я предполагаю, что на этом этапе содержимое вкладки не было создано, поэтому метод не находит их для установки пользовательского словаря.

Единственное, что я обнаружил, это сработало, вызывая его, когда загружалось отдельное текстовое поле. Однако это больно, так как я должен сделать это для каждого отдельного текстового поля в отдельности.

Кто-нибудь знает, как заставить настраиваемый словарь работать с текстовыми полями, которые не видны при первой загрузке окна?

Спасибо

P.S. Вот код для вспомогательного метода, который использует метод FindAllChildren(), показанный в связанном ответе SO ...

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 голосов
/ 22 мая 2018

Хотя ответ Дина Куги выглядел многообещающе, он не сработал для меня.После еще одного поиска кажется, что есть ошибка, которая препятствует запуску события Loaded в большинстве случаев.В комментарии к ответу на вопрос SO, где я видел упомянутое упоминание , Марцин Висницки связался с кодом, который он написал , который работает вокруг этой проблемы.

Как ятолько хочу, чтобы это работало для текстовых полей, я немного упростил его код.На случай, если это кому-нибудь поможет, вот мой упрощенный код ...

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
}

Будучи английским, я изменил "Initialized" на "Initialized", но в остальном код DP такой же.

Надеюсь, это кому-нибудь поможет.

0 голосов
/ 17 мая 2018

Возможно, есть лучшее решение, но вы можете использовать OnStartup событие вашего App.xaml.cs для установки словаря для каждого 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.
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...