none
How to find the parent window of a Dialog?

    Question

  • How can you find the parent window that launched a child Dialog window?

    I understand that you can assign the Owner property when you're launching a child Dialog window, however my scenario goes a bit deeper than that.

    I have a custom control that inherits from Window.  I want to be able to set the Owner to the parent Window of my custom window control from WITHIN the custom window control.  The reason for this is because my custom window/dialog control is part of a control library and I want it to behave like a windows MessageBox ... so the owner property needs to be set.  However I don't want consumers of my custom window control to have to set the Owner property themselves if they don't want to - i just want the Owner property to default to whatever parent window effectively launched my custom dialog window.

    Is that possible?
    Friday, March 27, 2009 7:45 PM

Answers

  • What if you required a reference to the control opening your dialog in your dialog's constructor? Then you could do something like this:

        public partial class testDialog : Window
        {
            private testDialog()
            {
                InitializeComponent();
            }
            public testDialog(DependencyObject depObject):this()
            {
                Owner = Window.GetWindow(depObject);
            }
        }
    And in whatever code is used to open the dialog, they would just do something like this:

        private void Button_Click(object sender, RoutedEventArgs e)
            {
                testDialog td = new testDialog(sender as DependencyObject);
                td.Show();
            }


    • Marked as answer by Tao Liang Tuesday, March 31, 2009 2:16 AM
    Monday, March 30, 2009 6:29 PM

All replies

  • If you have some reference to an element in the parent window, you can call PresentationSource.FromVisual to get the PresentationSource of the window. Then query the RootVisual property of the PresentationSource, which should be the Window, which you can use as the value of your Owner property. Alternately, you can walk up the visual tree until you arrive at the Window.

    Ben
    This posting is provided "AS IS" with no warranties, and confers no rights.
    Friday, March 27, 2009 8:17 PM
  • I won't know anything about the parent window (or it's contents) ... so I tried walking the visual tree with no success.

    Any reason why this would return null?  (It's called from the constructor of my custom window control):

    UIElement element = VisualTreeHelper.GetParent(this) as UIElement; 

    I can't seem to walk the visual tree back to a parent window because the immediate parent of my custom window is null.
    Friday, March 27, 2009 11:48 PM
  • Your window control is always the root of the visual tree for the HWND it lives in. That is why its visual parent is null (there is no visual parent). That is also the reason why you need to know something about the parent window.

    Ben
    This posting is provided "AS IS" with no warranties, and confers no rights.
    Saturday, March 28, 2009 12:07 AM
  • Or you could add a custom “parent” member to the dialog window, then you can find the parent window easily.

    For example:

    Window1.xaml
    <Window x:Class="_temple.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="app" Width="400" Height="300" Background="White" >
        <StackPanel Width="300">
            <Button Click="Button_Click">Open Dialog Window</Button>
            <TextBox Name="txtInfo" Text="Parent Window Content"></TextBox>
        </StackPanel>
    </Window>
    

    Window1.xaml.cs
    using System.Windows;
    namespace _temple
    {
        public partial class Window1 : Window
        {
            public Window1()
            {
                InitializeComponent();
            }
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                DialogWindow w = new DialogWindow();
                w.parent = this;
                w.Show();
            }
        }
    }
    

    DialogWindow.xaml
    <Window x:Class="_temple.DialogWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Loaded="Window_Loaded"
        Title="DialogWindow" Height="300" Width="300">
        <Grid>
            <Label Name="lblInfo"></Label>
        </Grid>
    </Window>
    

    DialogWindow.xaml.cs
    using System.Windows;
    namespace _temple
    {
        public partial class DialogWindow : Window
        {
            public Window1 parent;
            public DialogWindow()
            {
                InitializeComponent();
            }
            private void Window_Loaded(object sender, RoutedEventArgs e)
            {
                if (parent != null)
                {
                    this.lblInfo.Content = "The info from parent: " + parent.txtInfo.Text.Trim();
                }
            }
        }
    }
    
    • Proposed as answer by Tao Liang Monday, March 30, 2009 6:41 AM
    • Unproposed as answer by Kofoed Monday, March 30, 2009 4:58 PM
    Monday, March 30, 2009 6:41 AM
  • Actually, in that case I don't think I'd need to create a new "Parent" property, I'd just set the Owner property.  The point is I'm not controlling the opening/launching of my custom dialog control.  That occurs in a different application that consumes my control library ... the control library contains the custom dialog.

    So it appears there's no real good way to do this.  bah!
    Monday, March 30, 2009 4:57 PM
  • What if you required a reference to the control opening your dialog in your dialog's constructor? Then you could do something like this:

        public partial class testDialog : Window
        {
            private testDialog()
            {
                InitializeComponent();
            }
            public testDialog(DependencyObject depObject):this()
            {
                Owner = Window.GetWindow(depObject);
            }
        }
    And in whatever code is used to open the dialog, they would just do something like this:

        private void Button_Click(object sender, RoutedEventArgs e)
            {
                testDialog td = new testDialog(sender as DependencyObject);
                td.Show();
            }


    • Marked as answer by Tao Liang Tuesday, March 31, 2009 2:16 AM
    Monday, March 30, 2009 6:29 PM
  • I like Joe's answer.

    I recently did a similar thing where I had a Ctor for the dialog that required I pass in a Dependency object.  Then I was able to get at parent dialog information via that object.

    Hope this helps.

    -ja

    Monday, March 30, 2009 6:37 PM