2015-12-23 15 views
11

Na komputerze z kulturą Ustawienie "de-DE" (lub inaczej niż "en-US"), chciałbym mieć RichTextBox z włączonym sprawdzaniem pisowni, z zaznaczonym językiem ustawionym na Angielski ("en-US").Konfliktowe ustawienia językowe WPF richtextbox

<RichTextBox SpellCheck.IsEnabled="True" Language="en-US"/> 

Umożliwia to sprawdzanie pisowni, ale sprawdza przy użyciu kultury "DE-DE" zamiast "en-US". To samo dotyczy dodawania xml:lang="en-us".

Jednak

<RichTextBox SpellCheck.IsEnabled="True" InputLanguageManager.InputLanguage="en-US"/> 

poprawnie umożliwia sprawdzanie pisowni w języku angielskim, ale również zmiany układu klawiatury na "en-US".

Jak mogę ustawić system klawiatury (w moim przypadku "de-DE"), ale sprawdzanie pisowni RichTextBox jest angielski?

(potencjalnie istotne: Używam .NET Framework 4.5)

+0

wierzę (ale nie wiem na pewno), że trzeba zainstalować język w systemie Windows, aby włączyć sprawdzanie pisowni. A to pochodzi z Windows 8 i nowszych. Kontynuując moje spekulacje, na niemieckim komputerze po zainstalowaniu języka "en-US" domyślnie otrzymujesz klawiaturę "US". Ustawienie języka wprowadzania na "en-US" spowoduje przełączenie klawiatury na "US", jednak jeśli usuniesz klawiaturę "US" i dodasz "niemiecką" klawiaturę do "en-US", zachowasz "niemiecki" "Klawiatura nawet podczas sprawdzania pisowni za pomocą" en-US ". Możesz obracać języki i klawisze, naciskając klawisz Windows. –

Odpowiedz

4

starałem się odtworzyć problemu i dla mnie nie mogłem aktywny sprawdzania pisowni dla innego języka niż angielski, choć zmieniły się ustawienia regionalne i kultura nić przed komponentów zostały zainicjowany:

Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("de-DE"); 
    Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture("de-DE"); 

oparciu o rozwiązania przewidziane here, udało mi się zrobić to praca:

1) sieje z RichTextBox:

class RichTextBoxEx : RichTextBox 
{ 
    protected override void OnTextChanged(TextChangedEventArgs e) 
    { 
     var changeList = e.Changes.ToList(); 
     if (changeList.Count > 0) 
     { 
      foreach (var change in changeList) 
      { 
       TextPointer start = null; 
       TextPointer end = null; 
       if (change.AddedLength > 0) 
       { 
        start = this.Document.ContentStart.GetPositionAtOffset(change.Offset); 
        end = this.Document.ContentStart.GetPositionAtOffset(change.Offset + change.AddedLength); 
       } 
       else 
       { 
        int startOffset = Math.Max(change.Offset - change.RemovedLength, 0); 
        start = this.Document.ContentStart.GetPositionAtOffset(startOffset); 
        end = this.Document.ContentStart.GetPositionAtOffset(change.Offset); 
       } 

       if (start != null && end != null) 
       { 
        var range = new TextRange(start, end); 
        range.ApplyPropertyValue(FrameworkElement.LanguageProperty, Document.Language); 
       } 
      } 
     } 
     base.OnTextChanged(e); 
    } 
} 

2) Użyj go w XAML

<local:RichTextBoxEx x:Name="richTextBox" HorizontalAlignment="Left" Height="100" Margin="33,100,0,0" VerticalAlignment="Top" Width="474" 
      xml:lang="de-DE" SpellCheck.IsEnabled="True"> 

[edytuj]

Próbowałem również w celu uniknięcia stosowania wartości właściwości dla każdej zmiany tekstu, poprzez zdefiniowanie zegar i pisownia sprawdzające wszystko od czasu do czasu. Na moim komputerze, nie widzę różnicy przy korzystaniu the longest Wikipedia article content:

class RichTextBoxEx : RichTextBox 
{ 
    DispatcherTimer timer; 
    bool textChanged = false; 

    public RichTextBoxEx() 
    { 
     if (DesignerProperties.GetIsInDesignMode(this)) 
      return; 

     timer = new DispatcherTimer(); 
     timer.Interval = new TimeSpan(0, 0, 1); 
     timer.Tick += timer_Tick; 
     timer.Start(); 
    } 

    void timer_Tick(object sender, EventArgs e) 
    { 
     try 
     { 
      var range = new TextRange(Document.ContentStart, Document.ContentEnd); 
      range.ApplyPropertyValue(FrameworkElement.LanguageProperty, Document.Language); 
     } 
     finally 
     { 
      textChanged = false; 
     } 
    } 

    protected override void OnTextChanged(TextChangedEventArgs e) 
    { 
     // TODO: remove if timer version works correctly 
     //var changeList = e.Changes.ToList(); 
     //if (changeList.Count > 0) 
     //{ 
     // foreach (var change in changeList) 
     // { 
     //  TextPointer start = null; 
     //  TextPointer end = null; 
     //  if (change.AddedLength > 0) 
     //  { 
     //   start = this.Document.ContentStart.GetPositionAtOffset(change.Offset); 
     //   end = this.Document.ContentStart.GetPositionAtOffset(change.Offset + change.AddedLength); 
     //  } 
     //  else 
     //  { 
     //   int startOffset = Math.Max(change.Offset - change.RemovedLength, 0); 
     //   start = this.Document.ContentStart.GetPositionAtOffset(startOffset); 
     //   end = this.Document.ContentStart.GetPositionAtOffset(change.Offset); 
     //  } 

     //  if (start != null && end != null) 
     //  { 
     //   var range = new TextRange(start, end); 
     //   range.ApplyPropertyValue(FrameworkElement.LanguageProperty, Document.Language); 
     //  } 
     // } 
     //} 

     textChanged = true; 
     base.OnTextChanged(e); 
    } 
} 
+0

Dziękuję, Aleksiej, to wydaje się działać. Jednak sprawia, że ​​wprowadzanie tekstu do RichTextBox jest wyraźnie powolne. Czy istnieje sposób, aby nie wykonywać aplikacji właściwości języka przy każdej zmianie (tj. Naciśnięciu klawisza), ale być może dopiero po każdym wprowadzonym słowie? –

+0

Czy możesz podać długość treści? Właśnie dodałem inne podejście i zastanawiam się, czy to jest lepsze dla twojego konkretnego przypadku. – Alexei

+0

Dzięki Alexei! Mamy wolne maszyny (:-(), więc czasami jest to problem, ale niektórzy użytkownicy testują wersję obsługującą sprawdzanie pisowni i żaden z nich nie skarżył się na złą wydajność, więc prawdopodobnie pozostanę przy wersji bez timera. Jeszcze raz dziękuję! –

Powiązane problemy