5

ユーザーがドラッグできるWPFでウィンドウを作成するアプリがあります。親ウィンドウのメインメニューを超えないように制限したいと思います。WindowLocationChangedイベントを処理すると、変更が既に行われたに発生するため、ウィンドウを強制的に別の位置に戻すことしかできません。これにより、視覚効果が低下します。

移動が実際に発生する前に処理できるイベントはありますか?これにより、ウィンドウを傍受して特定の制限内にとどめることができますか? 一部の商用 WPF ライブラリは、実際に画面上で移動が発生する前に発生するOnMovingイベントをサポートしています。ネイティブ WPF にそのようなものはありますか (可能であれば、マネージ コード環境内にとどまります)。

または、依存関係プロパティを使用して x、y の最大値または最小値を設定する方法はありますか? (注、サイズ変更ではなく、移動しています)

前もって感謝します。

4

1 に答える 1

8

この例は、ウィンドウが開始 X/Y 位置より下に移動するのを防ぐ方法を示すデモです...何をしたいのかの開始点を提供するはずです。

サイズ変更時に上と左の位置が変更される可能性があることに注意してください。そのため、サイズ変更によって変更されないように WM_SIZING メッセージも処理されます。

それが必要ない場合は、WM_SIZING ケースを取り出してください。

    <Window x:Class="WpfApplication12.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" Loaded="Window_Loaded">
        <Grid>

        </Grid>
    </Window>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Interop;
using System.Runtime.InteropServices;

namespace WpfApplication12
{
    [StructLayout(LayoutKind.Sequential)]
    public struct WIN32Rectangle
    {
        public int Left;
        public int Top;
        public int Right;
        public int Bottom;
    }

    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        const int WM_SIZING = 0x0214;
        const int WM_MOVING = 0x0216;

        private Point InitialWindowLocation;

        public MainWindow()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            WindowInteropHelper helper = new WindowInteropHelper(this);
            HwndSource.FromHwnd(helper.Handle).AddHook(HwndMessageHook);

            InitialWindowLocation = new Point(this.Left, this.Top);
        }

        private IntPtr HwndMessageHook(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam, ref bool bHandled)
        {
            switch (msg)
            {
               // You may prefer to check the specific size action being done
               //
               //case WM_SIZING:
               //     {
               //         case (wParam)
               //         {
               //             case WMSZ_LEFT:
               //             {

               //             }
               //             break;

               //             case WSSZ_TOP:
               //             {
               //             }
               //             break;

               //             case WSSZ_TOPLEFT:
               //             {
               //             }
               //             break;
               //         }
               //     }
               //     break;

                case WM_SIZING:
                case WM_MOVING:
                    {
                        WIN32Rectangle rectangle = (WIN32Rectangle)Marshal.PtrToStructure(lParam, typeof(WIN32Rectangle));

                        if (rectangle.Left < this.InitialWindowLocation.X)
                        {
                            rectangle.Left = (int)this.InitialWindowLocation.X;
                            rectangle.Right = (int)this.Left + (int)this.Width;

                            bHandled = true;
                        }

                        if (rectangle.Top < this.InitialWindowLocation.Y)
                        {
                            rectangle.Top = (int)this.InitialWindowLocation.Y;
                            rectangle.Bottom = (int)this.Top + (int)this.Height;

                            bHandled = true;
                        }

                        if (bHandled)
                        {
                            Marshal.StructureToPtr(rectangle, lParam, true);
                        }
                    }
                    break;

            }
            return IntPtr.Zero;
        }
    }
}
于 2012-09-11T22:15:24.367 に答える