To prevent entering special characters on textbox ( Already have thousand of textboxes in solution )

后端 未结 2 1968
野趣味
野趣味 2021-01-29 04:00

We have a advanced software written by using c# ( windows forms ). In their we have 1000 or more textboxes. I need to validate user input on all these textboxes to stop entering

2条回答
  •  猫巷女王i
    2021-01-29 04:25

    "Is there any way to handle this from a single place and affect for every textboxes"

    There's a few ways. But it seems you don't want to edit the textbox itself, so there's only one reliable way I'm aware of; attaching a global keyboard hook. Code follows:

    class GlobalKeyboardHook
            {
                #region DLL Imports
                [DllImport("user32.dll")]
                static extern IntPtr SetWindowsHookEx(int hookEventId, keyboardProc callback, IntPtr handleInstance, uint threadId);
    
                [DllImport("user32.dll")]
                static extern bool UnhookWindowsHookEx(IntPtr handleInstance);
    
                [DllImport("user32.dll")]
                static extern int CallNextHookEx(IntPtr ignoredParameter, int hookCode, int wParam, ref KeyboardHookStruct lParam);
    
                [DllImport("kernel32.dll")]
                static extern IntPtr LoadLibrary(string libFileName);
    
                [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
                private static extern IntPtr GetModuleHandle(string lpModuleName);
                #endregion DLL Imports
    
                #region Class Declarations
                private delegate int keyboardProc(int code, int wParam, ref KeyboardHookStruct lParam);
                private keyboardProc kbdProc;
    
                public struct KeyboardHookStruct
                {
                    public int vkCode;
                    public int scanCode;
                    public int flags;
                    public int time;
                    public int extraInfo;
                }
    
                private static class KeyboardMessages
                {
                    public const int WH_KEYBOARD_LL = 13;
                    public const int WM_KEYDOWN = 0x100;
                    public const int WM_KEYUP = 0x101;
                    public const int WM_SYSKEYDOWN = 0x104;
                    public const int WM_SYSKEYUP = 0x105;
                }
                
                IntPtr HookPointer = IntPtr.Zero;
                IntPtr ModuleInstance = IntPtr.Zero;
    
                public event KeyEventHandler KeyDown;
                public event KeyEventHandler KeyUp;
    
                #endregion Class Declarations
    
                #region Class Functions
                public GlobalKeyboardHook() {
                    EnableHook(true, null);
                }
    
                public GlobalKeyboardHook(Process P) {
                    EnableHook(true, P);
                }
    
                ~GlobalKeyboardHook() {
                    EnableHook(false, null);
                }
    
                public void EnableHook(bool Enabled)
                {
                    EnableHook(Enabled, null);
                }
    
                public void EnableHook(bool Enabled, Process P) {
                    if (Enabled)
                    {
                        HookPointer = SetWindowsHookEx(KeyboardMessages.WH_KEYBOARD_LL, kbdProc = HookCallback, ModuleInstance = P == null ? LoadLibrary("User32") : GetModuleHandle(P.MainModule.ModuleName), 0);
                    }
                    else
                    {
                        UnhookWindowsHookEx(HookPointer);
                        HookPointer = IntPtr.Zero;
                        ModuleInstance = IntPtr.Zero;
                        kbdProc = null;
                    }  
                }
    
                public int HookCallback(int code, int wParam, ref KeyboardHookStruct lParam) {
                    if (code >= 0) {    
                        KeyEventArgs key = new KeyEventArgs((Keys)lParam.vkCode);
                        if ((wParam == KeyboardMessages.WM_KEYDOWN || wParam == KeyboardMessages.WM_SYSKEYDOWN) && (KeyDown != null)) {
                            KeyDown(this, key) ;
                        } else if ((wParam == KeyboardMessages.WM_KEYUP || wParam == KeyboardMessages.WM_SYSKEYUP) && (KeyUp != null)) {
                            KeyUp(this, key);
                        }
                        if (key.Handled)
                            return 1;
                    }
                    return CallNextHookEx(HookPointer, code, wParam, ref lParam);
                }
                #endregion Class Functions
            }
    

    To activate we add the following:

    GlobalKeyboardHook ghk = new GlobalKeyboardHook(Process.GetCurrentProcess());
    Type tbType = typeof(TextBox);
    ghk.KeyDown += new KeyEventHandler(() => {
        if (typeof(this.ActiveControl) == tbType)
            RunValidation(this.ActiveControl.Text);
    });
    

    Once you have the boilerplate hook, adding validation becomes pretty simple. No loops means you're not wasting processor time iterating over a thousand text boxes.

    Just remember this will apply to ALL controls of type TextBox within the current process. If you add a custom TextBox control or don't want to check all of them - that should be accounted for prior to calling RunValidation().

提交回复
热议问题