扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
最近做了一个小工具,其中用到了WPF中的TextBox控件。对于这个控件的使用,其中主要的一个功能是需要选择指定的行,并将其显示在控件可见区域的视图中(如果不在可视区域时,需要控件自动滚动到改行)。在我使用时,发现一个问题,如果当我先将指定的行滚动至视图中,然后在将其选中,则经常会不稳定,有时能定位并选中,有时则会选中错误位置,或者报错。现在我想将我遇到的问题以代码的方式进行说明,以及我的解决方案。不过,目前其原因还未搞明白,如果有高人,还请给予指点。
博罗ssl适用于网站、小程序/APP、API接口等需要进行数据传输应用场景,ssl证书未来市场广阔!成为创新互联建站的ssl证书销售渠道,可以享受市场价格4-6折优惠!如果有意向欢迎电话联系或者加微信:18980820575(备注:SSL证书合作)期待与您的合作!首先,在自定义控件中添加一个TextBox控件,命名为txtBoxDocument,并在控件中提供两个公共方法GoToLine(int rowIndex)和SelectedLine(int rowIndex),用来定位并滚动至指定行和选中改行。
////// 定位到指定行 /// /// 指定的从零开始的行的索引 public void GoToLine(int rowIndex) { txtBoxDocument.ScrollToLine(rowIndex); } ////// 选中指定的行 /// /// 指定的从零开始的行的索引 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):
////// 选中指定的行 /// /// 指定的从零开始的行的索引 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运行时需要做某些处理,因此,此时去获取指定行的文本长度或文本内容则容易出现问题。另外,认为文本内容滚动之后对于在可视范围内显示的文本相对于文本框的上边界的距离发生了变化,这也有可能是一个因素。不知道猜测是否正确,还希望各位大侠、专家给予指正,也好将其原理分享给其他程序员朋友。
另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流