拖放窗口到另一个窗口 [英] Drop a window into another window

查看:98
本文介绍了拖放窗口到另一个窗口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的drop事件

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

My mainwindow 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">



什么也没有发生,任何想法,为什么?

Nothing happens, any idea why?

我怎样可以删除任何窗口在我的申请,我的主窗口

How can I drop any window in my application into my main window?

要证明什么,我试图做
b将tabitem5 $ b $和tabitem2被拖到了外面主窗口,因而成为独立的窗口,现在我试图扭转这一进程并通过拖动到主窗口

to demonstrate what i am trying to do the tabitem5 and tabitem2 were dragged outside the mainwindow and thus the became independent windows, now i am trying to reverse the process and make them tabs again by dragging them to the main window

我给赏金一个完整的代码示例,标签,窗口和窗口标签让他们的标签再次,一个MVVM解决方案接受过

i am giving the bounty for a full code sample, tab to window and window to tab, an mvvm solution is acceptable too

推荐答案

这听起来像你正试图实现对接系统。你吃过看看现有的对接管理。

It sounds like you are trying to implement a docking system. Have you had a look at existing Docking Managers.

阿瓦隆码头是一个伟大的开源例子。这是有据可查的,易于使用。

Avalon Dock is a great Open Source example. It's well documented and easy to use.

如果你决心实现自己的,你可以尝试寻找是否有您拖动一个下一个窗口。不幸的是WPF没有一种简单的方法跨Windows来的HitTest。解决这个问题的方法是做一些Win32调用。使用的代码是从另一个线程SO 这里,通过的雷伯恩斯和Win32调用获取当前的鼠标位置,由弗雷德里克Hedblad

If you're determined to implement your own, you can try to find if there is a Window beneath the one you are dragging. Unfortunately WPF doesn't have an easy way to HitTest across Windows. The way around this would be to make some Win32 calls. The code used is from another SO thread here, by Ray Burns and a Win32 call for getting the current mouse position, by Fredrik Hedblad.

我也用 WindowStyle =无并实施了窗口自定义标题栏,所以我还可以捕捉鼠标该窗口上的事件。

I've also used WindowStyle="None" and implemented a custom title bar for the window so I can catch mouse events on the window.

我不完全相信你如何执行的标签拖动到创建一个新窗口,但如果是工作,你可以做到以下几点。

I'm not entirely sure how you have implemented the tab dragging to create a new window but if that is working you can do the following.

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

这篇关于拖放窗口到另一个窗口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