.net WPF:如何设置 UserControl 显示的对话框的所有者窗口?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/607370/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WPF: How do I set the Owner Window of a Dialog shown by a UserControl?
提问by Zack Peterson
I've got a WPF application with these three types of things...
我有一个包含这三种类型的东西的 WPF 应用程序......
- WindowMain
- UserControlZack
- WindowModal
- 主窗口
- 用户控件
- 窗口模态
UserControlZack1 sits on my WindowMain...
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 displays a WindowModal dailog box...
UserControlZack1 显示一个 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 do I set box.Owner to the correct Window, my running instance of WindowMain?
如何将 box.Owner 设置为正确的 Window,即我正在运行的 WindowMain 实例?
I cannot use box.Owner = Me.Owner, because "'Owner' is not a member of 'ProjectName.UserControlZack'."
我不能使用box.Owner = Me.Owner,因为“'Owner' 不是'ProjectName.UserControlZack' 的成员。”
I cannot use box.Owner = Me.Parent, because that returns a Grid, not the Window.
我不能使用box.Owner = Me.Parent,因为它返回一个网格,而不是窗口。
I cannot use box.Owner = WindowMain, because "'WindowMain' is a type and cannot be used as an expression."
我不能使用box.Owner = WindowMain,因为“'WindowMain' 是一种类型,不能用作表达式。”
回答by Martin Moser
Try to use
尝试使用
.Owner = Window.GetWindow(this)
回答by Nir
To get the top level window your control is in, assuming there is one:
要获得您的控件所在的顶级窗口,假设有一个:
(Window)PresentationSource.FromVisual(this).RootVisual
To get the main window:
获取主窗口:
Application.Current.MainWindow
回答by JRL1283
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();
回答by Andrew Barrett
Updating to try and help Greg from the comments. The command works in the main windows menu, the button in the user control and the context menu in the user control.
更新以尝试从评论中帮助 Greg。该命令在主窗口菜单、用户控件中的按钮和用户控件中的上下文菜单中起作用。
I'd do it with commands. So have a class Commands.cs something like:
我会用命令来做。所以有一个类 Commands.cs 类似于:
public static class Commands
{
public static RoutedUICommand TestShowDialogCommand = new RoutedUICommand("Test command", "TestShowDialog", typeof(Commands));
}
Register these in your main window: (you don't need the canshow it defaults to true)
在您的主窗口中注册这些:(您不需要 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;
}
This is my xaml for the main window:
这是我的主窗口的 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>
This is the xaml for my user control (default code behind only)
这是我的用户控件的 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>
You could take it a bit further and handle the command in a controller class instead and make it that bit more MVC.
您可以更进一步,并在控制器类中处理命令,并使其更像 MVC。
回答by Zack Peterson
I got it to work by crawling all the way back up through my XAML...
我通过一直爬回我的 XAML 来让它工作......
box.Owner = DirectCast(DirectCast(DirectCast(Me.Parent, Grid).Parent, Grid).Parent, Window)
But this seems quite inelegant. Is there a better way?
但这似乎很不雅观。有没有更好的办法?
回答by Davy8
What about changing the name of the window to WindowMain1 or something, and setting the owner to that?
将窗口的名称更改为 WindowMain1 或其他名称,并将所有者设置为该名称怎么样?

