如何让网格捕获鼠标,但仍然允许孩子处理单击事件

时间:2018-10-31 01:26:47

标签: c# wpf grid children mousecapture

如果标题令人困惑,请提前抱歉。这是情况。我有一个名为SmtpClient client = new SmtpClient("smtp.live.com", 587); client.EnableSsl = true; client.DeliveryMethod = SmtpDeliveryMethod.Network; client.UseDefaultCredentials = false; client.Credentials = new NetworkCredential("xxxxx@hotmail.com", "******"); MailMessage msgobj = new MailMessage(); msgobj.To.Add(obj.ToEmail); msgobj.From = new MailAddress("xxxxx@hotmail.com"); msgobj.Body = obj.EMailBody; msgobj.Subject = obj.EmailSubject; msgobj.CC.Add(obj.EmailCC); msgobj.Bcc.Add(obj.EmailBCC); if (obj.imageFile != null && obj.imageFile.ContentLength > 0) { msgobj.Attachments.Add(new Attachment(obj.imageFile.InputStream, obj.imageFile.FileName)); } client.Send(msgobj); 的网格。此网格内有一系列grdFilters(每行一个)。通常,此网格是隐藏的。但是我希望它在出现提示时(单击按钮时)显示,并在用户单击网格以外的其他位置时显示。为了处理外部控制鼠标单击,我首先尝试这样捕获鼠标:

CheckBoxes

问题在于,虽然“筛选器”网格捕获了鼠标,但是无法单击任何网格子级(复选框)。我真的很想找到一种方法来检测何时在网格外部单击鼠标,同时仍然允许网格的子代接受鼠标按下事件。在此先感谢您的任何帮助。

根据请求,这里是我的一些Xaml:

    AddHandler(Mouse.PreviewMouseDownOutsideCapturedElementEvent, new MouseButtonEventHandler(HandleClickOutsideOfControl));

    private void HandleClickOutsideOfControl(object sender, MouseButtonEventArgs e)
    {
        if (this.filters) //Check if the Filters grid is visible
        {
            ShowHideMenu("sbHideFilters", grdFilters); //Method that hides the grid
            Mouse.Capture(null); //Release the mouse
        }
    }

    private void btnFilters_Click(object sender, RoutedEventArgs e)
    {
        if (!this.filters) //Check if the filters grid is shown
        {
            ShowHideMenu("sbShowFilters", grdFilters); //Method that reveals the grid
            Mouse.Capture(grdFilters); //Capture the mouse
        }
    }

我唯一遗漏的是资源字典和页面定义本身。

1 个答案:

答案 0 :(得分:1)

我认为Mouse.CapturePreviewMouseDownOutsideCapturedElementEvent对于您想要的内容来说太具体了。

我宁愿使用hitResultsList,它可以在许多不同的情况下使用:

我对AddHandler进行了一些修改

AddHandler(Mouse.PreviewMouseDownEvent, new MouseButtonEventHandler(HandleMouseDown));

然后我添加了VisualTreeHelper.HitTest逻辑

    //List to store all the elements under the cursor
    private List<DependencyObject> hitResultsList = new List<DependencyObject>();

    private void HandleMouseDown(object sender, MouseButtonEventArgs e)
    {

        Point pt = e.GetPosition((UIElement)sender);
        hitResultsList.Clear();

        //Retrieving all the elements under the cursor
        VisualTreeHelper.HitTest(this, null,
            new HitTestResultCallback(MyHitTestResult),
            new PointHitTestParameters(pt));

        //Testing if the grdFilters is under the cursor
        if (!hitResultsList.Contains(this.grdFilters) && grdFilters.Visibility == System.Windows.Visibility.Visible)
        {
            grdFilters.Visibility = System.Windows.Visibility.Hidden;
        }
    }

    //Necessary callback function
    private HitTestResultBehavior MyHitTestResult(HitTestResult result)
    {
        hitResultsList.Add(result.VisualHit);
        return HitTestResultBehavior.Continue;
    }

这样,您还可以从btnFilters_Click中删除Mouse.Capture调用:

    private void btnFilters_Click(object sender, RoutedEventArgs e)
    {
        if (grdFilters.Visibility != System.Windows.Visibility.Visible)
            grdFilters.Visibility = System.Windows.Visibility.Visible; }
    }