关于WPF中TextBox行的选择与显示的问题

声明:本文是本人在51CTO上的一篇博文,今天打算将其转载到博客园,以方便自己查阅。原文地址为:http://kestrelsaga.blog.51cto.com/3015222/1542584

最近做了一个小工具,其中用到了WPF中的TextBox控件。对于这个控件的使用,其中主要的一个功能是需要选择指定的行,并将其显示在控件可见区域的视图中(如果不在可视区域时,需要控件自动滚动到改行)。在我使用时,发现一个问题,如果当我先将指定的行滚动至视图中,然后在将其选中,则经常会不稳定,有时能定位并选中,有时则会选中错误位置,或者报错。现在我想将我遇到的问题以代码的方式进行说明,以及我的解决方案。不过,目前其原因还未搞明白,如果有高人,还请给予指点。

首先,在自定义控件中添加一个TextBox控件,命名为txtBoxDocument,并在控件中提供两个公共方法GoToLine(int rowIndex)和SelectedLine(int rowIndex),用来定位并滚动至指定行和选中改行。

/// <summary>

        /// 定位到指定行

        /// </summary>

        /// <param name="rowIndex">指定的从零开始的行的索引</param>

        public void GoToLine(int rowIndex)

        {

            txtBoxDocument.ScrollToLine(rowIndex);

        }

        /// <summary>

        /// 选中指定的行

        /// </summary>

        /// <param name="rowIndex">指定的从零开始的行的索引</param>

        public void SelectedLine(int rowIndex)

        {

            try

            {

                int lineLength = txtBoxDocument.GetLineLength(rowIndex);

                int start = txtBoxDocument.GetCharacterIndexFromLineIndex(rowIndex);

                txtBoxDocument.Focus();

                txtBoxDocument.Select(start, lineLength);

            }

            catch { }

        }

  然后,我们在调用这两个方法(假设我们使用一个Button调用,并在TextBox中指定要跳转至的行),Button命名为:btnGoTo,该文本框命名为txtBoxLineNum

private void btnGoTo_Click(object sender, RoutedEventArgs e)

        {

            int rowIndex = 0;

            if(int.TryParse(txtBoxLineNum.Text,rowIndex))

            {

                //先选择,再跳转至指定位置(这种使用方式没问题)

                SelectedLine(rowIndex );

                GoToLine(rowIndex );

            }

        }

  如果将上面的调用方式改成下面情况,则会在SelectedLine(int rowIndex)方法的int lineLength = txtBoxDocument.GetLineLength(rowIndex);这句话出现问题,得出的lineLength不一定就是指定行的文本长度了,有可能是负值。错误的调用方式如下:

        private void btnGoTo_Click(object sender, RoutedEventArgs e)

        {

            int rowIndex = 0;

            if(int.TryParse(txtBoxLineNum.Text,rowIndex))

            {

                //先跳转定位,再选择(这种使用方式不稳定)

                GoToLine(rowIndex );

                SelectedLine(rowIndex );

            }

        }

  如果将SelectedLine(int rowIndex)方法中的获取指定行的文本长度的方式改为先获取其内容,再计算长度(int lineLength = txtBoxDocument.GetLineText(rowIndex).Length;),则经常会报错。下面是改后的SelectedLine(int rowIndex):

        /// <summary>

        /// 选中指定的行

        /// </summary>

        /// <param name="rowIndex">指定的从零开始的行的索引</param>

        public void SelectedLine(int rowIndex)

        {

            try

            {

                //采用错误的调用方式,下面这句话会报错(错误信息如下面贴出的图片所示)

                int lineLength = txtBoxDocument.GetLineText(rowIndex).Length;

                int start = txtBoxDocument.GetCharacterIndexFromLineIndex(rowIndex);

                txtBoxDocument.Focus();

                txtBoxDocument.Select(start, lineLength);

            }

            catch { }

        }

错误内容:当前方法的代码已经过优化,因此无法计算表达式的值。

