2011-02-07 15 views
3

DragMove()メソッドを使用してドラッグできるwpfの子ウィンドウがあります。 しかし、ウィンドウを親ウィンドウコントロールの境界内でのみドラッグできるようにする必要があります。特定の境界内でウィンドウをドラッグ可能にするWPF

誰でもこれを達成する方法を提案できますか? ありがとう!

答えて

5

これを行うには2通りの方法があります。 LocationEnded

を使用して

あなたがこのイベントを処理する場合は、オーナーウィンドウの境界内にあることをトップまたは左を変更することができます。例:

private void Window_LocationChanged(object sender, EventArgs e) 
    { 

     if (this.Left < this.Owner.Left) 
      this.Left = this.Owner.Left; 

     //... also right top and bottom 
     // 
    } 

これを書くのは非常に簡単ですが、それは、ユーザーがマウスボタンを放すとき、それは場所にそれだけでバックウィンドウをプッシュドラッグウィンドウを拘束しないようPrinciple of least astonishmentに違反します。ピーターは、Windowsメッセージングに相互運用機能とドラッグウィンドウをブロックすることができます同様の質問にはan answerで指摘するようにAddHook

を使用して

。これは、の素晴らしい影響を実際のドラッグウィンドウを境界にしています

ここで私はあなただけの移動を探したり、メッセージを移動するフックハンドラで

//In Window_Loaded the handle is there (earlier its null) so this is good time to add the handler 

    private void Window_Loaded(object sender, RoutedEventArgs e) 
    { 

     WindowInteropHelper helper = new WindowInteropHelper(this); 
     HwndSource.FromHwnd(helper.Handle).AddHook(HwndSourceHookHandler); 
    } 

を追加するためにロードされたウィンドウでAddHookアプローチのために一緒に

スタートを入れていくつかのサンプルコードです。次に、lParam矩形を読んで境界外かどうかを確認します。もしそうなら、lParam矩形の値を変更し、それを元に戻す必要があります。簡潔にするために、私は左だけをしました。あなたは、右、上、下のケースを書き留める必要があります。

private IntPtr HwndSourceHookHandler(IntPtr hwnd, int msg, IntPtr wParam, 
    IntPtr lParam, ref bool handled) 
     { 


const int WM_MOVING = 0x0216; 
     const int WM_MOVE = 0x0003; 


     switch (msg) 
     { 
      case WM_MOVING: 
       { 


        //read the lparm ino a struct 

        MoveRectangle rectangle = (MoveRectangle)Marshal.PtrToStructure(
         lParam, typeof(MoveRectangle)); 


        // 

        if (rectangle.Left < this.Owner.Left) 
        { 
         rectangle.Left = (int)this.Owner.Left; 
         rectangle.Right = rectangle.Left + (int)this.Width; 
        } 



        Marshal.StructureToPtr(rectangle, lParam, true); 

        break; 
       } 
      case WM_MOVE: 
       { 
        //Do the same thing as WM_MOVING You should probably enacapsulate that stuff so don'tn just copy and paste 

        break; 
       } 


     } 

     return IntPtr.Zero; 

    } 

あなたは子ウィンドウが親ウィンドウよりも大きいことを許可されている場合、何をすべきかを把握する必要がありますlParamに

[StructLayout(LayoutKind.Sequential)] 
    //Struct for Marshalling the lParam 
    public struct MoveRectangle 
    { 
     public int Left; 
     public int Top; 
     public int Right; 
     public int Bottom; 

    } 

最後の注意のための構造体。

+0

ありがとう、コンラッド。私はこれを試み、あなたに知らせるでしょう。 – Dan

+0

@ダンちょうどあなたがダブルスからintsへのキャストはおそらく大丈夫だと知らせるために。 [この質問](http://stackoverflow.com/q/4937003/119477)を参照してください。 –

関連する問題