У меня есть C# WPF RichTextBox
, которая позволяет ScaleX
и ScaleY
LayoutTransform
корректировки через Slider
. К сожалению, это масштабирование может привести к остановке каретки, что может быть исправлено по коду at this SO post here. К сожалению, установка в карете заставляет заклинание проверять красные криволинейные линии, чтобы перестать отображаться по мере ввода. Кажется, что сфокусировавшись на RichTextBox
и фокусируя его снова, нажав на Slider
, все вновь появятся красные squiggly линии. Вы можете просмотреть демо-версию этой ошибки на моем GitHub here.WPF RichTextBox - Установка Caret.RenderTransform Перерывы Проверка орфографии
Вопрос: Как я могу вызвать красную волнистую проверять орфографию линии, чтобы показать, как тип пользователей в то же время позволяя RichTextBox
масштабирования и полностью оказанного-на-все-Scale уровни каретки? Я пробовал вручную звонить GetSpellingError(TextPointer)
, и это работает ... вроде. Он не является полностью надежным, если я не позвоню GetSpellingError
по телефону каждый слово RichTextBox
, которое очень медленно вычисляется при наличии большого количества контента. Я также попытался использовать отражение и т. Д. В пунктах Speller
и связанных внутренних классах, таких как Highlights
, SpellerStatusTable
и SpellerHighlightLayer
. При просмотре списка запусков SpellerStatusTable
(который, как представляется, содержит информацию о том, являются ли прогоны чистыми или грязными), прогоны не обновляются, чтобы содержать ошибки до тех пор, пока не будет нажат ползунок, а это означает, что RichTextBox
не перепроверяет орфографические ошибки ,
Замечание caretSubElement.RenderTransform = scaleTransform;
в CustomRichTextBox.cs
«исправляет» проблему, но затем снова разрывает визуализацию каретки.
код -
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));
}
}
Будем надеяться, что [Jon Skeet] (https://stackoverflow.com/users/22656/jon-skeet) видит это. – cnsumner
Это довольно типичная ошибка WPF. Проверка орфографии и повторная рендеринг задерживаются, и достаточно легко не получить триггер, когда вам это нравится. В каждой версии .NET есть много исправлений ошибок WPF, но они включаются только тогда, когда вы настраиваете таргетинг на этот выпуск в своем проекте. Поэтому сначала убедитесь, что вы нацелились на 4.6.2. Если вы все еще видите это, то пусть они работают на 4.6.3, что работает только, когда вы расскажете им об этом через connect.microsoft.com. –
@HansPassant Спасибо за ваше предложение. Я попробовал обновление до 4.6.2, и ошибка все еще присутствует печально. Я бы предположил, что где-то есть какой-то ручной вызов повторной обработки или вызов «пожалуйста, повторите проверку моего текста», но я еще не нашел тот, который работает. Друг предположил, что я больше пытаюсь поиграть с ручными вызовами «GetSpellingError», поэтому я больше посмотрю на это. – Deadpikle