2014-05-20 9 views
0

J'ai une MainWindow avec une bordure et un ChildWindow comme une boîte de dialogue sans une bordure. Quand une fenêtre enfant est ouverte, il n'est pas possible de déplacer la fenêtre principale ou de la redimensionner.Comment faire pour déplacer enfant-fenêtre sans fenêtre/Boîte de dialogue dans WPF

Je veux que l'application se comporte comme c'est une seule fenêtre.

J'ai essayé d'utiliser un comportement comme dans le lien suivant mais cela ne fait que déplacer ma fenêtre enfant à l'intérieur de la fenêtre principale.

DragBahvior

Répondre

2

Il est un moyen de permettre beaucoup plus facile le traînement, ou le déplacement des Window s sans marge. S'il vous plaît voir la page Window.DragMove Method sur MSDN pour plus de détails, mais en bref, il vous suffit d'ajouter cette ligne à votre code dans l'une des souris vers le bas des gestionnaires d'événements:

public YourWindow() 
{ 
    InitializeComponent(); 
    MouseLeftButtonDown += YourWindow_MouseLeftButtonDown; 
} 

...

private void YourWindow_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
{ 
    DragMove(); // <-- this is all you need to add 
} 

Les utilisateurs pourront alors cliquer sur n'importe quelle zone du Window (en fonction de ce que vous y mettez) et le faire glisser autour de l'écran.

MISE A JOUR >>>

Il semble que il y a plus à vos besoins que j'ai remarqué. Pour réaliser ce que vous voulez, il y a un certain nombre de choses que vous devez faire. Tout d'abord, vous devez positionner l'enfant Window dans un lieu particulier par rapport au MainWindow.xaml Window. Comme vous l'ouvrez, faire quelque chose comme ceci:

Window window = new Window(); 
window.Top = this.Top; 
window.Left = this.Left; 
window.LocationChanged += Window_LocationChanged; 
window.ShowDialog(); 

pourrait être compensée par une certaine quantité de jeu La position enfant Window:

Window window = new Window(); 
window.Top = this.Top + someHorizontalOffsetAmount; 
window.Left = this.Left + someVerticalOffsetAmount; 
window.LocationChanged += Window_LocationChanged; 
window.ShowDialog(); 

