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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/.htaccess/5.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
C# 当我点击文本框时,将其固定到顶部_C#_Wpf_Textbox - Fatal编程技术网

C# 当我点击文本框时,将其固定到顶部

C# 当我点击文本框时,将其固定到顶部,c#,wpf,textbox,C#,Wpf,Textbox,我有一个简单的文本框: <TextBox Name="PART_txtBx" IsReadOnly="True" ScrollViewer.VerticalScrollBarVisibility="Auto" /> 当我点击文本框时,当我向其添加一些文本时,它会自动将滚动条置于顶部 如果我像这样处理PreviewMouseLeftButtonDown事件: private void PART_txtBx_PreviewMouseLeftButtonDown_1(object se

我有一个简单的文本框:

<TextBox Name="PART_txtBx" IsReadOnly="True" ScrollViewer.VerticalScrollBarVisibility="Auto"  />
当我点击文本框时,当我向其添加一些文本时,它会自动将滚动条置于顶部

如果我像这样处理PreviewMouseLeftButtonDown事件:

private void PART_txtBx_PreviewMouseLeftButtonDown_1(object sender, MouseButtonEventArgs e)
{
    e.Handled = true;
}
文本框正常工作,但我当然不能选择任何文本

有什么办法防止这种行为吗

编辑1: 我注意到当文本框被创建时,即使它有焦点,也没有任何插入符号。插入符号仅在执行单击时显示,但我无法在单击后的文本框中找到更改的内容。 我的文本框是只读的,所以我不需要插入符号。

May:PART\u txtBx.CaretIndex=PART\u txtBx.Length

或:
PART_txtBx.SelectionStart=PART_txtBx.Text.Length; 第xtbx.ScrollToCaret部分

使用textbox\u更改事件

您需要扩展TextBox控件以添加PreviewTextChanged事件,如前所述。预览文本更改时,您必须记住SelectionStart和SelectionLength 文本框的句柄事件ScrollViewer.ScrollChanged:

ScrollViewer.ScrollChanged="OnScrollChanged" <!--in xaml-->


private void OnScrollChanged(object sender, ScrollChangedEventArgs e)
{
    // here you could prevent scrolling
    isOnBottom = (sender as TextBox).VerticalOffset + (sender as TextBox).ViewportHeight == (sender as TextBox).ExtentHeight;
}
在手动输入文本的情况下,您必须阻止文本选择


希望有帮助,所以我创建了自己的CustomTextblock来解决这个问题:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace CE.EthernetMessagesManager.Views
{
    public class CustomTextBox : TextBox
    {
        private int realCaretIndex = 0;
        private bool triggeredByUser = false;
        private bool isScrollingWithMouse = false;

        public CustomTextBox()
            : base()
        {
            this.PreviewMouseLeftButtonDown += CustomTextBox_PreviewMouseLeftButtonDown;
            this.PreviewMouseLeftButtonUp += CustomTextBox_PreviewMouseLeftButtonUp;
            this.PreviewMouseMove += CustomTextBox_PreviewMouseMove;
            this.PreviewMouseWheel += CustomTextBox_PreviewMouseWheel;
            this.TextChanged += CustomTextBox_TextChanged;
            this.LostFocus += CustomTextBox_LostFocus;

            this.AddHandler(ScrollViewer.ScrollChangedEvent, new RoutedEventHandler((X, S) =>
            {
                if ((S as ScrollChangedEventArgs).VerticalChange != 0 && triggeredByUser)
                {
                    TextBox textBox = (X as TextBox);
                    int newLinePosition = 0;
                    newLinePosition = (int)(((S as ScrollChangedEventArgs).VerticalChange + textBox.ExtentHeight) / (textBox.FontSize + 2));

                    realCaretIndex += newLinePosition * ((S as ScrollChangedEventArgs).VerticalChange < 0 ? -1 : 1);
                    if (realCaretIndex < 0)
                        realCaretIndex = 0;

                    textBox.CaretIndex = realCaretIndex;
                    triggeredByUser = false;
                }
            }));
        }

        void CustomTextBox_LostFocus(object sender, System.Windows.RoutedEventArgs e)
        {
            e.Handled = true;
        }

        void CustomTextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            TextBox textBox = sender as TextBox;
            textBox.CaretIndex = realCaretIndex;

            var max = (textBox.ExtentHeight - textBox.ViewportHeight);
            var offset = textBox.VerticalOffset;

            if (max != 0 && max == offset)
                this.Dispatcher.Invoke(new Action(() =>
                {
                    textBox.ScrollToEnd();
                }),
                    System.Windows.Threading.DispatcherPriority.Loaded);
        }

        void CustomTextBox_PreviewMouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e)
        {
            triggeredByUser = true;
        }

        void CustomTextBox_PreviewMouseMove(object sender, System.Windows.Input.MouseEventArgs e)
        {
            if (isScrollingWithMouse)
            {
                TextBox textBox = sender as TextBox;
                realCaretIndex = textBox.GetCharacterIndexFromPoint(Mouse.GetPosition(textBox), true);
            }
        }

        void CustomTextBox_PreviewMouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            isScrollingWithMouse = false;
        }

        void CustomTextBox_PreviewMouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            TextBox textBox = sender as TextBox;
            realCaretIndex = textBox.GetCharacterIndexFromPoint(Mouse.GetPosition(textBox), true);
            triggeredByUser = true;
            isScrollingWithMouse = true;
        }
    }
}
当我手动将滚动条放在底部时,这个CustomTextBox也将滚动条固定在底部。 xaml:

            <v:CustomTextBox 
                IsReadOnly="True"
                ScrollViewer.HorizontalScrollBarVisibility="Auto"
                ScrollViewer.VerticalScrollBarVisibility="Auto"
                />

