WPF:如何设置由UserControl显示的对话框的所有者窗口?

我有一个WPF应用程序与这三种types的东西…

  • WindowMain
  • UserControlZack
  • WindowModal

UserControlZack1坐在我的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显示一个WindowModal dailog框…

部分公共类UserControlZack

    ...

     Private Sub SomeButton_Click(...)
         '实例化对话框并打开模态...
         Dim box As WindowModal = New WindowModal()
         box.Owner = ?????
         box.ShowDialog()
         '如果对话框被接受,用户input的过程数据...
        如果(box.DialogResult.GetValueOrDefault = True)那么
             _SomeVar = box.SomeVar
             ...
        万一
    结束小组

末class

如何将box.Owner设置为正确的Window,我正在运行的WindowMain实例?

我不能使用box.Owner = Me.Owner ,因为“'Owner'不是'ProjectName.UserControlZack'的成员。

我不能使用box.Owner = Me.Parent ,因为它返回一个Grid,而不是Window。

我不能使用box.Owner = WindowMain ,因为“'WindowMain'是一个types,不能用作expression式。

尝试使用

 .Owner = Window.GetWindow(this) 

为了获得顶层窗口的控制权,假设有一个:

 (Window)PresentationSource.FromVisual(this).RootVisual 

要获得主窗口:

 Application.Current.MainWindow 
 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(); 

更新尝试和帮助格雷格从评论。 该命令适用于主窗口菜单,用户控件中的button和用户控件中的上下文菜单。

我会用命令来做。 所以有一个Commands.cs类就像这样:

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

在你的主窗口中注册这些:(你不需要canshow默认是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; } 

这是我的主窗口的xaml:

 <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> 

这是我的用户控件的xaml(默认代码仅在后面)

 <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> 

你可以进一步,并在一个控制器类中处理命令,使它更多的MVC。

通过我的XAML一路爬行,我得到了它的工作…

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

但是这似乎很不雅观。 有没有更好的办法?

把窗口的名字改成WindowMain1或者什么东西,然后把所有者设置成那个呢?