Освобождение от захвата мыши и пропуск щелчка мыши

У меня есть элемент управления, похожий на всплывающее окно или меню. Я хочу отображать его, и когда пользователь щелкает мышью за пределами поля, он скрыть себя. Я использовал Mouse.Capture (this, CaptureMode. SubTree), а также повторно получил захват таким же образом, как Menu / Popup в OnLostMouseCapture.

Когда пользователь щелкает мышью за пределами элемента управления, я освобождаю захват мыши в OnPreviewMouseDown. Я не устанавливаю для e.Handled значение true. Щелчок мыши приведет к другим элементам управления в основном интерфейсе пользователя, но не к кнопке закрытия (красный крестик) окна. Для закрытия приложения требуется 2 щелчка мышью.

Есть ли способ указать WPF перезапустить щелчок мыши или отправить событие повторного щелчка мыши?

Вот мой код. Обратите внимание, я переименовал его в MainMenuControl - я не создаю меню, поэтому Menu / MenuItem и Popup не являются параметрами.

public class MainMenuControl : Control
    {
        static MainMenuControl()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(MainMenuControl), new FrameworkPropertyMetadata(typeof(MainMenuControl)));
        }

        public MainMenuControl()
        {
            this.Loaded += new RoutedEventHandler(MainMenuControl_Loaded);

            Mouse.AddPreviewMouseDownOutsideCapturedElementHandler(this, OnPreviewMouseDownOutsideCapturedElementHandler);
        }

        void MainMenuControl_Loaded(object sender, RoutedEventArgs e)
        {
            this.IsVisibleChanged += new DependencyPropertyChangedEventHandler(MainMenuControl_IsVisibleChanged);
        }

        void MainMenuControl_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            if (this.IsVisible)
            {
                Mouse.Capture(this, CaptureMode.SubTree);
                Debug.WriteLine("Mouse.Capture");
            }
        }

        // I was doing this in OnPreviewMouseDown, but changing to this didn't have any effect
        private void OnPreviewMouseDownOutsideCapturedElementHandler(object sender, MouseButtonEventArgs e)
        {
            Debug.WriteLine("OnPreviewMouseDownOutsideCapturedElementHandler");

            if (!this.IsMouseInBounds())
            {
                if (Mouse.Captured == this)
                {
                    Mouse.Capture(this, CaptureMode.None);
                    Debug.WriteLine("Mouse.Capture released");
                }
                Debug.WriteLine("Close Menu");
            }
        }

        protected override void OnLostMouseCapture(MouseEventArgs e)
        {
            base.OnLostMouseCapture(e);

            Debug.WriteLine("OnLostMouseCapture");

            MainMenuControl reference = e.Source as MainMenuControl;
            if (Mouse.Captured != reference)
            {
                if (e.OriginalSource == reference)
                {
                    if ((Mouse.Captured == null) || (!reference.IsAncestorOf(Mouse.Captured as DependencyObject)))
                    {
                        //TODO: Close
                        Debug.WriteLine("Close Menu");
                    }
                }
                // if a child caused use to lose the capture, then recapture.
                else if (reference.IsAncestorOf(e.OriginalSource as DependencyObject))
                {
                    if (Mouse.Captured == null)
                    {
                        Mouse.Capture(reference, CaptureMode.SubTree);
                        Debug.WriteLine("Mouse.Capture");
                        e.Handled = true;
                    }
                }
                else
                {
                    //TODO: Close
                    Debug.WriteLine("Close Menu");
                }
            }

        }

        private bool IsMouseInBounds()
        {
            Point point = Mouse.GetPosition(this);
            Rect bounds = new Rect(0, 0, this.Width, this.Height);

            return bounds.Contains(point);
        }

    }
10
задан Geoff Cox 22 April 2011 в 03:41
поделиться