WPF: How to set the owner window of the dialog shown by UserControl?

I have a WPF application with these three types of things ...

  • Windowmain
  • UserControlZack
  • Windowmodal

UserControlZack1 is on my WindowMain ...

<Window x:Class="WindowMain" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:ProjectName" ... Name="WindowMain"> <Grid> ... <local:UserControlZack x:Name="UserControlZack1" ... /> ... </Grid> </Window> 

UserControlZack1 displays a window window WindowModal ...

 Partial Public Class UserControlZack

    ...

     Private Sub SomeButton_Click (...)
         'instantiate the dialog box and open modally ...
         Dim box As WindowModal = New WindowModal ()
         box.Owner = ?????
         box.ShowDialog ()
         'process data entered by user if dialog box is accepted ...
         If (box.DialogResult.GetValueOrDefault = True) Then
             _SomeVar = box.SomeVar
             ...
         End if
     End sub

 End class

How to install box.Owner in the right window, my executable instance of WindowMain?

I cannot use box.Owner = Me.Owner because Owner is not a member of ProjectName.UserControlZack.

I cannot use box.Owner = Me.Parent because it returns a Grid, not a Window.

I cannot use box.Owner = WindowMain because "WindowMain" is a type and cannot be used as an expression.

+50
wpf dialog user-controls
Mar 03 '09 at 17:37
source share
6 answers

Try using

 .Owner = Window.GetWindow(this) 
+111
Mar 04 '09 at 8:11
source share

To get the top-level window your control is in, if any:

 (Window)PresentationSource.FromVisual(this).RootVisual 

To get the main window:

 Application.Current.MainWindow 
+36
Mar 04 '09 at 8:08
source share
 MyWpfDialog dialog = new MyWpfDialog(); //remember, this is WinForms UserControl and its Handle property is //actually IntPtr containing Win32 HWND. new System.Windows.Interop.WindowInteropHelper(dialog).Owner = this.Handle; dialog.ShowDialog(); 
+8
03 Oct 2018-11-11T00:
source share

Update to try and help Greg in the comments. The command works in the Windows main menu, in the user control and in the context menu of the user control.

I would do it with commands. So the Commands.cs class has something like:

 public static class Commands { public static RoutedUICommand TestShowDialogCommand = new RoutedUICommand("Test command", "TestShowDialog", typeof(Commands)); } 

Register them in your main window: (you do not need the default canshow line to be true)

  public Window1() { InitializeComponent(); CommandManager.RegisterClassCommandBinding(typeof(System.Windows.Controls.Control), new CommandBinding(Commands.TestShowDialogCommand, ShowDialogCommand, CanShowDialogCommand)); } private void ShowDialogCommand(object sender, ExecutedRoutedEventArgs e) { var box = new Window(); box.Owner = this; box.ShowDialog(); } private void CanShowDialogCommand(object sender, CanExecuteRoutedEventArgs e) { e.CanExecute = true; } 

This is my xaml for the main window:

 <Window x:Class="WpfApplication1.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:WpfApplication1="clr-namespace:WpfApplication1" Title="Window1" Height="300" Width="322"> <Grid> <StackPanel> <Menu> <MenuItem Header="Test"> <MenuItem Header="ShowDialog" Command="{x:Static WpfApplication1:Commands.TestShowDialogCommand}"/> </MenuItem> </Menu> <WpfApplication1:BazUserControl /> </StackPanel> </Grid> </Window> 

This is xaml for my user control (default only)

 <UserControl x:Class="WpfApplication1.BazUserControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:WpfApplication1="clr-namespace:WpfApplication1" Height="300" Width="300"> <Grid> <StackPanel> <Button Command="{x:Static WpfApplication1:Commands.TestShowDialogCommand}" Content="ClickMe" ></Button> <TextBox> <TextBox.ContextMenu> <ContextMenu> <MenuItem Header="ShowDialog" Command="{x:Static WpfApplication1:Commands.TestShowDialogCommand}" /> </ContextMenu> </TextBox.ContextMenu> </TextBox> </StackPanel> </Grid> </UserControl> 

You can do this a little further and process the command in the controller class instead and make the bit bigger than MVC.

+5
Mar 03 '09 at 17:51
source share

I got it for work by fully scanning my XAML ...

 box.Owner = DirectCast (DirectCast (DirectCast (Me.Parent, Grid) .Parent, Grid) .Parent, Window)

But it seems completely inelegant. Is there a better way?

0
Mar 03 '09 at 17:44
source share

How about changing the window name to WindowMain1 or something else and assigning it to this owner?

0
Mar 03 '09 at 17:47
source share



All Articles