文本框无法点击但可编辑

我有一个带有10个文本框的小表单,我将它们设置在右边的Tab顺序中,目前我希望它们以Tab To的方式。 我想知道是否有办法设置文本框,因此除非它们被选中,否则无法选择它们进行编辑。 ie …我不希望最终用户能够点击文本框来编辑它们,我只希望它们可以通过Tabbing进行编辑。

这应该可以解决问题

 public partial class PoorTextBox : TextBox { protected override void WndProc(ref Message m) { if (m.Msg == (int) WM.LBUTTONDOWN) { return;//Eat mouse down events } base.WndProc(ref m); } } 

窗口消息枚举可以在这里找到。


如何在不inheritanceTextBox情况下执行此操作:

 class EatMouseDown : NativeWindow { protected override void WndProc(ref Message m) { if (m.Msg == (int)WM.LBUTTONDOWN) { return; } base.WndProc(ref m); } } protected override void OnLoad(EventArgs e) { base.OnLoad(e); new EatMouseDown().AssignHandle(textBox1.Handle);//Subclass a Handle } 

如何做到没有任何inheritance:

清理部分省略,这也很重要。 这可能是错误的但是有效。 推荐的方法是使用inheritance。 从.net fw src中提取所需的方法。

 class EatMouseDown { public delegate IntPtr WndProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam); #region External methods... [DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern IntPtr SetWindowLong(HandleRef hWnd, int nIndex, WndProc wndproc); [DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern IntPtr SetWindowLongPtr(HandleRef hWnd, int nIndex, WndProc wndproc); [DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern IntPtr GetWindowLong(HandleRef hWnd, int nIndex); [DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern IntPtr GetWindowLongPtr(HandleRef hWnd, int nIndex); [DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern IntPtr DefWindowProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam); [DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern IntPtr CallWindowProc(IntPtr wndProc, IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam); #endregion private const int GWLP_WNDPROC = -4; private IntPtr handle; private IntPtr originalWndProc; private IntPtr currentWndProc; public static IntPtr SetWindowLongHelper(HandleRef hWnd, int nIndex, WndProc wndProc) { return IntPtr.Size == 4 ? SetWindowLong(hWnd, nIndex, wndProc) : SetWindowLongPtr(hWnd, nIndex, wndProc); } public static IntPtr GetWindowLongHelper(HandleRef hWnd, int nIndex) { return IntPtr.Size == 4 ? GetWindowLong(hWnd, nIndex) : GetWindowLongPtr(hWnd, nIndex); } internal void SubclassHandle(IntPtr handle) { this.handle = handle; this.originalWndProc = GetWindowLongHelper(new HandleRef(this, handle), GWLP_WNDPROC); SetWindowLongHelper(new HandleRef(this, handle), GWLP_WNDPROC, new WndProc(this.Callback)); this.currentWndProc = GetWindowLongHelper(new HandleRef(this, handle), GWLP_WNDPROC); } private IntPtr Callback(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam) { var m = Message.Create(hwnd, msg, wparam, lparam); if (m.Msg == (int)WM.LBUTTONDOWN) { return IntPtr.Zero; } return CallWindowProc(originalWndProc, hwnd, msg, wparam, lparam); } } protected override void OnLoad(EventArgs e) { base.OnLoad(e); new EatMouseDown().SubclassHandle(textBox1.Handle);//Subclass a Handle } 

这是与Sriram Sakthivel所做的类似的方法,但使用IMessageFilter代替:

 public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { List TextBoxes = new List(); FindTextBoxes(this, TextBoxes); Application.AddMessageFilter(new SuppressTextBoxClicks(TextBoxes)); } private void FindTextBoxes(Control ctl, List TBs) { foreach(Control childCtl in ctl.Controls) { if (childCtl is TextBox) { TBs.Add((TextBox)childCtl); } else if(childCtl.HasChildren) { FindTextBoxes(childCtl, TBs); } } } } public class SuppressTextBoxClicks : IMessageFilter { private List _TextBoxes = null; private const int WM_LBUTTONDOWN = 0x201; public SuppressTextBoxClicks(List TextBoxes) { _TextBoxes = TextBoxes; } public bool PreFilterMessage(ref Message m) { switch (m.Msg) { case WM_LBUTTONDOWN: if (_TextBoxes != null) { foreach(TextBox TB in _TextBoxes) { if (TB.Handle.Equals(m.HWnd)) { return true; } } } break; default: break; } return false; } } 

将所有文本框的Enabled属性设置为false ,第一个除外。 在TextChanged事件上,检查Text是否为空。 如果它不为空,启用下一个TextBox,依此类推……

您也可以使用Enter事件foreach TextBox尝试这个

  private void textBox2_Enter(object sender, EventArgs e) { if (textBox1.Text == "") textBox1.Focus(); } private void textBox3_Enter(object sender, EventArgs e) { if (textBox1.Text == "") textBox1.Focus(); else if (textBox2.Text == "") textBox2.Focus(); } private void textBox4_Enter(object sender, EventArgs e) { if (textBox1.Text == "") textBox1.Focus(); else if (textBox2.Text == "") textBox2.Focus(); else if (textBox3.Text == "") textBox3.Focus(); }