none
关于Popup 下拉框 点击其他地方自动关闭的问题 RRS feed

  • 问题

  • 我自己写一个Combox   想要点击控件  现实下拉的DropDown     点击其他任意地方(除过控件和Drop部分)  下拉收起

    1) 我监视控件点击    并对控件本身和DropDown部分 做点击测试 确定是否点击上

     

    void SearchTextBox_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)

            {

                // Retrieve the coordinate of the mouse position.

                Point pt = e.GetPosition(this);

     

                // Perform the hit test against a given portion of the visual object tree.

                HitTestResult htr1 = VisualTreeHelper.HitTest(this, pt);

     

                HitTestResult htr2 = this.DropDown_Popup.HitTest(e.GetPosition(this.DropDown_Popup));

     

                if (this.IsDropDown && this.DropDown_Popup.IsShow)

                {

                    if (htr1 != null || htr2 != null)

                    {

                        e.Handled = false;

                        return;

                    }

                    else

                    {

                        this.IsDropDown = false;

                    }

                }

                else

                {

                    this.IsDropDown = !this.IsDropDown;

                }

                e.Handled = false;

            }

     

    2) 当下拉现实后    所有鼠标消息 发送到 控件处理 

     

    public static void IsDropDownPorpertyChangeCallBack(DependencyObject sender, DependencyPropertyChangedEventArgs e)

            {

                SearchTextBox stb = sender as SearchTextBox;

                if ((bool)e.NewValue)

                {

                    stb.CaptureMouse();

                }

                else

                {

                    stb.ReleaseMouseCapture();

                }

            }

     

     

    3)杯具来了!!!!!!!!!!!!!!!     下拉部分 不响应鼠标事件了  按钮 什么的都对鼠标无视了

    求解      感谢感谢  感感谢·~~~~~

     

    • 已编辑 PUPPYWIN 2010年4月30日 4:07
    2010年4月29日 20:35

答案

  • 你好!

         他是这样处理的:

            private static void OnLostMouseCapture(object sender, MouseEventArgs e)
            {
                ComboBox comboBox = (ComboBox)sender;

                //
     

                if (Mouse.Captured != comboBox)
                {
                    if (e.OriginalSource == comboBox)
                    {
                        // If capture is null or it's not below the combobox, close.
                        // More workaround for task 22022 -- check if it's a descendant (following Logical links too)
                        if (Mouse.Captured == null || !MenuBase.IsDescendant(comboBox, Mouse.Captured as DependencyObject))
                        {
                            comboBox.Close();
                        }
                    }
                    else
                    {
                        if (MenuBase.IsDescendant(comboBox, e.OriginalSource as DependencyObject))
                        {
                            // Take capture if one of our children gave up capture (by closing their drop down)
                            if (comboBox.IsDropDownOpen && Mouse.Captured == null && MS.Win32.SafeNativeMethods.GetCapture() == IntPtr.Zero)
                            {
                                Mouse.Capture(comboBox, CaptureMode.SubTree);
                                e.Handled = true;
                            }
                        }
                        else
                        {
                            comboBox.Close();
                        }
                    }
                }
            }

    这就是他的处理方式,实际上上面代码就是ComboBox的源代码!这个方法应该是系统来调用的,里面有很多未公开的方法和属性,也就是说你自己无法写这样的方法来和系统交互!

    我建议你继承Combobox来实现自己的控件!


    周雪峰
    • 已标记为答案 PUPPYWIN 2010年5月4日 2:15
    2010年4月30日 8:32
    版主

全部回复

  • 你好!

       你的SearchTextBox捕获了鼠标,所以出现了这样的问题!

       不知道你到底想实现怎样的效果呢?

    默认情况下ComboBox点击其他地方,下拉框就会收起了啊!

     


    周雪峰
    2010年4月30日 1:59
    版主
  • 你好!

    这个不是Combox  是我自己写的一个控件   用来准备实现自动完成的功能

    所以IsOpen的触发时机和Combox 也不一样    但是其他都还好控制

    要实现的目标:

    下拉打开-----  当用户输入字符自动搜索对应选项在结果集返回的时候打开下拉框   或者用户手动点击搜索按钮

    下拉关闭----- 用户选择下拉某项改变SeletedItem的时候关闭   或者鼠标点击该界面其他位置(非该控件框 非下拉框)和窗体外位置时    下拉框关闭

     

    点击空白地方下拉收起,这点和Combox是相同的  我想实现这个功能  不知道微软的Combox是怎么实现的

    2010年4月30日 3:45
  • 你好!

         他是这样处理的:

            private static void OnLostMouseCapture(object sender, MouseEventArgs e)
            {
                ComboBox comboBox = (ComboBox)sender;

                //
     

                if (Mouse.Captured != comboBox)
                {
                    if (e.OriginalSource == comboBox)
                    {
                        // If capture is null or it's not below the combobox, close.
                        // More workaround for task 22022 -- check if it's a descendant (following Logical links too)
                        if (Mouse.Captured == null || !MenuBase.IsDescendant(comboBox, Mouse.Captured as DependencyObject))
                        {
                            comboBox.Close();
                        }
                    }
                    else
                    {
                        if (MenuBase.IsDescendant(comboBox, e.OriginalSource as DependencyObject))
                        {
                            // Take capture if one of our children gave up capture (by closing their drop down)
                            if (comboBox.IsDropDownOpen && Mouse.Captured == null && MS.Win32.SafeNativeMethods.GetCapture() == IntPtr.Zero)
                            {
                                Mouse.Capture(comboBox, CaptureMode.SubTree);
                                e.Handled = true;
                            }
                        }
                        else
                        {
                            comboBox.Close();
                        }
                    }
                }
            }

    这就是他的处理方式,实际上上面代码就是ComboBox的源代码!这个方法应该是系统来调用的,里面有很多未公开的方法和属性,也就是说你自己无法写这样的方法来和系统交互!

    我建议你继承Combobox来实现自己的控件!


    周雪峰
    • 已标记为答案 PUPPYWIN 2010年5月4日 2:15
    2010年4月30日 8:32
    版主