将窗口放入另一个窗口
我的下降事件
private void Window_Drop(object sender, DragEventArgs e) { var window = e.Data.GetData(typeof(Window)) as Window; if (window != null) { var tabitem = new TabItem(); tabitem.Content = window.Content; tabcontrol1.Items.Add(tabitem); window.Close(); } }
我的主窗口XAML
什么都没发生,任何想法为什么?
如何将应用程序中的任何窗口拖放到主窗口中?
展示我想要做的事情 tabitem5和tabitem2被拖到主窗口之外,因此成为独立的窗口,现在我试图通过将它们拖动到主窗口来反转过程并再次使它们成为标签
我正在给予完整代码示例的赏金,选项卡到窗口和窗口到选项卡,mvvm解决方案也是可以接受的
听起来你正在尝试实现对接系统。 你有没有看过现有的Docking Manager。
Avalon Dock是一个很好的开源示例。 它记录良好且易于使用。
如果您决定实施自己的,您可以尝试查找拖动的窗口下方是否有窗口。 不幸的是,WPF在Windows上没有简单的HitTest方法。 解决这个问题的方法是进行一些Win32调用。 Fredrik Hedblad使用的代码来自Ray Burns的另一个SO线程,以及获取当前鼠标位置的Win32调用。
我还使用了WindowStyle="None"
并为窗口实现了一个自定义标题栏,以便我可以在窗口中捕获鼠标事件。
我不完全确定你是如何实现选项卡拖动来创建一个新窗口但如果这样做有效,你可以执行以下操作。
XAML
码
public partial class DraggedWindow : Window { private readonly MainWindow _mainWindow; private bool _isDropped = false; public DraggedWindow(MainWindow mainWindow) { _mainWindow = mainWindow; InitializeComponent(); DataContext = new TabItem() { Header = "TabItem6", Content = "Content6" }; } const uint GW_HWNDNEXT = 2; [DllImport("User32")] static extern IntPtr GetTopWindow(IntPtr hWnd); [DllImport("User32")] static extern IntPtr GetWindow(IntPtr hWnd, uint wCmd); [DllImport("User32")] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool GetCursorPos(ref Win32Point pt); [StructLayout(LayoutKind.Sequential)] internal struct Win32Point { public Int32 X; public Int32 Y; }; public static Point GetMousePosition() { Win32Point w32Mouse = new Win32Point(); GetCursorPos(ref w32Mouse); return new Point(w32Mouse.X, w32Mouse.Y); } public Window FindWindowUnderThisAt(Point screenPoint) // WPF units (96dpi), not device units { return ( from win in SortWindowsTopToBottom(Application.Current.Windows.OfType()) where new Rect(win.Left, win.Top, win.Width, win.Height).Contains(screenPoint) && !Equals(win, this) select win ).FirstOrDefault(); } public IEnumerable SortWindowsTopToBottom(IEnumerable unsorted) { var byHandle = unsorted.ToDictionary(win => ((HwndSource)PresentationSource.FromVisual(win)).Handle); for (IntPtr hWnd = GetTopWindow(IntPtr.Zero); hWnd != IntPtr.Zero; hWnd = GetWindow(hWnd, GW_HWNDNEXT)) { if (byHandle.ContainsKey(hWnd)) yield return byHandle[hWnd]; } } private void DraggedWindow_OnMouseMove(object sender, MouseEventArgs e) { if (e.LeftButton == MouseButtonState.Pressed) { this.DragMove(); } var absoluteScreenPos = GetMousePosition(); var windowUnder = FindWindowUnderThisAt(absoluteScreenPos); if (windowUnder != null && windowUnder.Equals(_mainWindow)) { if (_isDropped) { // Your code here var tabitem = new TabItem(); tabitem.Content = (DataContext as TabItem).Content; tabitem.Header = (DataContext as TabItem).Header; _mainWindow.TabControl1.Items.Add(tabitem); this.Close(); } } } private void DraggedWindow_OnMouseDown(object sender, MouseButtonEventArgs e) { _isDropped = false; } private void DraggedWindow_OnMouseUp(object sender, MouseButtonEventArgs e) { _isDropped = true; } }
主窗口Xaml(示例)
Content1 Content2 Content3 Content4 Content5
主窗口代码(示例)
public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); new DraggedWindow(this).Show(); } }