none
假如键盘输入焦点在一个textBox里面,此时鼠标移动到另外一个列表框上面滚动滚轮,就不能让列表框里面的内容滚动了吗? RRS feed

  • 问题

  • 键盘输入焦点在一个textBox里面,此时鼠标移动到另外一个列表框上面滚动滚轮,就不能让列表框里面的内容滚动了吗?

    难道必须在列表框上点一下鼠标才能够滚动吗?只是点了一下之后,输入焦点就不再是textbox了。

    我是希望能够实现即使输入焦点不在列表框里面,只要鼠标在它上面滚动就能够让列表框的内容滚动的效果,而同时我就可以继续在textBox上输入内容。不知道有没有方法可以实现?


    da jia hao!
    2012年1月3日 7:03

答案

  • hi,我想我可能找到了解决的方法,看看下面的代码:

     

            textBox1.MouseWheel += new MouseEventHandler(textBox1_MouseWheel);

            void textBox1_MouseWheel(object sender, MouseEventArgs e)
            {
                if (e.Delta > 0)
                    SendMessage(listBox1.Handle, 0x0100, 0x26, 0);
                else
                    SendMessage(listBox1.Handle, 0x0100, 0x28, 0);
            }

     

    原理就是在textbox里面的时候,处理mousewheel事件,然后向listbox发送WM_KEYDOWN消息,这样就行了!测试有效果!

    不过呢,效果始终比不上web上大量可见的自动完成效果。。真的有点遗憾。。。

     

    另外,向listbox发送WM_MOUSEWHEEL事件没效果,可能这个消息要求一定有输入焦点才可以吧!

     


    da jia hao!
    2012年1月5日 13:14

