Wpf ViewBox使RichTextBox失去插入符号
RichTextBox放在一个ViewBox中,并缩放到10-1000%的不同级别。百分比小于100%时,插入符号在随机光标位置消失 我知道当一个视频被缩小(压缩)时,它会失去像素。有什么方法可以停止松开光标Wpf ViewBox使RichTextBox失去插入符号,wpf,richtextbox,Wpf,Richtextbox,RichTextBox放在一个ViewBox中,并缩放到10-1000%的不同级别。百分比小于100%时,插入符号在随机光标位置消失 我知道当一个视频被缩小(压缩)时,它会失去像素。有什么方法可以停止松开光标 <Viewbox> <RichTextBox Name="richTextBox1" Width="400" Height="400" /> </Viewbox> 好吧,你真的解决不了这个问题。ViewBox在封面下使
<Viewbox>
<RichTextBox Name="richTextBox1" Width="400" Height="400" />
</Viewbox>
好吧,你真的解决不了这个问题。ViewBox在封面下使用ScaleTransform,而ScaleTransform在缩小比例时将隐藏某些行,因为它无法显示所有内容。ScaleTransform没有使用非常先进的算法来进行缩放(它只是以尽可能快的方式进行),我认为您无法改变这一点。最终编辑:
嘿,我只是想说,你甚至可以在没有任何反思的情况下工作!!这不是优化的代码,我将留给你自己。而且这仍然是依靠内部的东西。因此,它来了:
代码隐藏:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
rtb.LayoutUpdated += (sender, args) =>
{
var child = VisualTreeHelper.GetChild(vb, 0) as ContainerVisual;
var scale = child.Transform as ScaleTransform;
rtb.ScaleX = scale.ScaleX;
};
}
}
public class RTBwithVisibleCaret:RichTextBox
{
private UIElement _flowDocumentView;
private AdornerLayer _adornerLayer;
private UIElement _caretSubElement;
private ScaleTransform _scaleTransform;
public RTBwithVisibleCaret()
{
LayoutUpdated += (sender, args) =>
{
if (!IsKeyboardFocused) return;
if(_adornerLayer == null)
_adornerLayer = AdornerLayer.GetAdornerLayer(_flowDocumentView);
if (_adornerLayer == null || _flowDocumentView == null) return;
if(_scaleTransform != null && _caretSubElement!= null)
{
_scaleTransform.ScaleX = 1/ScaleX;
_adornerLayer.Update(_flowDocumentView);
}
else
{
var adorners = _adornerLayer.GetAdorners(_flowDocumentView);
if(adorners == null || adorners.Length<1) return;
var caret = adorners[0];
_caretSubElement = (UIElement) VisualTreeHelper.GetChild(caret, 0);
if(!(_caretSubElement.RenderTransform is ScaleTransform))
{
_scaleTransform = new ScaleTransform(1 / ScaleX, 1);
_caretSubElement.RenderTransform = _scaleTransform;
}
}
};
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
var cthost = GetTemplateChild("PART_ContentHost") as FrameworkElement;
_flowDocumentView = cthost is ScrollViewer ? (UIElement)((ScrollViewer)cthost).Content : ((Decorator)cthost).Child;
}
public double ScaleX
{
get { return (double)GetValue(ScaleXProperty); }
set { SetValue(ScaleXProperty, value); }
}
public static readonly DependencyProperty ScaleXProperty =
DependencyProperty.Register("ScaleX", typeof(double), typeof(RTBwithVisibleCaret), new UIPropertyMetadata(1.0));
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
rtb.GotFocus +=RtbOnGotFocus;
}
private void RtbOnGotFocus(object s, RoutedEventArgs routedEventArgs)
{
rtb.LayoutUpdated += (sender, args) =>
{
var child = VisualTreeHelper.GetChild(vb, 0) as ContainerVisual;
var scale = child.Transform as ScaleTransform;
rtb.Selection.GetType().GetMethod("System.Windows.Documents.ITextSelection.UpdateCaretAndHighlight", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(
rtb.Selection, null);
var caretElement=rtb.Selection.GetType().GetProperty("CaretElement", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(rtb.Selection, null);
if (caretElement == null)
return;
var caretSubElement = caretElement.GetType().GetField("_caretElement", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(caretElement) as UIElement;
if (caretSubElement == null) return;
var scaleTransform = new ScaleTransform(1/scale.ScaleX, 1);
caretSubElement.RenderTransform = scaleTransform;
};
}
}
代码隐藏:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
rtb.LayoutUpdated += (sender, args) =>
{
var child = VisualTreeHelper.GetChild(vb, 0) as ContainerVisual;
var scale = child.Transform as ScaleTransform;
rtb.ScaleX = scale.ScaleX;
};
}
}
public class RTBwithVisibleCaret:RichTextBox
{
private UIElement _flowDocumentView;
private AdornerLayer _adornerLayer;
private UIElement _caretSubElement;
private ScaleTransform _scaleTransform;
public RTBwithVisibleCaret()
{
LayoutUpdated += (sender, args) =>
{
if (!IsKeyboardFocused) return;
if(_adornerLayer == null)
_adornerLayer = AdornerLayer.GetAdornerLayer(_flowDocumentView);
if (_adornerLayer == null || _flowDocumentView == null) return;
if(_scaleTransform != null && _caretSubElement!= null)
{
_scaleTransform.ScaleX = 1/ScaleX;
_adornerLayer.Update(_flowDocumentView);
}
else
{
var adorners = _adornerLayer.GetAdorners(_flowDocumentView);
if(adorners == null || adorners.Length<1) return;
var caret = adorners[0];
_caretSubElement = (UIElement) VisualTreeHelper.GetChild(caret, 0);
if(!(_caretSubElement.RenderTransform is ScaleTransform))
{
_scaleTransform = new ScaleTransform(1 / ScaleX, 1);
_caretSubElement.RenderTransform = _scaleTransform;
}
}
};
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
var cthost = GetTemplateChild("PART_ContentHost") as FrameworkElement;
_flowDocumentView = cthost is ScrollViewer ? (UIElement)((ScrollViewer)cthost).Content : ((Decorator)cthost).Child;
}
public double ScaleX
{
get { return (double)GetValue(ScaleXProperty); }
set { SetValue(ScaleXProperty, value); }
}
public static readonly DependencyProperty ScaleXProperty =
DependencyProperty.Register("ScaleX", typeof(double), typeof(RTBwithVisibleCaret), new UIPropertyMetadata(1.0));
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
rtb.GotFocus +=RtbOnGotFocus;
}
private void RtbOnGotFocus(object s, RoutedEventArgs routedEventArgs)
{
rtb.LayoutUpdated += (sender, args) =>
{
var child = VisualTreeHelper.GetChild(vb, 0) as ContainerVisual;
var scale = child.Transform as ScaleTransform;
rtb.Selection.GetType().GetMethod("System.Windows.Documents.ITextSelection.UpdateCaretAndHighlight", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(
rtb.Selection, null);
var caretElement=rtb.Selection.GetType().GetProperty("CaretElement", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(rtb.Selection, null);
if (caretElement == null)
return;
var caretSubElement = caretElement.GetType().GetField("_caretElement", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(caretElement) as UIElement;
if (caretSubElement == null) return;
var scaleTransform = new ScaleTransform(1/scale.ScaleX, 1);
caretSubElement.RenderTransform = scaleTransform;
};
}
}
这对我有用。一切都说了。是否可以选择将RichTextBox的内容缩放到不同的级别?例如,根据一个变量增加或减少fontsize和pagewidth?也许可以解释一下您的目标是什么,以防有人能想出一种不同于使用
ViewBox
+RichTextBox
?您的目标是什么版本的.NET/WPF。NET/WPF 4?缩放内容而不是将RTB放在ViewBox中-太多工作了!我研究了第二种选择。此解决方案的问题在于装饰符的大小与RTB相同(..,但不等于实际插入符号的大小),因此ScaleTransform也会移动插入符号的位置。@Trainee4Life请参阅我的编辑。不过我还是认为放大内容是更好的方法。谢谢马库斯!我已经实现了类似的解决方案。反射和反射到救援中。@Trainee4Life请查看我的最终编辑。这甚至可以毫无反省地工作!!!