How to align a WPF window to a child of a second window?

Will Pittenger 306 Reputation points
2024-08-08T03:07:52.1866667+00:00

So I've been trying to get a System.Windows.Window to be aligned with a control in a second Window. In the image, the magnifying glass is the control I want to align to. There's padding around the icon. The dark gray box with the +- buttons is the Window. I want it to appear like the left side of that image. But I commonly get what's on the right—if the gray window even appears. I know the window with the +- buttons is open as it's modal and top level. But I can't see it. Below is the code I use to position it.

The gray window has its WindowsStartupLocation set to Manual. Among the things I tried include setting only the Left or Top properties. Setting only Left gives me something resembling what I see in the right pane. If I set Top with or without setting Left, the gray window never appears.


				System.Windows.Point ptWhere = ctrlOpenedBy.PointToScreen(new System.Windows.Point(0, 0));

				Left = ptWhere.X;

				Top = ptWhere.Y - ActualHeight;

So what am I doing wrong?
User's image

Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,762 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,858 questions
XAML
XAML
A language based on Extensible Markup Language (XML) that enables developers to specify a hierarchy of objects with a set of properties and logic.
805 questions
Windows 11
Windows 11
A Microsoft operating system designed for productivity, creativity, and ease of use.
9,478 questions
0 comments No comments
{count} votes

Accepted answer
  1. Hui Liu-MSFT 48,506 Reputation points Microsoft Vendor
    2024-08-08T07:21:52.9466667+00:00

    Hi,@Will Pittenger . Welcome to Microsoft Q&A. To position GrayWindow so that its left side aligns with the left side of the ctrlOpenedBy image and its bottom edge aligns with the top edge of the ctrlOpenedBy image, you need to adjust the Left and Top properties of GrayWindow based on the image's position and dimensions. Here is my test sample, you could check it out.

    
    <Window x:Class="WindowInWindow.GrayWindow"
    
           ...  
           WindowStyle="None"  Background="Gray" Topmost="False"    Title="GrayWindow" Height="100" Width="400">
        <StackPanel Orientation="Horizontal">
            <Button x:Name="minmize" Width="30" Height="50" Content="-"/>
            <Image Source="OIP.jpg" Width="80" Height="50"/>
            <Button x:Name="addbutton" Width="30" Height="50" Content="+"/>
        </StackPanel>
    </Window>
    
    
    <Window x:Class="WindowInWindow.MainWindow"
       ...
       Loaded="Window_Loaded"  Title="MainWindow" Height="450" Width="800">
    <Grid Name="grid" Background="Pink">
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Bottom">
            <Image x:Name="ctrlOpenedBy" Source="th.jpg" Width="40" Height="40"  />
            <TextBlock Text="search" Width="100" Height="40" FontSize="22" TextAlignment="Center" Background="AliceBlue"/>
        </StackPanel>
    </Grid>
    </Window>
    
    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        ShowGrayWindow();
    }
    private void ShowGrayWindow()
    {
        GrayWindow grayWindow = new GrayWindow();
        grayWindow.WindowStartupLocation = WindowStartupLocation.Manual;
        grayWindow.Owner = this;
        grayWindow.Loaded += (s, e) =>
        {
            Point imagePosition = ctrlOpenedBy.PointToScreen(new Point(0, 0));
            grayWindow.Left = imagePosition.X;
            grayWindow.Top = imagePosition.Y - grayWindow.ActualHeight ;
    
        };
        grayWindow.Show();
    }
    
    
    

    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    1 person found this answer helpful.

1 additional answer

Sort by: Most helpful
  1. Will Pittenger 306 Reputation points
    2024-08-09T14:41:07.4733333+00:00

    Ah, System.Windows.DpiScale and `System.Windows.Media.VisualTreeHelper`` to the rescue. What was suggested above almost worked. However, I had to divide by the scale—not multiple it in.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.