防止在TextBox中选择文本

时间:2017-02-21 13:21:57

标签: c# winforms textbox custom-controls textselection

已经提出了类似的问题(例如,here),但是我没有找到针对我的具体案例的答案。我正在构建一个基于DevExpress控件的自定义控件,该控件依次基于标准TextBox而且我的闪烁问题似乎是由于基本的TextBox组件,它试图更新选择

如果不解释我的自定义控件的所有细节,要重现此问题,您只需要在TextBox中放置Form,然后使用此代码:

public partial class Form1 : Form {
    public Form1() {
        InitializeComponent();
        textBox1.MouseMove += TextBox1_MouseMove;
    }

    private void TextBox1_MouseMove(object sender, MouseEventArgs e) {
        (sender as TextBox).Text = DateTime.Now.Ticks.ToString();
    }
}

如果您启动它,则单击TextBox,然后将光标向右移动,您会发现闪烁问题(请参阅视频here)。对于我的自定义控件,我需要避免这种闪烁。我必然会使用TextBox(所以没有RichTextBox)。有什么想法吗?

3 个答案:

答案 0 :(得分:1)

Reza Aghaei同时通过覆盖WndProc和拦截WM_SETFOCUS消息提供了解决方案。见here

答案 1 :(得分:0)

根据您的想法,有几种解决方案:

如果你想阻止选择,那就是:

        private void TextBox1_MouseMove(object sender, MouseEventArgs e)
    {
        (sender as TextBox).Text = DateTime.Now.Ticks.ToString();
        (sender as TextBox).SelectionLength = 0;
    }

或选择全部:

        private void TextBox1_MouseMove(object sender, MouseEventArgs e)
    {
        (sender as TextBox).Text = DateTime.Now.Ticks.ToString();
        (sender as TextBox).SelectAll();
    }

除此之外,您还可以指定选择的条件,例如:

        private void TextBox1_MouseMove(object sender, MouseEventArgs e)
    {
        (sender as TextBox).Text = DateTime.Now.Ticks.ToString();
        if (MouseButtons == MouseButtons.Left) (sender as TextBox).SelectAll();
        else (sender as TextBox).SelectionLength = 0;
    }

但是只要您想要选择文本,您总会得到一些闪烁,因为普通的Textbox不可能使用BeginEdit和EndEdit之类的东西,所以它会先改变文本然后再选择它。

答案 2 :(得分:0)

观看视频时,您的文本框似乎不必要地调用WM_ERASEBKGND。为了解决这个问题,您可以继承textbox类并拦截这些消息。下面是示例代码应该做的技巧(未经测试)免责声明:我已经将此技术用于其他WinForm控件,这些控件具有视频中显示的闪烁类型,但不是TextBox。如果它对您有用,请告诉我。祝你好运!

// textbox no flicker
public partial class TexttBoxNF : TextBox
{
    public TexttBoxNF()
    {
    }

    public TexttBoxNF(IContainer container)
    {
        container.Add(this);

        InitializeComponent();

        //Activate double buffering
        this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);

        //Enable the OnNotifyMessage event so we get a chance to filter out 
        // Windows messages before they get to the form's WndProc
        this.SetStyle(ControlStyles.EnableNotifyMessage, true);
    }

    //http://stackoverflow.com/questions/442817/c-sharp-flickering-listview-on-update
    protected override void OnNotifyMessage(Message m)
    {
        //Filter out the WM_ERASEBKGND message
        if (m.Msg != 0x14)
        {
            base.OnNotifyMessage(m);
        }
    }
}