0

To simulate a modal dialog in WPF, I display a Window and call: Mouse.Capture(dialogBoxArea, CaptureMode.SubTree);

The call returns false.

Mouse.Captured is null. dialogBoxArea.Visibility is Visibility.Visible. dialogBoxArea.IsEnabled is true.

If the line is called again a second time, it returns true and correctly captures the mouse.

What condition might I be missing that is preventing the capture from working?

Edit

Here's what I've tried so far.

        if (Mouse.Captured != null)
        {
            // Not called, so presumably, nothing has already captured the mouse
            MessageBox.Show("already captured");
        }

        if (dialogBoxArea.Visibility != Visibility.Visible)
        {
            // Not called
            MessageBox.Show("not visible");
        }

        if (!dialogBoxArea.IsEnabled)
        {
            // Not called
            MessageBox.Show("not enabled");
        }

        // According to documentation, this should release mouse capture from anything that holds it
        Mouse.Capture(null);

        // Attempt to capture the mouse
        if (!Mouse.Capture(dialogBox, CaptureMode.SubTree))
        {
            // This is called
            Mouse.Capture(null);
            Mouse.Capture(dialogBox, CaptureMode.SubTree);
        }
Robert Gowland
  • 7,677
  • 6
  • 40
  • 58
  • Possibly the mouse is already captured by something else. How are you calling it? – 500 - Internal Server Error May 17 '13 at 20:09
  • You could install the NET Source code and then trace into the Mouse.Capture. http://weblogs.asp.net/rajbk/archive/2010/04/21/setting-up-visual-studio-2010-to-step-into-microsoft-net-source-code.aspx .... Or look at the source code and visually check it .... or use NET Reflector to decompile the IL and get a good approximation..... Here's the Capture function ... http://www.orbifold.net/default/uielementisvisible-returns-false/ ... maybe its something to do with the mouseinputProvider – Colin Smith May 17 '13 at 21:04
  • @500-InternalServerError, I've added the code that I've tried so far. It leads me to believe that nothing else has captured the mouse. – Robert Gowland May 21 '13 at 13:57
  • This looks like something you likely never want to do in WPF. Are you sure you approach the underlying problem correctly? What is the usecase? – Johannes May 21 '13 at 13:57
  • @Johannes, The requirement are: 1) show a modal dialog such that within the application only the dialog buttons may be respond to user input 2) the dialog may not be a windows dialog box 3) the dialog may not block other applications. I'm not sure whether I've approached the problem correctly, but the only other method seem to be placing a nearly invisible rectangle the size of the screen behind the dialog box which seemed less clean that capturing the mouse. This is a problem we'll run into in other ways, so I'm keep on solving it correctly once and for all. – Robert Gowland May 21 '13 at 14:06
  • @RobertGowland If i understand you it can not be a window and should be a subdivision of your original window. This sould like you actually want to load a different viewmodel as part of your main viewmodel. This is completely supported on its own - the only meaningful downside could be that you can not create a generic viewmodel for different datamodels. I take a look into my personal library, i wrote the code somewhere in a demoproject. – Johannes May 21 '13 at 14:13
  • @colinsmith, Thanks for the link to tracing into .NET source code. I didn't end up having to go that far, but it will be a handy tool for the future. – Robert Gowland May 23 '13 at 18:39

1 Answers1

1

As a first iteration i would talk to your client.

The following opens a dialog option window that is always on top of the original window and blocks calls to it, but does not hinder the overall execution at all. If your customer sees the behaviour he may be happy with that.

namespace StackoverflowExample
{
  public partial class MainWindow : Window
  {
    public MainWindow()
    {
      InitializeComponent();
    }
    void NewWindowAsDialog(object sender, RoutedEventArgs e)
    {
      Window myOwnedDialog = new Window();
      myOwnedDialog.Owner = this;
      myOwnedDialog.ShowDialog();
    }
  }
}

I will post another option later here that will illustrate how to load a window into a subdivision (grid etc.) of your xaml. You could filter all other calls based on the content that is loaded into that division rather then filtering the mouscall. Your filtering could run into the problem of the logical vs the viewtree - you only ever want to look at the trees if you create your own templates from scratch.

Johannes
  • 6,490
  • 10
  • 59
  • 108