Ich habe eine C# WPF RichTextBox
bekam, die über eine Slider
für ScaleX
und ScaleY
LayoutTransform
Anpassungen erlaubt. Leider kann diese Skalierung dazu führen, dass das Caret nicht mehr rendert, ein Fehler, der mit dem Code at this SO post here behoben werden kann. Leider verursacht die Einstellung RenderTransform
des Carets, dass die roten Linien während der Eingabe nicht mehr angezeigt werden. Es scheint so, als würde man die RichTextBox
nicht fokussieren und durch erneutes Klicken auf Slider
wieder fokussieren, so dass alle roten Linien wieder auftauchen. Sie können eine Demo dieses Fehlers auf meinem GitHub here anzeigen.WPF RichTextBox - Einstellung Caret.RenderTransform Breaks Spell Check
Frage: Wie kann ich die rote Wellenrechtschreibprüfung Linien führen die Benutzertypen zu zeigen, wie während immer noch für RichTextBox
Skalierung ermöglicht und eine komplett gerenderte-at-all-Scale-Ebenen caret? Ich habe versucht, manuell GetSpellingError(TextPointer)
aufrufen, und das funktioniert ... Art von. Es ist nicht vollständig zuverlässig, es sei denn, ich rufe GetSpellingError
auf alle Wort der RichTextBox
, die sehr langsam ist zu berechnen, wenn es eine große Menge an Inhalt ist. Ich habe auch versucht, die Reflexion und solche auf Artikel innerhalb der Speller
und verwandte interne Klassen, wie Highlights
, SpellerStatusTable
und SpellerHighlightLayer
zu verwenden. Wenn man sich die Laufliste von SpellerStatusTable
anschaut (die Informationen darüber zu haben scheint, ob Läufe sauber oder schmutzig sind), werden die Läufe nicht so lange aktualisiert, bis der Schieberegler angeklickt wird, was bedeutet, dass die RichTextBox
nicht erneut nach Rechtschreibfehlern sucht .
Kommentieren caretSubElement.RenderTransform = scaleTransform;
in CustomRichTextBox.cs
"behebt" das Problem, aber bricht dann das Caret-Rendering wieder.
-Code -
MainWindow.xaml:
<Window x:Class="BrokenRichTextBox.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:BrokenRichTextBox"
mc:Ignorable="d"
Title="Rich Text Box Testing" Height="350" Width="525">
<Grid Background="LightGray">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Slider Name="FontZoomSlider" Grid.Row="0" Width="150" Value="2" Minimum="0.3" Maximum="10" HorizontalAlignment="Right" VerticalAlignment="Center"/>
<local:CustomRichTextBox x:Name="richTextBox"
Grid.Row="1"
SpellCheck.IsEnabled="True"
ScaleX="{Binding ElementName=FontZoomSlider, Path=Value}"
ScaleY="{Binding ElementName=FontZoomSlider, Path=Value}"
AcceptsTab="True">
<local:CustomRichTextBox.LayoutTransform>
<ScaleTransform ScaleX="{Binding ElementName=richTextBox, Path=ScaleX, Mode=TwoWay}"
ScaleY="{Binding ElementName=richTextBox, Path=ScaleY, Mode=TwoWay}"/>
</local:CustomRichTextBox.LayoutTransform>
<FlowDocument>
<Paragraph>
<Run>I am some sample text withhh typooos</Run>
</Paragraph>
<Paragraph>
<Run FontStyle="Italic">I am some more sample text in italic</Run>
</Paragraph>
</FlowDocument>
</local:CustomRichTextBox>
</Grid>
</Window>
CustomRichTextBox.cs:
using System;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Threading;
namespace BrokenRichTextBox
{
class CustomRichTextBox : RichTextBox
{
private bool _didAddLayoutUpdatedEvent = false;
public CustomRichTextBox() : base()
{
UpdateAdorner();
if (!_didAddLayoutUpdatedEvent)
{
_didAddLayoutUpdatedEvent = true;
LayoutUpdated += updateAdorner;
}
}
public void UpdateAdorner()
{
updateAdorner(null, null);
}
// Fixing missing caret bug code adjusted from: https://stackoverflow.com/questions/5180585/viewbox-makes-richtextbox-lose-its-caret
private void updateAdorner(object sender, EventArgs e)
{
Dispatcher.BeginInvoke(new Action(() =>
{
Selection.GetType().GetMethod("System.Windows.Documents.ITextSelection.UpdateCaretAndHighlight", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(
Selection, null);
var caretElement = Selection.GetType().GetProperty("CaretElement", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(Selection, null);
if (caretElement == null)
return;
var caretSubElement = caretElement.GetType().GetField("_caretElement", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(caretElement) as UIElement;
if (caretSubElement == null) return;
// Scale slightly differently if in italic just so it looks a little bit nicer
bool isItalic = (bool)caretElement.GetType().GetField("_italic", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(caretElement);
double scaleX = 1;
if (!isItalic)
scaleX = (1/ScaleX);
else
scaleX = 0.685;// output;
double scaleY = 1;
var scaleTransform = new ScaleTransform(scaleX, scaleY);
caretSubElement.RenderTransform = scaleTransform; // The line of trouble
}), DispatcherPriority.ContextIdle);
}
public double ScaleX
{
get { return (double)GetValue(ScaleXProperty); }
set { SetValue(ScaleXProperty, value); }
}
public static readonly DependencyProperty ScaleXProperty =
DependencyProperty.Register("ScaleX", typeof(double), typeof(CustomRichTextBox), new UIPropertyMetadata(1.0));
public double ScaleY
{
get { return (double)GetValue(ScaleYProperty); }
set { SetValue(ScaleYProperty, value); }
}
public static readonly DependencyProperty ScaleYProperty =
DependencyProperty.Register("ScaleY", typeof(double), typeof(CustomRichTextBox), new UIPropertyMetadata(1.0));
}
}
Hoffen wir, dass [Jon Skeet] (https://stackoverflow.com/users/22656/jon-skeet) sieht dies. – cnsumner
Das ist ein ziemlich typischer WPF-Bug. Die Rechtschreibprüfung und das erneute Rendern ist verzögert und es ist einfach genug, den Auslöser nicht zu bekommen, wenn es Ihnen gefällt. Jede .NET-Version hat viele WPF-Fehlerbehebungen, aber sie sind nur aktiviert, wenn Sie diese Version in Ihrem Projekt als Ziel haben. Stellen Sie zuerst sicher, dass Sie 4.6.2 anvisieren. Wenn Sie es immer noch sehen, dann lassen Sie sie an 4.6.3 arbeiten, das funktioniert nur, wenn Sie ihnen über connect.microsoft.com davon erzählen. –
@HansPassant Vielen Dank für Ihren Vorschlag. Ich habe ein Update auf 4.6.2 versucht, und der Bug ist leider immer noch vorhanden. Ich würde mir vorstellen, dass irgendwo ein manueller Neu-Render-Anruf oder "bitte überprüfe meinen Text" -Ruf, aber ich habe noch keinen gefunden, der funktioniert. Ein Freund hat vorgeschlagen, dass ich versuche, mehr mit manuellen 'GetSpellingError'-Anrufen zu spielen, also werde ich mir das genauer ansehen. – Deadpikle