Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf ViewBox使RichTextBox失去插入符号_Wpf_Richtextbox - Fatal编程技术网

Wpf ViewBox使RichTextBox失去插入符号

Wpf ViewBox使RichTextBox失去插入符号,wpf,richtextbox,Wpf,Richtextbox,RichTextBox放在一个ViewBox中,并缩放到10-1000%的不同级别。百分比小于100%时,插入符号在随机光标位置消失 我知道当一个视频被缩小(压缩)时,它会失去像素。有什么方法可以停止松开光标 <Viewbox> <RichTextBox Name="richTextBox1" Width="400" Height="400" /> </Viewbox> 好吧,你真的解决不了这个问题。ViewBox在封面下使

RichTextBox放在一个ViewBox中,并缩放到10-1000%的不同级别。百分比小于100%时,插入符号在随机光标位置消失

我知道当一个视频被缩小(压缩)时,它会失去像素。有什么方法可以停止松开光标

    <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请查看我的最终编辑。这甚至可以毫无反省地工作!!!