none
一个只显示数字的TextBox,怎么实现一直按着按钮或键盘某个键时,Textbox里的数字一直增长或减少? RRS feed

  • 问题

  • 如题。

    鼠标一直按着按钮或者一直按着键盘某个键,只要一直按着,Text里面的数字就不断上升和减少。这个一直按着的事件是什么?

    2019年2月22日 10:43

答案

  • 如题。

    鼠标一直按着按钮或者一直按着键盘某个键,只要一直按着,Text里面的数字就不断上升和减少。这个一直按着的事件是什么?

    Hi  Trian555,   

    >>鼠标一直按着按钮或者一直按着键盘某个键,只要一直按着,Text里面的数字就不断上升和减少。这个一直按着的事件是什么?


    如果需要尝试键盘钩子来实现,你可以参考下面:

         // hook keyboard 注册
                IntPtr hModule = GetModuleHandle(IntPtr.Zero);
                hookProc = new LowLevelKeyboardProcDelegate(LowLevelKeyboardProc);
                hHook = SetWindowsHookEx(WH_KEYBOARD_LL, hookProc, hModule, 0);
                if (hHook == IntPtr.Zero)
                {
                    MessageBox.Show("Failed to set hook, error = " + Marshal.GetLastWin32Error());
                }
    
    
            private struct KBDLLHOOKSTRUCT
            {
                public int vkCode;
                int scanCode;
                public int flags;
                int time;
                int dwExtraInfo;
            }
    
            private delegate int LowLevelKeyboardProcDelegate(int nCode, int wParam, ref KBDLLHOOKSTRUCT lParam);
    
            [DllImport("user32.dll")]
            private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProcDelegate lpfn, IntPtr hMod, int dwThreadId);
    
            [DllImport("user32.dll")]
            private static extern bool UnhookWindowsHookEx(IntPtr hHook);
    
            [DllImport("user32.dll")]
            private static extern int CallNextHookEx(int hHook, int nCode, int wParam, ref KBDLLHOOKSTRUCT lParam);
    
            [DllImport("kernel32.dll")]
            private static extern IntPtr GetModuleHandle(IntPtr path);
    
            private IntPtr hHook;
            LowLevelKeyboardProcDelegate hookProc; // prevent gc
            const int WH_KEYBOARD_LL = 13;
    
            private   int LowLevelKeyboardProc(int nCode, int wParam, ref KBDLLHOOKSTRUCT lParam)
            {
                if (nCode >= 0)
                    switch (wParam)
                    {
                        case 256: // WM_KEYDOWN
                            if (lParam.vkCode == 13)//enter
                            {
                               
                                Countplus++; // 一个 DependencyProperty属性
                               
                                return CallNextHookEx(1, nCode, wParam, ref lParam);
                            }
                            break;
                        case 257: // WM_KEYUP
                            break;
                    }
                return CallNextHookEx(0, nCode, wParam, ref lParam);
            }
    
            private void Window_Closed(object sender, EventArgs e)
            {
                UnhookWindowsHookEx(hHook); // release keyboard hook
            }
    此外,请通过标记有用的帖子作为答案来关闭线程。 如果他们遇到类似问题,这将有助于其他成员快速找到解决方案。 如果您有新问题,可以启动一个新线程,其中包含所有必要的代码片段,以便能够从头开始重现您的问题以及有关结果的详细说明,包括任何异常消息。

     

    Best Regards,

    Yong Lu


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • 已标记为答案 Trian555 2019年2月27日 2:45
    2019年2月25日 3:24
    版主
  • 键盘事件:

    KeyDown

    鼠标事件

    MouseLeftButtonDown或者MouseButtonDown

    除此还可以通过鼠标钩子或者键盘钩子来获取的系统全局的事件

    在事件里面需要配合其他的代码来实现

    注意的是

    如果直接将键盘事件写在Box里面则会出现字符。

    如果写在面板控件上请提前设置好焦点

     <Grid  Focusable="True" x:Name="G" KeyDown="TB_KeyDown"  Background="Transparent"  MouseLeftButtonDown="Grid_MouseLeftButtonDown" >
            <TextBlock x:Name="STB" Margin="336,122,320,253"/>
            <TextBox  x:Name="TB" Margin="307,181,296,170" />
        </Grid>

      public partial class MainWindow : Window
        {
            DispatcherTimer Timer = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(50) };
            public MainWindow()
            {
                InitializeComponent();
                G.Focus();
            }
    
    
            int i = 0;
            private void TB_KeyDown(object sender, KeyEventArgs e)
            {
    
                switch (e.SystemKey)
                {
                    case Key.LeftAlt:
                        i++;
                        Debug.WriteLine(i);
                        TB.Text = i.ToString();
                        STB.Text = "Key";
                        break;
                }
    
            }
            
            private void Grid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
            {
                if (e.LeftButton == MouseButtonState.Pressed)
                {
                    Timer.Start();
                    Timer.Tick += Timer_Tick;
                }
    
            }
    
            private void Timer_Tick(object sender, EventArgs e)
            {
                if (Mouse.LeftButton == MouseButtonState.Pressed)
                {
                    i++;
                    TB.Text = i.ToString();
                    STB.Text = "Mosue";
                }
                else
                    Timer.Stop();
            }
    
          
        }

    我用的是按钮的PreviewMouseLeftButtonDown事件,我发现在TabItem里使用有些问题,如果祖父空间中有个TabItem。如果点击按钮自增数字几秒,然后在点击所属的TabItem的时候,TextBox里的数字也在自增。设置了e.Handled没什么用,这个是怎么回事?如何解决?
    • 已标记为答案 Trian555 2019年2月27日 2:45
    2019年2月23日 2:49