全部回复

  • 键盘输入焦点在一个textBox里面,此时鼠标移动到另外一个列表框上面滚动滚轮,就不能让列表框里面的内容滚动了吗?

    难道必须在列表框上点一下鼠标才能够滚动吗?只是点了一下之后,输入焦点就不再是textbox了。

    我是希望能够实现即使输入焦点不在列表框里面,只要鼠标在它上面滚动就能够让列表框的内容滚动的效果,而同时我就可以继续在textBox上输入内容。不知道有没有方法可以实现?


    da jia hao!

    恐怕不行。如果你要这样做,建议使用Timer自动实现类似滚屏的效果(Timer的Interval=500,Enabled=True)

    namespace WinFormCSharp
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }

            private void Form1_Load(object senderEventArgs e)
            {
                //模拟产生500个数据
                for (int i = 1i < 501i++)
                {
                    listBox1.Items.Add(i);
                }
            }

            private void timer1_Tick(object senderEventArgs e)
            {
                listBox1.SelectedIndex++;
            }
        }
    }

       QQ我:讨论(Talk)
    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处

    2012年1月4日 5:37
    版主
  • 谢谢回复。不过我是要求只有用户滚动鼠标滚轮的时候列表框才滚动啊,所以看来还是不行了。

    我的目的其实是想用listbox来模拟web上自动完成的功能,虽然C#的textbox本身带有autocomplete功能,但是它的功能太弱智,无法满足要求,所以只好自己做。

    自己做的话,能够想到的方法就是用一个listbox来显示选项,可这样就不能实现鼠标滚动的效果,比起在IE上还是差了很多。。。


    da jia hao!
    2012年1月4日 7:47
  • 谢谢回复。不过我是要求只有用户滚动鼠标滚轮的时候列表框才滚动啊,所以看来还是不行了。

    我的目的其实是想用listbox来模拟web上自动完成的功能,虽然C#的textbox本身带有autocomplete功能,但是它的功能太弱智,无法满足要求,所以只好自己做。

    自己做的话,能够想到的方法就是用一个listbox来显示选项,可这样就不能实现鼠标滚动的效果,比起在IE上还是差了很多。。。


    da jia hao!

    那我建议你直接使用Combobox,设置其属性:


       QQ我:讨论(Talk)
    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处
    2012年1月4日 8:10
    版主
  • 谢谢回复。不过其实textbox和combobox的autocomplete都是一样的,缺点是只能匹配开头的字符。例如有一个选项为“AAA88899”,那么只有你输入“A”的时候才会列出这个选项,如果你输入“88”等其他字符都不会出现这个选项。这种功能我想用户是难以接受的。。。

    为什么微软自己的软件例如outlook的联系人自动完成功能都做的非常好,但是提供给开发者的开发工具里面却完全是另外一个层次。。。


    da jia hao!
    • 已编辑 liubin 2012年1月5日 3:31
    2012年1月5日 3:26
  • 谢谢回复。不过其实textbox和combobox的autocomplete都是一样的,缺点是只能匹配开头的字符。例如有一个选项为“AAA88899”,那么只有你输入“A”的时候才会列出这个选项,如果你输入“88”等其他字符都不会出现这个选项。这种功能我想用户是难以接受的。。。

    的确如此,你看来要比较“讨巧”一点做法(以下代码当你在Combobx中输入任意字符,自动查询包含该字符的全部内容,注意区分大小写)。

    namespace WinFormCSharp
    {
        public partial class Form1 : Form
        {
            List<string> strings = null;

            public Form1()
            {
                InitializeComponent();
            }

            private void Form1_Load(object senderEventArgs e)
            {
                //预先对整个Combobox的内容进行备份
               strings = comboBox1.Items.Cast<string>().ToList();

            }


            private void comboBox1_KeyUp(object senderKeyEventArgs e)
            {
                if (comboBox1.Text != "")
                {
                    comboBox1.Items.Clear();
                    comboBox1.AutoCompleteCustomSource.Clear();

                    var ss = strings.FindAll(s => s.IndexOf(comboBox1.Text>= 0).ToArray();

                    if (ss != null && ss.Length != 0)
                    {
                        comboBox1.Text = "";
                        comboBox1.SelectedText = "";
                        comboBox1.Items.AddRange(ss.ToArray());
                        comboBox1.SelectedIndex = 0;    //默认选择第一项
                        e.Handled = true;
                    }
                }
            }
           
        }
    }

    测试环境:在Combobox的Items输入:

    AA88034

    AA

    AAB

    B

    C

    运行程序:

    1)在Combox中输入8(下拉框出现第一个)

    2)在Combox中输入A(下拉框出现三个,默认第一个选项)


       QQ我:讨论(Talk)
    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处
    2012年1月5日 5:37
    版主
  • 谢谢回复。不过其实textbox和combobox的autocomplete都是一样的,缺点是只能匹配开头的字符。例如有一个选项为“AAA88899”,那么只有你输入“A”的时候才会列出这个选项,如果你输入“88”等其他字符都不会出现这个选项。这种功能我想用户是难以接受的。。。

    为什么微软自己的软件例如outlook的联系人自动完成功能都做的非常好,但是提供给开发者的开发工具里面却完全是另外一个层次。。。


    da jia hao!


    可能涉及到商业用途和利益方面,不可能把每一个功能都向外公开或者告诉这个怎么实现的。苦衷只有我们这些程序员懂得。

    当然微软已经为我们贡献了很多了。我们只能说现在可能某些code不能实现您所期待的功能,可能在将来的版本上实现。

     

    另外我看那些像百度,Google,bing搜索栏,写的还不是一样的只显示以输入的字符开头的条目。我想你可能需要的是模糊查询类似的功能,这种似乎用原始的想法会好点: textbox输入,listbox 显示相关的条目,选择一条显示在textbox上。

     edit:或者参考一下Wei_Dong的做法(刚看到。。)


    Best Regards,
    Rocky Yue[MSFT]
    MSDN Community Support | Feedback to us

    2012年1月5日 5:39
    版主
  • 我想到了另外一个方法,就是在textbox里面处理OnMouseWheel事件,然后直接将事件转给listBox去处理,相当于人工发送一个mousewheel消息给listbox,不知道这样是否可行?

    如何实现给listbox发送mousewheel的消息呢?


    da jia hao!
    2012年1月5日 6:11
  • 如何实现给listbox发送mousewheel的消息呢?

    C#好像不能直接这样处理……你可以先尝试看看我的第三个回复。
       QQ我:讨论(Talk)
    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处
    2012年1月5日 7:07
    版主
  • hi,我想我可能找到了解决的方法,看看下面的代码:

     

            textBox1.MouseWheel += new MouseEventHandler(textBox1_MouseWheel);

            void textBox1_MouseWheel(object sender, MouseEventArgs e)
            {
                if (e.Delta > 0)
                    SendMessage(listBox1.Handle, 0x0100, 0x26, 0);
                else
                    SendMessage(listBox1.Handle, 0x0100, 0x28, 0);
            }

     

    原理就是在textbox里面的时候,处理mousewheel事件,然后向listbox发送WM_KEYDOWN消息,这样就行了!测试有效果!

    不过呢,效果始终比不上web上大量可见的自动完成效果。。真的有点遗憾。。。

     

    另外,向listbox发送WM_MOUSEWHEEL事件没效果,可能这个消息要求一定有输入焦点才可以吧!

     


    da jia hao!
    2012年1月5日 13:14