2013-10-25 9 views
12

マイドロップイベントドロップ別のウィンドウにウィンドウ

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ソリューションがあまりにも

+0

ドラッグ操作を始めているコードを含むあなたの完全なコードを投稿してください。 –

+0

@HighCore thats私が逃しているもの – FPGA

+0

@HighCore PreviewMouseMoveハンドラは、ドラッグしたいサブウィンドウ上にあるはずですか? – FPGA

答えて

8

許容され、完全なコードサンプルのタブにウィンドウとウィンドウにタブを恵みを与えています。あなたは既存のドッキングマネージャーを見たことがありますか?

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

ちょうど完璧なことは、ドックアイテムを別のウィンドウに変換することをサポートしていない利用可能なドックマネージャーがあることです。タスクバーのドックアイテムを見たいと思っています。 +185、そして私はあなたにもっと多くを与えることを望む – FPGA

+0

これは、投票のダースに値する! –

関連する問題