it-swarm.com.de

WPF: Wie stelle ich das Besitzerfenster eines von einem UserControl angezeigten Dialogfelds ein?

Ich habe eine WPF-Anwendung mit diesen drei Arten von Dingen ...

  • WindowMain
  • UserControlZack
  • WindowModal

UserControlZack1 sitzt auf meinem 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 zeigt eine WindowModal-Dailog-Box an ...

 Teilweise öffentliche Klasse UserControlZack 
 
 ... 
 
 Private Sub SomeButton_Click (...) 
 'Instanziiert das Dialogfeld und modal öffnen ... 
 Feld abdunkeln als WindowModal = Neues WindowModal () 
 Feld. Eigentümer = ????? 
 Feld. ShowDialog () 
 ' Vom Benutzer eingegebene Daten verarbeiten, wenn das Dialogfeld akzeptiert wird ... 
 If (box.DialogResult.GetValueOrDefault = True) Then 
 _SomeVar = box.SomeVar 
 ... 
 End If 
 End Sub 
 
 End Class 

Wie setze ich box.Owner auf das richtige Fenster, meine laufende Instanz von WindowMain?

Ich kann nicht benutzen box.Owner = Me.Owner, weil "'Owner' kein Mitglied von 'ProjectName.UserControlZack' ist."

Ich kann nicht benutzen box.Owner = Me.Parent, weil das ein Gitter zurückgibt, nicht das Fenster.

Ich kann nicht benutzen box.Owner = WindowMain, weil "'WindowMain' ein Typ ist und nicht als Ausdruck verwendet werden kann."

54
Zack Peterson

Versuchen zu benutzen

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

Um das Fenster der obersten Ebene zu erhalten, in dem sich Ihr Steuerelement befindet, gehen Sie davon aus, dass es eines gibt:

(Window)PresentationSource.FromVisual(this).RootVisual

So rufen Sie das Hauptfenster auf:

Application.Current.MainWindow
40
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

Aktualisieren, um zu versuchen, Greg aus den Kommentaren zu helfen. Der Befehl funktioniert im Hauptfenstermenü, der Schaltfläche im Benutzersteuerelement und dem Kontextmenü im Benutzersteuerelement.

Ich würde es mit Befehlen machen. Also haben Sie eine Klasse Commands.cs so etwas wie:

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

Registrieren Sie diese in Ihrem Hauptfenster: (Sie brauchen nicht die Canshow, die standardmäßig auf true gesetzt ist.)

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

Dies ist meine XAML für das Hauptfenster:

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

Dies ist die XAML für meine Benutzersteuerung (Standardcode nur dahinter)

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

Sie könnten noch ein bisschen weiter gehen und den Befehl stattdessen in einer Controller-Klasse verarbeiten und MVC ein bisschen weiterentwickeln.

5
Andrew Barrett

Ich habe es geschafft, indem ich den ganzen Weg durch meine XAML zurückgekrabbelt bin ...

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

Aber das scheint ziemlich unelegant. Gibt es einen besseren Weg?

0
Zack Peterson

Wie wäre es, wenn Sie den Namen des Fensters in WindowMain1 oder so ändern und den Eigentümer darauf setzen?

0
Davy8