但是,采用正确的调用顺序的方式不论是GetLineText(rowIndex).Length方式获取指定行的文本长度还是使用GetLineLength(rowIndex)方式获取指定行的文本长度,都是没问题的。具体缘由尚不明确,也没有查到相关的资料介绍。我自己的理解是在进行ScrollToLine(rowIndex)操作之前,先选中指定行的文本,此时,文本内容没有进行滚动,是个静止的状态,当先进行滚动在去选中指定文本,文本内容是个动态滚动的,可能此时.NET运行时需要做某些处理,因此,此时去获取指定行的文本长度或文本内容则容易出现问题。另外,认为文本内容滚动之后对于在可视范围内显示的文本相对于文本框的上边界的距离发生了变化,这也有可能是一个因素。不知道猜测是否正确,还希望各位大侠、专家给予指正,也好将其原理分享给其他程序员朋友。

时间: 2024-08-26 06:06:58

关于WPF中TextBox行的选择与显示的问题的相关文章

WPF中textbox加入文件拖放操作

namespace WpfApplication1{ public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void textbox1_PreviewDragOver(object sender, DragEventArgs e) { e.Effects = DragDropEffects.Copy; e.Handled = true; } private

在WPF中使用文件夹选择对话框

开发中有时会想实现"选择某个文件夹"的效果: 在WPF中,使用Microsoft.Win32.OpenFileDialog只能选择文件,FolderBrowserDialog只能用树型的方式选择文件夹,很不好用. 终于找到一个办法,使用Windows API Code Pack 在VS里打开Package Manager Console后输入Install-Package WindowsAPICodePack-Shell获取包后 就可以像这样打开选择文件夹Dialog了: var di

解决WPF中TextBox文件拖放问题

在WPF中,当我们尝试向TextBox中拖放文件,从而获取其路径时,往往无法成功(拖放文字可以成功).造成这种原因关键是WPF的TextBox对拖放事件处理机制的不同,具体可参考这篇文章Textbox Drag/Drop in WPF,本文只是介绍如何解决这一问题. 解放方法如下: 使用PreviewDragOver和PreviewDrop事件代替DragOver和Drop事件. <TextBox Height="100″ PreviewDragOver="TextBox_Pre

dev 中的GridControl中的行实现选择的功能实现

1.项目有实现不GridControl中的数据导出Excel的功能,导出的时候是把所有的数据全部导出,现在要实现可供选择的灵活的导出功能.除了全选可全不选,还可以对每一行实现选择的功能.实现起来比较简单,界面也很简单,先贴一下实现的界面. 2.实现思路:先要在传给GridControl的DataTable中增加新的字段,字段名称可以自己选择,显示出方框的形状以供选择.默认全部选择,所以调用函数时,传入的isSelected为false.实现代码: public void AddChooseCol

WPF 中TextBox 增加输入检测,错误提示

先来总结下实现错误提示功能的几个要点 1:binding 的ValidationRules 2 :Validation.ErrorTemplate 首先我们在界面添加一个TextBox, Text绑定到people对象的属性age public class People { public int age { get; set; } public string name { get; set; } } <TextBox x:Name="textBox" HorizontalAlig

wpf中的datagrid绑定操作按钮是否显示或者隐藏

如图,需要在wpf中的datagrid的操作那列有个确认按钮,然后在某些条件下确认按钮可见,某些情况下不可见的,放在mvc里直接在cshtml页面中if..else就行了. 但是在wpf里不行..网上搜索了好久才找到解决方法,原来只是binding那个visiable属性就行了, 原文地址:https://www.cnblogs.com/niunan/p/10840422.html

WPF中TextBox限制输入不起作用的问题

最近再用textbox做限制输入时遇到一个莫名其妙的问题: 首先看代码: <TextBox  Name="txtip1" Height="40" Width="60" FontSize="20"  MaxLength="3"  TextChanged="TextBox_TextChanged"> private void TextBox_TextChanged(object

wpf中textbox与textblock有什么区别

textbox是windows.form控件,textblock是WPF控件. 功能类似,但后者功能更强,也节省系统资源 wpf是基于directx技术的系统,向后兼容性更好. textblock只用来显示文本.

WPF中TextBox在.NET 4.5无法输入浮点数

最近发现一个很奇怪的现象,TextBox中的Text绑定double型数据,触发条件UpdateSourceTrigger=PropertyChanged时,在.net4.5框架下无法输入小数点,而在.net 4.0之前的框架不存在这个问题. 解决办法 修改Xmal中的StringFormat <Grid> <TextBox Text="{Binding Score,UpdateSourceTrigger=PropertyChanged, StringFormat={}{0}}