遗憾的是,这个实现的选择被打破了。我将研究它

PART\u txtBx.SelectionStart=PART\u txtBx.Text.Length;我会把它钉在底部,我不想要它
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace CE.EthernetMessagesManager.Views
{
    public class CustomTextBox : TextBox
    {
        private int realCaretIndex = 0;
        private bool triggeredByUser = false;
        private bool isScrollingWithMouse = false;

        public CustomTextBox()
            : base()
        {
            this.PreviewMouseLeftButtonDown += CustomTextBox_PreviewMouseLeftButtonDown;
            this.PreviewMouseLeftButtonUp += CustomTextBox_PreviewMouseLeftButtonUp;
            this.PreviewMouseMove += CustomTextBox_PreviewMouseMove;
            this.PreviewMouseWheel += CustomTextBox_PreviewMouseWheel;
            this.TextChanged += CustomTextBox_TextChanged;
            this.LostFocus += CustomTextBox_LostFocus;

            this.AddHandler(ScrollViewer.ScrollChangedEvent, new RoutedEventHandler((X, S) =>
            {
                if ((S as ScrollChangedEventArgs).VerticalChange != 0 && triggeredByUser)
                {
                    TextBox textBox = (X as TextBox);
                    int newLinePosition = 0;
                    newLinePosition = (int)(((S as ScrollChangedEventArgs).VerticalChange + textBox.ExtentHeight) / (textBox.FontSize + 2));

                    realCaretIndex += newLinePosition * ((S as ScrollChangedEventArgs).VerticalChange < 0 ? -1 : 1);
                    if (realCaretIndex < 0)
                        realCaretIndex = 0;

                    textBox.CaretIndex = realCaretIndex;
                    triggeredByUser = false;
                }
            }));
        }

        void CustomTextBox_LostFocus(object sender, System.Windows.RoutedEventArgs e)
        {
            e.Handled = true;
        }

        void CustomTextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            TextBox textBox = sender as TextBox;
            textBox.CaretIndex = realCaretIndex;

            var max = (textBox.ExtentHeight - textBox.ViewportHeight);
            var offset = textBox.VerticalOffset;

            if (max != 0 && max == offset)
                this.Dispatcher.Invoke(new Action(() =>
                {
                    textBox.ScrollToEnd();
                }),
                    System.Windows.Threading.DispatcherPriority.Loaded);
        }

        void CustomTextBox_PreviewMouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e)
        {
            triggeredByUser = true;
        }

        void CustomTextBox_PreviewMouseMove(object sender, System.Windows.Input.MouseEventArgs e)
        {
            if (isScrollingWithMouse)
            {
                TextBox textBox = sender as TextBox;
                realCaretIndex = textBox.GetCharacterIndexFromPoint(Mouse.GetPosition(textBox), true);
            }
        }

        void CustomTextBox_PreviewMouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            isScrollingWithMouse = false;
        }

        void CustomTextBox_PreviewMouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            TextBox textBox = sender as TextBox;
            realCaretIndex = textBox.GetCharacterIndexFromPoint(Mouse.GetPosition(textBox), true);
            triggeredByUser = true;
            isScrollingWithMouse = true;
        }
    }
}
            <v:CustomTextBox 
                IsReadOnly="True"
                ScrollViewer.HorizontalScrollBarVisibility="Auto"
                ScrollViewer.VerticalScrollBarVisibility="Auto"
                />