c# - 将一个窗口拖放到另一个窗口中

标签 c# wpf window

我的掉落事件

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

 <Window x:Class="WpfApplication2.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525" Drop="Window_Drop">

没有任何反应,知道为什么吗?

如何将应用程序中的任何窗口拖放到主窗口中?

展示我正在尝试做的事情 enter image description here tabitem5 和 tabitem2 被拖到主窗口之外,因此成为独立的窗口,现在我试图扭转这个过程,通过将它们拖到主窗口来再次使它们成为标签

我悬赏一个完整的代码示例,选项卡到窗口和窗口到选项卡,mvvm 解决方案也是可以接受的

最佳答案

听起来您正在尝试实现对接系统。您是否查看过现有的对接管理器。

Avalon Dock是一个很好的开源示例。它有据可查且易于使用。

如果您决定实现自己的,可以尝试查找您拖动的窗口下方是否有一个窗口。不幸的是,WPF 没有一种跨 Windows 进行 HitTest 的简单方法。解决这个问题的方法是进行一些 Win32 调用。使用的代码来自另一个 SO 线程 here , 通过 Ray Burns以及获取当前 mouse position 的 Win32 调用, 通过 Fredrik Hedblad .

我还使用了 WindowStyle="None" 并为窗口实现了一个自定义标题栏,这样我就可以在窗口上捕获鼠标事件。

我不完全确定您是如何实现选项卡拖动以创建新窗口的,但如果可行,您可以执行以下操作。

XAML

<Window x:Class="WpfApplication1.DraggedWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Dragged Window" Height="350" Width="525"
    MouseMove="DraggedWindow_OnMouseMove" MouseDown="DraggedWindow_OnMouseDown" MouseUp="DraggedWindow_OnMouseUp" WindowStyle="None">
<Window.Resources>
    <Style TargetType="HeaderedContentControl">
        <Setter Property="HeaderTemplate">
            <Setter.Value>
                <DataTemplate>
                    <Border Background="Gray" Opacity="0.8">
                        <DockPanel LastChildFill="True">
                            <Button DockPanel.Dock="Right" Content="X" Width="20" Height="20" Margin="2"/>
                            <TextBlock DockPanel.Dock="Left" Text="{Binding Header}"/>
                        </DockPanel>
                    </Border>
                </DataTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>
<Grid>
    <HeaderedContentControl Header="{Binding}" Content="{Binding Content}"/>
</Grid>

代码

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<Window>())
          where new Rect(win.Left, win.Top, win.Width, win.Height).Contains(screenPoint)
          && !Equals(win, this)
          select win
        ).FirstOrDefault();
    }

    public IEnumerable<Window> SortWindowsTopToBottom(IEnumerable<Window> 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(示例)

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="350" Width="525">
<Grid>
    <TabControl Name="TabControl1">
        <TabItem Header="TabItem1">Content1</TabItem>
        <TabItem Header="TabItem2">Content2</TabItem>
        <TabItem Header="TabItem3">Content3</TabItem>
        <TabItem Header="TabItem4">Content4</TabItem>
        <TabItem Header="TabItem5">Content5</TabItem>
    </TabControl>
</Grid>

主窗口代码(示例)

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        new DraggedWindow(this).Show();
    }
}

关于c# - 将一个窗口拖放到另一个窗口中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19595618/

相关文章:

Swift ,隐藏/删除窗口( View ?)

c# - CF.NET SMTP - 使用 Gmail 发送电子邮件

c# - (C#) 如何在不加载或重写整个文件的情况下修改现有 XML 文件中的属性值?

.net - 替代基于消息区分异常?

c# - 从 Excel 粘贴到 WPF DataGrid

java - 如何设置窗口始终在任何其他应用程序之上

c# - 在 C# 中访问 UNC 路径的最佳方式

c# - 如何使用覆盖 Equals() 的逻辑实现对 GetHashCode() 的覆盖

c# - MVVMLight CanExecute 在单击窗口之前不起作用

window - 关于close.window()方法的 Electron 问题