已经提出了类似的问题(例如,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
)。有什么想法吗?
答案 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);
}
}
}