locked
Positioning a window wpf RRS feed

  • Question

  • I've tried every suggestion and none seem to work.  I have a modal dialog I want to be able to position at a specific point in a control, a Canvas or DockPanel.  Converting the pnt(0,0) to screen coordinates with the control produces the wrong position when I set the WindowStartupLocation.  I might be able to implement the modal window as a floating popup like a tool tip, if there were someway for the "floating" control to receive the keyboard focus.  In any case , dewspite all the suggestions converting the point to screen coordinates and then displaying the the window at that point does not work!
    Wednesday, August 27, 2014 10:48 PM

Answers

  • Popup:

            private void Popup1_Opened(object sender, EventArgs e)
            {
                Popup p = (Popup)sender;
                StackPanel sp = (StackPanel)p.Child;
                TextBox tb = (TextBox)sp.FindName("Text1");
                tb.Focus();
            }

    The above code handles a popup open event, finds a textbox in there inside a stackpanel and sets focus.

    .

    PS

    IMO

    Popup offers a significant advantage over a modal window in that it is far easier to place it relative to some control in the parent window.

    You can disable the parent window whilst it's open if you wanted modal style operation.


    Hope that helps
    Please don't forget to up vote answers you like or which help you and mark one(s) which answer your question.


    Thursday, August 28, 2014 7:46 AM