全部回复

  • 键盘事件:

    KeyDown

    鼠标事件

    MouseLeftButtonDown或者MouseButtonDown

    除此还可以通过鼠标钩子或者键盘钩子来获取的系统全局的事件

    在事件里面需要配合其他的代码来实现

    注意的是

    如果直接将键盘事件写在Box里面则会出现字符。

    如果写在面板控件上请提前设置好焦点

     <Grid  Focusable="True" x:Name="G" KeyDown="TB_KeyDown"  Background="Transparent"  MouseLeftButtonDown="Grid_MouseLeftButtonDown" >
            <TextBlock x:Name="STB" Margin="336,122,320,253"/>
            <TextBox  x:Name="TB" Margin="307,181,296,170" />
        </Grid>

      public partial class MainWindow : Window
        {
            DispatcherTimer Timer = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(50) };
            public MainWindow()
            {
                InitializeComponent();
                G.Focus();
            }
    
    
            int i = 0;
            private void TB_KeyDown(object sender, KeyEventArgs e)
            {
    
                switch (e.SystemKey)
                {
                    case Key.LeftAlt:
                        i++;
                        Debug.WriteLine(i);
                        TB.Text = i.ToString();
                        STB.Text = "Key";
                        break;
                }
    
            }
            
            private void Grid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
            {
                if (e.LeftButton == MouseButtonState.Pressed)
                {
                    Timer.Start();
                    Timer.Tick += Timer_Tick;
                }
    
            }
    
            private void Timer_Tick(object sender, EventArgs e)
            {
                if (Mouse.LeftButton == MouseButtonState.Pressed)
                {
                    i++;
                    TB.Text = i.ToString();
                    STB.Text = "Mosue";
                }
                else
                    Timer.Stop();
            }
    
          
        }

    • 已编辑 ARM830 2019年2月22日 15:34
    2019年2月22日 14:14
  • 键盘事件:

    KeyDown

    鼠标事件

    MouseLeftButtonDown或者MouseButtonDown

    除此还可以通过鼠标钩子或者键盘钩子来获取的系统全局的事件

    在事件里面需要配合其他的代码来实现

    注意的是

    如果直接将键盘事件写在Box里面则会出现字符。

    如果写在面板控件上请提前设置好焦点

     <Grid  Focusable="True" x:Name="G" KeyDown="TB_KeyDown"  Background="Transparent"  MouseLeftButtonDown="Grid_MouseLeftButtonDown" >
            <TextBlock x:Name="STB" Margin="336,122,320,253"/>
            <TextBox  x:Name="TB" Margin="307,181,296,170" />
        </Grid>

      public partial class MainWindow : Window
        {
            DispatcherTimer Timer = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(50) };
            public MainWindow()
            {
                InitializeComponent();
                G.Focus();
            }
    
    
            int i = 0;
            private void TB_KeyDown(object sender, KeyEventArgs e)
            {
    
                switch (e.SystemKey)
                {
                    case Key.LeftAlt:
                        i++;
                        Debug.WriteLine(i);
                        TB.Text = i.ToString();
                        STB.Text = "Key";
                        break;
                }
    
            }
            
            private void Grid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
            {
                if (e.LeftButton == MouseButtonState.Pressed)
                {
                    Timer.Start();
                    Timer.Tick += Timer_Tick;
                }
    
            }
    
            private void Timer_Tick(object sender, EventArgs e)
            {
                if (Mouse.LeftButton == MouseButtonState.Pressed)
                {
                    i++;
                    TB.Text = i.ToString();
                    STB.Text = "Mosue";
                }
                else
                    Timer.Stop();
            }
    
          
        }

    我用的是按钮的PreviewMouseLeftButtonDown事件,我发现在TabItem里使用有些问题,如果祖父空间中有个TabItem。如果点击按钮自增数字几秒,然后在点击所属的TabItem的时候,TextBox里的数字也在自增。设置了e.Handled没什么用,这个是怎么回事?如何解决?
    • 已标记为答案 Trian555 2019年2月27日 2:45
    2019年2月23日 2:49
  • 我这面

    使用TabControl+Tabitem作为父控件,使用隧道事件,并没有发现你说的错误。

    能否将你的代码贴上来

    2019年2月23日 10:07
  • 如题。

    鼠标一直按着按钮或者一直按着键盘某个键,只要一直按着,Text里面的数字就不断上升和减少。这个一直按着的事件是什么?

    Hi  Trian555,   

    >>鼠标一直按着按钮或者一直按着键盘某个键,只要一直按着,Text里面的数字就不断上升和减少。这个一直按着的事件是什么?


    如果需要尝试键盘钩子来实现,你可以参考下面:

         // hook keyboard 注册
                IntPtr hModule = GetModuleHandle(IntPtr.Zero);
                hookProc = new LowLevelKeyboardProcDelegate(LowLevelKeyboardProc);
                hHook = SetWindowsHookEx(WH_KEYBOARD_LL, hookProc, hModule, 0);
                if (hHook == IntPtr.Zero)
                {
                    MessageBox.Show("Failed to set hook, error = " + Marshal.GetLastWin32Error());
                }
    
    
            private struct KBDLLHOOKSTRUCT
            {
                public int vkCode;
                int scanCode;
                public int flags;
                int time;
                int dwExtraInfo;
            }
    
            private delegate int LowLevelKeyboardProcDelegate(int nCode, int wParam, ref KBDLLHOOKSTRUCT lParam);
    
            [DllImport("user32.dll")]
            private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProcDelegate lpfn, IntPtr hMod, int dwThreadId);
    
            [DllImport("user32.dll")]
            private static extern bool UnhookWindowsHookEx(IntPtr hHook);
    
            [DllImport("user32.dll")]
            private static extern int CallNextHookEx(int hHook, int nCode, int wParam, ref KBDLLHOOKSTRUCT lParam);
    
            [DllImport("kernel32.dll")]
            private static extern IntPtr GetModuleHandle(IntPtr path);
    
            private IntPtr hHook;
            LowLevelKeyboardProcDelegate hookProc; // prevent gc
            const int WH_KEYBOARD_LL = 13;
    
            private   int LowLevelKeyboardProc(int nCode, int wParam, ref KBDLLHOOKSTRUCT lParam)
            {
                if (nCode >= 0)
                    switch (wParam)
                    {
                        case 256: // WM_KEYDOWN
                            if (lParam.vkCode == 13)//enter
                            {
                               
                                Countplus++; // 一个 DependencyProperty属性
                               
                                return CallNextHookEx(1, nCode, wParam, ref lParam);
                            }
                            break;
                        case 257: // WM_KEYUP
                            break;
                    }
                return CallNextHookEx(0, nCode, wParam, ref lParam);
            }
    
            private void Window_Closed(object sender, EventArgs e)
            {
                UnhookWindowsHookEx(hHook); // release keyboard hook
            }
    此外,请通过标记有用的帖子作为答案来关闭线程。 如果他们遇到类似问题,这将有助于其他成员快速找到解决方案。 如果您有新问题,可以启动一个新线程,其中包含所有必要的代码片段,以便能够从头开始重现您的问题以及有关结果的详细说明,包括任何异常消息。

     

    Best Regards,

    Yong Lu


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • 已标记为答案 Trian555 2019年2月27日 2:45
    2019年2月25日 3:24
    版主