700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 重写Winform的Textbox单行模式下滚动条。

重写Winform的Textbox单行模式下滚动条。

时间:2018-08-27 02:50:40

相关推荐

重写Winform的Textbox单行模式下滚动条。

C#Textbox,必须同时设置属性Multiline =True、ScrollBars=Horizontal、WordWrap=False才会显示出水平滚动条,且默认字体大小下,控件的Size.Height >= 33才能正常显示完全文本。这非常的丑陋!占空间!

想着能调节压缩一下滚动条的高度就好了,只是现实太残酷,滚动条没有高度属性可设置!!!

只能想办法重写Textbox了。折腾两天,各种百度,终于实现自己想要的结果。

1、新建自定义控件,改变继承自TextBox。

public partial class TinyXScrollBarTextBox : TextBox

2、在TinyXScrollBarTextBox的设计模式中,拖放两个panel作为滚动条和滑块。分别命名为:panelXScrollBar、panelXScrollSlider。

3、在InitializeComponent()函数中设置,this.Controls.Add(this.panelXScrollBar);this.panelXScrollBar.Controls.Add(this.panelXScrollSlider);

4、初始化三个关键属性,

public TinyXScrollBarTextBox(){InitializeComponent();base.Multiline = true;base.WordWrap = false;base.ScrollBars = ScrollBars.None;}

并加入如下代码,屏蔽其修改:

/// <summary>/// 屏蔽系统的滚动条设置。并显示为水平滚动,实际为 base.ScrollBars = ScrollBars.None;/// </summary>[Browsable(false)][EditorBrowsable(EditorBrowsableState.Never)]public new ScrollBars ScrollBars{get{return ScrollBars.Horizontal;}set{base.ScrollBars = ScrollBars.None;}} /// <summary>/// 屏蔽系统的多行开关,实际为 base.Multiline = true;/// </summary>//[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)][Browsable(false)][EditorBrowsable(EditorBrowsableState.Never)]public new bool Multiline{get{return true;}set{base.Multiline = true;}}[Browsable(false)][EditorBrowsable(EditorBrowsableState.Never)]public new bool WordWrap{get{return false;}set{base.WordWrap = false;}}

5、文本框文本发生变化时,过滤掉转行、回车(\ror \n)。并禁止输入回车键,使现为多行模式下表现得像单行模式。

protected override void OnTextChanged(EventArgs e){ClearRNChar();var w = panelXScrollBar.Width;textGdiWidth = TextRenderer.MeasureText(Text, Font).Width;if (textGdiWidth > w){this.panelXScrollBar.Visible = true;var ws = panelXScrollBar.Width * 2 - textGdiWidth;ws = ws < 25 ? 25 : ws; //计算滑块的长度,并设置最小为25个像素。panelXScrollSlider.Width = ws;var sliderW = panelXScrollBar.Width - panelXScrollSlider.Width;int indexWidth = GetTextGdiWidthByIndex(SelectionStart);SliderLeft = (int)((indexWidth * 1.0) / textGdiWidth * sliderW);}else{panelXScrollBar.Visible = false;var start = SelectionStart;SelectionStart = 0;ScrollToCaret();SelectionStart = start;}base.OnTextChanged(e);}private void TinyXScrollBarTextBox_KeyDown(object sender, KeyEventArgs e){//屏蔽回车键if ((int)e.KeyCode == 13){e.SuppressKeyPress = true;}}

6、滑块的滑动代码,这部分来源于网络,找不到来源了,也不难。

private static bool IsMove = false; //标识 鼠标在滑块上的运动状态 初始为falseprivate int X; //定义一个变量 用于记录鼠标进入滑块中并按下时的位置private void panelXScrollSlider_MouseDown(object sender, MouseEventArgs e)//鼠标对滑块的按下事件 {IsMove = true; //标识鼠标开始移动 X = e.Location.X;//鼠标的初始位置的X坐标panelXScrollSlider.BackColor = Color.FromArgb(200, 100, 100, 100); ; //滑块颜色变为深一点的色}private void panelXScrollSlider_MouseMove(object sender, MouseEventArgs e)//鼠标对滑块的 移动 事件{if (IsMove == true) //如果鼠标开始移动{if (panelXScrollSlider.Right >= this.Width){if ((e.Location.X - X) < 0) //如果 鼠标向左滑动 {panelXScrollSlider.Left += e.Location.X - X; //将滑块的位置增加 增加的量是鼠标移动的距离}else //如果鼠标向下移动{panelXScrollSlider.Left = this.Width - panelXScrollSlider.Width; //滑块的位置始终为 滑条最底部的位置}}else if (panelXScrollSlider.Left <= 0){if ((e.Location.X - X) > 0){panelXScrollSlider.Left += e.Location.X - X;}else{panelXScrollSlider.Left = 0;}}else{panelXScrollSlider.Left += e.Location.X - X;}}}private void panelXScrollSlider_MouseUp(object sender, MouseEventArgs e) //当鼠标松开时候 意味着 用户 不再需要滑动滑块{IsMove = false; //此时将标识变为falsepanelXScrollSlider.BackColor = Color.FromArgb(100, 100, 100, 100); //颜色变为原来的暗色SliderLeft = panelXScrollSlider.Left;//通过设置触发内容的滚动。}private void panelXScrollSlider_MouseEnter(object sender, EventArgs e){panelXScrollSlider.BackColor = Color.FromArgb(200, 100, 100, 100);}private void panelXScrollSlider_MouseLeave(object sender, EventArgs e){panelXScrollSlider.BackColor = Color.FromArgb(100, 100, 100, 100);}

7、鼠标点滚动条的操作:在滑块的右侧点击,则向右滚动,反之亦然

/// <summary>/// 在滑块的右侧点击,则向右滚动,反之亦然/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void panelXScrollBar_MouseClick(object sender, MouseEventArgs e){if (Text.Length == 0){return;}int oldStart = SelectionStart;int oldSlectedLen = SelectionLength;var ns = 0;if (e.X > panelXScrollSlider.Right){var rightindex = GetCharIndexFromPosition(new Point(this.panelXScrollBar.Right - 3, 1));ns = rightindex + 1;ns = ns > Text.Length - 1 ? Text.Length : ns;}else if (e.X < panelXScrollSlider.Left){var leftindex = GetCharIndexFromPosition(new Point(3, 1));ns = leftindex - 1;ns = ns < 0 ? 0 : ns;}SelectionStart = ns;SelectionLength = 0;ScrollToCaret();var left = (int)((ns * 1.0 / Text.Length) * (panelXScrollBar.Width - panelXScrollSlider.Width));panelXScrollSlider.Left = left;SelectionStart = oldStart;SelectionLength = oldSlectedLen;}

8、滑块与光标的联动。这一块实现得不是丝滑,不过差不多就得了。

找了很久也没有找到文字滚动的控制方式 ,只能利用了ScrollToCaret()来控制。

ScrollToCaret()只要光标能显示出来,就不再滚动,控制起来有些不够丝滑!同时滑块的位置计算也不是很精准,只是大概这样子。

----end----夜已深。不详写了,有兴趣的同学可以下载资源:

C#重写Winform的Textbox单行模式下滚动条。-C#文档类资源-CSDN下载

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。