wake-up-neo.com

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

我有一个WPF应用程序有这三种类型的东西......

  • 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()
'如果接受对话框,用户输入的过程数据... 
如果(box.DialogResult.GetValueOrDefault = True)那么
 _SomeVar = box.SomeVar 
 ... 
结束如果
 End Sub 
 
 End Class 

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

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

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

我不能使用box.Owner = WindowMain,因为“'WindowMain'是一个类型,不能用作表达式。”

54
Zack Peterson

尝试使用

.Owner = Window.GetWindow(this)
123
Martin Moser

要获得顶级窗口,您的控件就在,假设有一个:

(Window)PresentationSource.FromVisual(this).RootVisual

要获得主窗口:

Application.Current.MainWindow
39
Nir
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
JRL1283

更新以尝试和帮助Greg的评论。该命令适用于主窗口菜单,用户控件中的按钮和用户控件中的上下文菜单。

我会用命令来做。所以有一个类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。

5
Andrew Barrett

我通过我的XAML一路爬回来让它工作......

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

但这似乎相当不优雅。有没有更好的办法?

0
Zack Peterson

如何将窗口名称更改为WindowMain1或其他内容,并将所有者设置为?

0
Davy8