Ensuite, vous avez besoin d'un gestionnaire pour l'événement Window.LocationChanged (qui est soulevée l'enfant Window est déplacé):

private void Window_LocationChanged(object sender, EventArgs e) 
{ 
    Window window = (Window)sender; 
    this.Top = window.Top; 
    this.Left = window.Left; 
} 

C'est tout! Maintenant, les deux Window vont se déplacer ensemble. Évidemment, si vous utilisez un offset dans le premier exemple, vous devrez utiliser le (s) même (s) offset (s) dans le gestionnaire Window_LocationChanged.

+0

Ensuite seulement ma fenêtre de dialogue bouge. Ce n'est pas ce que je voulais faire. – Kingpin

1

Il semble que votre dialogue est Modal, par exemple, il a été appelé avec ShowDialog() et vous arrête d'utiliser le reste de l'application jusqu'à ce qu'il soit rejeté, y compris le déplacement de la fenêtre principale.

Si ce n'est pas le comportement que vous voulez, alors vous aurez besoin de faire votre dialogue modeless simplement en appelant Show(), ou encore mieux, puisque vous semblez vouloir se comporter comme une fenêtre, pourquoi ne pas utiliser WPF comme il était destiné et se débarrasser complètement du dialogue?

+0

Ouais, ce serait bien si vous utilisiez juste une superposition de contrôle sur mon mainwindow pour afficher le contenu. Décevant je n'ai pas cette option :( – Kingpin

+0

Ma fenêtre est montrée avec ShowDialog mais Show n'est pas le comportement que je voulais – Kingpin

+0

-1 Pour * ne * pas fournir de réponse à la question Quelle est la raison pour laquelle je vote? ? Représailles? ... c'est l'acte d'un noob amer Ne pouvait pas supporter de perdre les 2 points de réputation sans se venger? Allez Gaz ... avec plus de 8000 réputation, vous êtes sûrement mieux que ça. Mon comportement est pathétique et vraiment inattendu de la part d'un membre réputé – Sheridan

0

J'ai donc finalement trouvé une solution. J'ai écrit une extension à la classe de Windows et c'était trop compliqué :)

namespace MultiWindowWPF 
{ 
    using System; 
    using System.Drawing; 
    using System.Linq; 
    using System.Threading; 
    using System.Windows; 
    using System.Windows.Forms; 
    using System.Windows.Input; 
    using System.Windows.Media; 
    using System.Windows.Threading; 

    using Application = System.Windows.Application; 

    public static class WindowExtensions 
    { 
    /// <summary> 
    /// Shows the Dialog Modal. 
    /// </summary> 
    /// <param name="dialogWindow">The dialog window.</param> 
    public static void ShowModal(this Window dialogWindow) 
    { 
     Window window = Application.Current.Windows.OfType<Window>().FirstOrDefault(w => w.IsKeyboardFocusWithin) ?? Application.Current.MainWindow; 
     IInputElement lastFocused = FocusManager.GetFocusedElement(window); 
     IInputElement lastKeyboardSelected = Keyboard.FocusedElement; 
     EventHandler locationChanged = (sender, args) => ParentWndMove(dialogWindow); 
     SizeChangedEventHandler sizeChanged = (sender, args) => ParentWndMove(dialogWindow); 
     EventHandler stateChanged = (sender, args) => ParentWndStateChanged(dialogWindow); 

     window.LocationChanged += locationChanged; 
     window.SizeChanged += sizeChanged; 
     window.StateChanged += stateChanged; 

     EventHandler close = (sender, args) => 
     { 

     if (dialogWindow.Dispatcher.CheckAccess()) 
     { 
      dialogWindow.Close(); 
     } 
     else 
     { 
      dialogWindow.Dispatcher.Invoke(dialogWindow.Close); 
     } 

     window.LocationChanged -= locationChanged; 
     window.SizeChanged -= sizeChanged; 
     window.StateChanged -= stateChanged; 
     }; 

     EventHandler closed = (sender, args) => 
     { 
     Window self = sender as Window; 
     Enable(); 
     if (self != null) 
     { 
      self.Owner = null; 
     } 
     }; 

     ExitEventHandler exit = (sender, args) => close(sender, args); 

     DependencyPropertyChangedEventHandler isEnabledChanged = null; 
     isEnabledChanged = (o, eventArgs) => 
     { 
      window.Dispatcher.BeginInvoke(
      DispatcherPriority.ApplicationIdle, 
      new Action(
      () => 
       { 
        FocusManager.SetFocusedElement(window, lastFocused); 
      Keyboard.Focus(lastKeyboardSelected); 
     })); 

     ((Window)o).IsEnabledChanged -= isEnabledChanged; 
     }; 
     window.IsEnabledChanged += isEnabledChanged; 
     dialogWindow.Closed += closed; 
     Application.Current.Exit += exit; 

     dialogWindow.Show(); 
     ParentWndMove(dialogWindow); 

     while (Application.Current != null) 
     { 
     DoEvents(); 
     } 
    } 

    private static void DoEvents() 
    { 
     DispatcherFrame frame = new DispatcherFrame(); 
     Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background, new DispatcherOperationCallback(ExitFrame), frame); 
     Dispatcher.PushFrame(frame); 
     Thread.Sleep(10); 
    } 

    private static void Enable() 
    { 
     foreach (Window window in Application.Current.Windows.OfType<Window>().Where(window => !window.OwnedWindows.OfType<Window>().Any())) 
     { 
     window.IsEnabled = true; 
     } 
    } 

    /// <summary> 
    /// Exits the frame. 
    /// </summary> 
    /// <param name="f">The f.</param> 
    /// <returns></returns> 
    public static object ExitFrame(object f) 
    { 
     ((DispatcherFrame)f).Continue = false; 
     return null; 
    } 

    /// <summary> 
    /// Parents the WND state changed. 
    /// </summary> 
    /// <param name="dialogWindow">The dialog window.</param> 
    public static void ParentWndStateChanged(Window dialogWindow) 
    { 
     Window owner = dialogWindow.Owner; 
     if (owner.WindowState != WindowState.Maximized) 
     { 
     dialogWindow.WindowState = owner.WindowState; 
     } 
     ParentWndMove(dialogWindow); 
    } 

    /// <summary> 
    /// Parents the WND move. 
    /// </summary> 
    /// <param name="dialogWindow">The dialog window.</param> 
    public static void ParentWndMove(Window dialogWindow) 
    { 
     Window owner = dialogWindow.Owner; 
     PresentationSource presentationsource = PresentationSource.FromVisual(dialogWindow); 
     Matrix m = presentationsource.CompositionTarget.TransformToDevice; 

     double centerWidth = owner.Left + owner.ActualWidth/2; 
     double centerHeight = owner.Top + owner.ActualHeight/2; 
     if (owner.WindowState == WindowState.Normal) 
     { 
     dialogWindow.Top = centerHeight - dialogWindow.ActualHeight/2; 
     dialogWindow.Left = centerWidth - dialogWindow.ActualWidth/2; 
     } 
     if (owner.WindowState == WindowState.Maximized) 
     { 
     //there is no current main window position to use, center on working screen 
     Rectangle frame = Screen.FromPoint(new System.Drawing.Point((int)(dialogWindow.Left * m.M11), (int)(dialogWindow.Top * m.M22))).Bounds; 

     dialogWindow.Left = frame.X/m.M11 + (frame.Width/m.M11 - dialogWindow.ActualWidth)/2; 
     dialogWindow.Top = frame.Y/m.M22 + (frame.Height/m.M22 - dialogWindow.ActualHeight)/2; 
     } 
    } 
    } 
} 
Questions connexes