All replies

  • The below works fine for me:

    XAML:

    <Window x:Class="ForumWpfApp.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow"
            Height="400"
            Width="400">
     <Grid>
      <Grid.RowDefinitions>
       <RowDefinition Height="*" />
       <RowDefinition Height="*" />
       <RowDefinition Height="*" />
      </Grid.RowDefinitions>
      
      <Grid.ColumnDefinitions>
       <ColumnDefinition Width="*" />
       <ColumnDefinition Width="*" />
       <ColumnDefinition Width="*" />
      </Grid.ColumnDefinitions>
    
      <Button Grid.Column="0"
              Grid.Row="0"
              Content="Click Me"
              Click="Button_Click"
              Width="75"
              HorizontalAlignment="Center"
              VerticalAlignment="Center" />
    
      <Button Grid.Column="1"
              Grid.Row="0"
              Content="Click Me"
              Click="Button_Click"
              Width="75"
              HorizontalAlignment="Center"
              VerticalAlignment="Center" />
    
      <Button Grid.Column="2"
              Grid.Row="0"
              Content="Click Me"
              Click="Button_Click"
              Width="75"
              HorizontalAlignment="Center"
              VerticalAlignment="Center" />
    
      <Button Grid.Column="0"
              Grid.Row="1"
              Content="Click Me"
              Click="Button_Click"
              Width="75"
              HorizontalAlignment="Center"
              VerticalAlignment="Center" />
    
      <Button Grid.Column="1"
              Grid.Row="1"
              Content="Click Me"
              Click="Button_Click"
              Width="75"
              HorizontalAlignment="Center"
              VerticalAlignment="Center" />
    
      <Button Grid.Column="2"
              Grid.Row="1"
              Content="Click Me"
              Click="Button_Click"
              Width="75"
              HorizontalAlignment="Center"
              VerticalAlignment="Center" />
    
      <Button Grid.Column="0"
              Grid.Row="2"
              Content="Click Me"
              Click="Button_Click"
              Width="75"
              HorizontalAlignment="Center"
              VerticalAlignment="Center" />
    
      <Button Grid.Column="1"
              Grid.Row="2"
              Content="Click Me"
              Click="Button_Click"
              Width="75"
              HorizontalAlignment="Center"
              VerticalAlignment="Center" />
    
      <Button Grid.Column="2"
              Grid.Row="2"
              Content="Click Me"
              Click="Button_Click"
              Width="75"
              HorizontalAlignment="Center"
              VerticalAlignment="Center" />
    
     </Grid>
    
    
    </Window>
    

    Code behind:

      private void Button_Click(object sender, RoutedEventArgs e)
      {
       Button l_button = sender as Button;
       Point l_topLeft = l_button.PointToScreen(new Point(0,0));
    
       Window l_window = new Window();
       l_window.WindowStartupLocation = WindowStartupLocation.Manual;
       l_window.Top = l_topLeft.Y;
       l_window.Left = l_topLeft.X;
       l_window.Width = 100;
       l_window.Height = 100;
       l_window.ShowDialog();
      }
    

    What are your issues?


    It would be greatly appreciated if you would mark any helpful entries as helpful and if the entry answers your question, please mark it with the Answer link.

    Thursday, August 28, 2014 5:01 AM
  • Popup:

            private void Popup1_Opened(object sender, EventArgs e)
            {
                Popup p = (Popup)sender;
                StackPanel sp = (StackPanel)p.Child;
                TextBox tb = (TextBox)sp.FindName("Text1");
                tb.Focus();
            }

    The above code handles a popup open event, finds a textbox in there inside a stackpanel and sets focus.

    .

    PS

    IMO

    Popup offers a significant advantage over a modal window in that it is far easier to place it relative to some control in the parent window.

    You can disable the parent window whilst it's open if you wanted modal style operation.


    Hope that helps
    Please don't forget to up vote answers you like or which help you and mark one(s) which answer your question.


    Thursday, August 28, 2014 7:46 AM
  • The problem is not about positioning to an absolute screen location.  The problem is positioning the window relative to the other controls in my application.  I've found a simple way to do this with a Popup derived class, however, Popup's have some annoying characteristics like the z-order.
    Friday, August 29, 2014 11:49 AM
  • Yes, Popups seem to work.  They have the annoying characteristic of always being at the top of the z-order. Do you know a way to change this?
    Friday, August 29, 2014 11:51 AM
  • That's kind of the point of  a pop up.

    Use an adorner if you want to put something on top of the popup.

    You could give this a go:

    http://chriscavanagh.wordpress.com/2008/08/13/non-topmost-wpf-popup/

    I'd try changing the z-panel index first though.

    <object Panel.ZIndex="int" .../>
    http://msdn.microsoft.com/en-us/library/system.windows.controls.panel.zindex(v=vs.110).aspx


    Hope that helps
    Please don't forget to up vote answers you like or which help you and mark one(s) which answer your question.



    • Edited by Andy ONeill Friday, August 29, 2014 12:27 PM
    Friday, August 29, 2014 12:25 PM
  • The problem is not about positioning to an absolute screen location.  The problem is positioning the window relative to the other controls in my application.  I've found a simple way to do this with a Popup derived class, however, Popup's have some annoying characteristics like the z-order.
    The sample that I provided displays 9 buttons in varying positions and when each button is clicked, it opens up the "dialog" with the top left corner aligned with the top left corner of the button. Perhaps I am not understanding what you mean by relative?

    It would be greatly appreciated if you would mark any helpful entries as helpful and if the entry answers your question, please mark it with the Answer link.

    Friday, August 29, 2014 1:04 PM
  • " it opens up the "dialog" with the top left corner aligned with the top left corner of the button. Perhaps I am not understanding what you mean by relative?"

    No it doesn't

    I clicked the bottom left button


    Hope that helps
    Please don't forget to up vote answers you like or which help you and mark one(s) which answer your question.

    Friday, August 29, 2014 1:58 PM
  • That is odd....on my system, it opens up exactly where it is supposed to.

    It would be greatly appreciated if you would mark any helpful entries as helpful and if the entry answers your question, please mark it with the Answer link.

    Friday, August 29, 2014 2:04 PM
  • That's by coincidence mate.

    I was aware of the problem only because I've seen it before.

    Best way to position precisely is using a pop up.

    Perhaps I should say the simplest.

    You could probably do a load of calculations... but why bother when a popup can do the job easy.

    If you want a laugh.

    Try with two screens and make the right one your primary.

    See what happens.


    Hope that helps
    Please don't forget to up vote answers you like or which help you and mark one(s) which answer your question.

    Friday, August 29, 2014 6:45 PM
  • I think it is a little too consistent to be merely a coincidence.  I have tried multiple positions across two monitors and even changed the primary display to the right monitor and repeated.  In every instance, the window opened up exactly where I expected it to across all nine button.

    I would be interested in figuring out what causes the issue: a particular resolution, zoom, video card, operating system, .NET version, etc, but it is difficult for me to chase when mine just seems to work.


    It would be greatly appreciated if you would mark any helpful entries as helpful and if the entry answers your question, please mark it with the Answer link.

    Friday, August 29, 2014 7:05 PM
  • Visual studio 2013 on win 8.1 pro AMD 5800.

    No zoom or anything whatsoever unusual other than the fact I have 2 * 22 inch Benq monitors.

    The resolution is default.

    "The issue" isn't caused by my set up, the approach just doesn't work reliably.

    Due to the way wpf works out co-ordinates.


    Hope that helps
    Please don't forget to up vote answers you like or which help you and mark one(s) which answer your question.

    Saturday, August 30, 2014 7:36 AM
  • My research has shown, and I can replicate your issue, by changing the DPI setting for the monitor through the Display applet.  WPF presumes a 96 DPI setting and this appears to be what sets things all wonky.  My system was already set at 96 DPI and was the reason that I was getting consistent results.

    Replacing the button click method in my previous post with:

      private void Button_Click(object sender, RoutedEventArgs e)
      {
       Button l_button = sender as Button;
       Point l_topLeftDip = l_button.PointToScreen(new Point(0, 0));
       PresentationSource l_source = PresentationSource.FromVisual(l_button);
       Matrix l_matrix = l_source.CompositionTarget.TransformFromDevice;
       Point l_topLeft = new Point(l_matrix.M11 * l_topLeftDip.X, l_matrix.M22 * l_topLeftDip.Y);
    
       Window l_window = new Window();
       l_window.WindowStartupLocation = WindowStartupLocation.Manual;
       l_window.Top = l_topLeft.Y;
       l_window.Left = l_topLeft.X;
       l_window.Width = 100;
       l_window.Height = 100;
       l_window.ShowDialog();
      }
    

    should work at various DPI settings.  I agree that Microsoft should fix this in their APIs and that it does take a little extra work, but I am driven by the why.


    It would be greatly appreciated if you would mark any helpful entries as helpful and if the entry answers your question, please mark it with the Answer link.

    Saturday, August 30, 2014 1:51 PM
  • Yeah, the 96dpi thing is something  to do with picking a "better" number than 72dpi.

    Calculating co-ordinates seems much more like winforms to me.

    With my wpf hat on I don't expect to have to do any of that lark.

    I like simple.

    The no code approach appeals to me a lot more than working out some obscure calculation which might fail for some reason.

    Like when MS "fix" the issue?

    If it is really an issue.

    .

    The pop up is a way simpler solution.

    It "just works" with no messing about.

    It's often useful that it can be bound to the same datacontext.

    Like my hand built combo:

    http://gallery.technet.microsoft.com/WPF-Multi-Select-Combo-d4b02a34

    .

    I've never seen a situation where the pop up being on top was a problem.

    I don't really follow the OP on that one.

    .

    I should perhaps emphasise that my reasoning isn't influenced by one being "my" answer and another someone else's.

    I don't make recommendations just to win points.

    Well.

    Unless someone hacks me off by copying my answers.

    Then annoyance might make me a bit competitive.

    But that's not you.


    Hope that helps
    Please don't forget to up vote answers you like or which help you and mark one(s) which answer your question.

    Saturday, August 30, 2014 4:13 PM