developer tip

WPF : UserControl에서 표시하는 대화 상자의 소유자 창을 어떻게 설정합니까?

copycodes 2021. 1. 9. 10:12
반응형

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

   ...

    비공개 서브 SomeButton_Click (...)
        '대화 상자를 인스턴스화하고 모달로 엽니 다 ...
        Dim box As WindowModal = New WindowModal ()
        box.Owner = ?????
        box.ShowDialog ()
        '대화 상자가 수락되면 사용자가 입력 한 데이터 처리 ...
        If (box.DialogResult.GetValueOrDefault = True) 그런 다음
            _SomeVar = 상자 .SomeVar
            ...
        End If
    End Sub

수업 종료

box.Owner를 올바른 Window, 실행중인 WindowMain 인스턴스로 설정하려면 어떻게해야합니까?

box.Owner = Me.Owner" 'Owner'는 'ProjectName.UserControlZack'의 구성원이 아니기 때문에 사용할 수 없습니다 ."

box.Owner = Me.ParentWindow가 아닌 ​​Grid를 반환하기 때문에 사용할 수 없습니다 .

내가 사용할 수 없습니다 box.Owner = WindowMain" 'WindowMain'는 유형이고 식으로 사용할 수 없습니다."때문에,


사용해보십시오

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

댓글에서 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>

This is the xaml for my user control (default code behind 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 could take it a bit further and handle the command in a controller class instead and make it that bit more MVC.


I got it to work by crawling all the way back up through my XAML...

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

But this seems quite inelegant. Is there a better way?


What about changing the name of the window to WindowMain1 or something, and setting the owner to that?

ReferenceURL : https://stackoverflow.com/questions/607370/wpf-how-do-i-set-the-owner-window-of-a-dialog-shown-by-a-usercontrol

반응형