我有一个带有边框的MainWindow和一个没有边框的对话窗口ChildWindow。当一个子窗口打开时,不可能移动主窗口或调整它的大小。如何在WPF中移动无边界的子窗口/对话框
我希望应用程序的行为只有一个窗口。
我试图使用一个行为,因为在下面的链接,但只是移动我的子窗口在主窗口内。
我有一个带有边框的MainWindow和一个没有边框的对话窗口ChildWindow。当一个子窗口打开时,不可能移动主窗口或调整它的大小。如何在WPF中移动无边界的子窗口/对话框
我希望应用程序的行为只有一个窗口。
我试图使用一个行为,因为在下面的链接,但只是移动我的子窗口在主窗口内。
有使拖动或无边界Window
S的移动更简单的方法。请参阅MSDN上的Window.DragMove
Method页面了解更多细节,但总之,你只需要这一行添加到您的代码在鼠标按下事件处理程序之一:
public YourWindow()
{
InitializeComponent();
MouseLeftButtonDown += YourWindow_MouseLeftButtonDown;
}
...
private void YourWindow_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
DragMove(); // <-- this is all you need to add
}
然后用户可以点击Window
的任何区域(取决于您放入的内容)并将其拖动到屏幕上。
UPDATE >>>
所以它好像还有更多你的要求比我第一次注意到。为了达到你想要的,你必须做很多事情。首先,您需要将儿童Window
定位在相对于MainWindow.xaml Window
的特定位置。当你打开它,做这样的事情:
Window window = new Window();
window.Top = this.Top + someHorizontalOffsetAmount;
window.Left = this.Left + someVerticalOffsetAmount;
window.LocationChanged += Window_LocationChanged;
window.ShowDialog();
然后你需要为Window.LocationChanged
事件的处理程序(这是引发时:
Window window = new Window();
window.Top = this.Top;
window.Left = this.Left;
window.LocationChanged += Window_LocationChanged;
window.ShowDialog();
孩子Window
位置可以通过一些设定数额抵消孩子Window
被移动):
private void Window_LocationChanged(object sender, EventArgs e)
{
Window window = (Window)sender;
this.Top = window.Top;
this.Left = window.Left;
}
就是这样!现在两个Window
将一起移动。显然,如果在第一个示例中使用了偏移量,则需要在处理程序中使用相同的偏移量。
这听起来像你的对话框是莫代尔,即它与ShowDialog()
调用和使用应用程序的其余部分,直到它被驳回,包括移动主窗口阻止你。
如果这不是你想要的行为,则需要通过只调用Show()
,或者更好,让您的对话框无模式,因为你似乎希望它表现为一个窗口,为什么不使用WPF作为它的目的是完全摆脱对话?
所以我终于找到了一个解决方案。我写了一个扩展到Windows类,它已退出复杂:)
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;
}
}
}
}
然后只有我的对话框窗口正在移动。这不是我想要做的。 – Kingpin