Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The proposed solution uses a special shield canvas to block input to other controls. This is fine, but I am trying implement a generic control and cannot depend on the existence of such a shield canvas. The binding of the MouseLeftButtonDown event on the root visual didn't work for me either, because existing buttons on my canvas would still fire their own click event and not the MouseLeftButtonDown on the root visual. I found the solution in this ice article: <strong>Popup.StaysOpen in Silverlight</strong> from Kent Boograart. The main methods for this question are:</p> <pre><code> private void OnPopupOpened(object sender, EventArgs e) { var popupAncestor = FindHighestAncestor(this.popup); if (popupAncestor == null) { return; } popupAncestor.AddHandler(Windows.Popup.MouseLeftButtonDownEvent, (MouseButtonEventHandler)OnMouseLeftButtonDown, true); } private void OnPopupClosed(object sender, EventArgs e) { var popupAncestor = FindHighestAncestor(this.popup); if (popupAncestor == null) { return; } popupAncestor.RemoveHandler(Windows.Popup.MouseLeftButtonDownEvent, (MouseButtonEventHandler)OnMouseLeftButtonDown); } private void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { // in lieu of DependencyObject.SetCurrentValue, this is the easiest way to enact a change on the value of the Popup's IsOpen // property without overwriting any binding that may exist on it var storyboard = new Storyboard() { Duration = TimeSpan.Zero }; var objectAnimation = new ObjectAnimationUsingKeyFrames() { Duration = TimeSpan.Zero }; objectAnimation.KeyFrames.Add(new DiscreteObjectKeyFrame() { KeyTime = KeyTime.FromTimeSpan(TimeSpan.Zero), Value = false }); Storyboard.SetTarget(objectAnimation, this.popup); Storyboard.SetTargetProperty(objectAnimation, new PropertyPath("IsOpen")); storyboard.Children.Add(objectAnimation); storyboard.Begin(); } private static FrameworkElement FindHighestAncestor(Popup popup) { var ancestor = (FrameworkElement)popup; while (true) { var parent = VisualTreeHelper.GetParent(ancestor) as FrameworkElement; if (parent == null) { return ancestor; } ancestor = parent; } } </code></pre> <p>I'm still not sure, why this solution works for me and this not:</p> <pre><code> Application.Current.RootVisual.MouseLeftButtonDown += (s1, e1) =&gt; { this.PopUp.IsOpen = false; }; </code></pre> <p>It looks like the FindHighestAncestor method will just return the root visual? But then the difference must be the event handler? I guess the main difference is the last parameter of the AddHandler method which is true in the case:</p> <pre><code>AddHandler(Windows.Popup.MouseLeftButtonDownEvent, (MouseButtonEventHandler)OnMouseLeftButtonDown, true); </code></pre> <p>The MSDN docs say:</p> <blockquote> <p>handledEventsToo</p> <p>Type: <strong>System.Boolean</strong></p> <p>true to register the handler such that it is invoked even when the routed event is marked handled in its event data; false to register the handler with the default condition that it will not be invoked if the routed event is already marked handled. The default is false. Do not routinely ask to rehandle a routed event. For more information, see Remarks.</p> </blockquote>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload