0

ドラッグ アンド ドロップ操作中に OnMouseMove や MouseWheel などのイベントを処理したい。

ただし、ドラッグ/ドロップに関するこの MSDN トピックからわかる限り、ドラッグ/ドロップ操作中に発生するイベントは、GiveFeedback、QueryContinueDrag、Drag Enter/Leave/Over、および対応する Preview* のみです。基本的に、これらのイベントを処理することで、マウスの位置を取得したり、ユーザーが Ctrl、Shift、Alt、Esc を押したり、マウス ボタンの 1 つを押したり離したりしたかどうかを確認したりできます。

ただし、ドラッグ アンド ドロップ操作中に、MouseWheel などの他のイベントを処理したいと考えています。具体的には、ユーザーが何かをドラッグしながら (マウス ホイールを使用して) ウィンドウの内容をスクロールできるようにすることです。バブリング バージョンとトンネリング バージョンの両方の他のイベントのハンドラーを作成し、それらをコントロール階層のさまざまなレベルにアタッチしようとしましたが、私が知る限り、それらのどれも起動していません。

マウスの位置がウィンドウの上部または下部にあるときに、DragOver を使用してウィンドウの内容をスクロールする部分的な解決策 (たとえば、ここで説明) があることは承知しています。しかし、それは私がやりたいことではありません。

ドラッグ操作中に (たとえば) OnMouseMove イベントを処理できることを示唆する記事を見つけました。記事のコードは上記のアプローチの変形ですが、DragOver ではなく OnMouseMove を処理するためです。ただし、このアプローチを採用しようとしましたが、ドラッグ中に OnMouseMove イベントを発生させることはできません。以下にコードを追加しました。これは F# であるため、FSharpxのF# XAML タイプ プロバイダーを使用しました。

MainWindow.xaml:

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="500" Width="900">
    <DockPanel Name="panel1">
        <StatusBar Name="status1" DockPanel.Dock="Bottom">
            <TextBlock Name="statustext1" />
        </StatusBar>
    </DockPanel>
</Window>

Program.fs:

(* 
Added references: PresentationCore, PresentationFramework, System.Xaml, UIAutomationTypes, WindowsBase.
*)

// STAThread, DateTime
open System
// Application
open System.Windows
// TextBox
open System.Windows.Controls

// XAML type provider
open FSharpx

type MainWindow = XAML<"MainWindow.xaml">

type TextBox2 (status : TextBlock) as this =
    inherit TextBox () with
    member private this.preview_mouse_left_button_down (args : Input.MouseButtonEventArgs) = do
        this.CaptureMouse () |> ignore
        base.OnPreviewMouseLeftButtonDown args
// Fires while selecting text with the mouse, but not while dragging.
    member private this.preview_mouse_move (args : Input.MouseEventArgs) =
        if this.IsMouseCaptured then do status.Text <- sprintf "mouse move: %d" <| DateTime.Now.Ticks
        do base.OnPreviewMouseMove args
    member private this.preview_mouse_left_button_up (args : Input.MouseButtonEventArgs) = do
        if this.IsMouseCaptured then do this.ReleaseMouseCapture ()
        base.OnPreviewMouseLeftButtonUp args
    do
        this.PreviewMouseLeftButtonDown.Add this.preview_mouse_left_button_down
        this.PreviewMouseMove.Add this.preview_mouse_move
        this.PreviewMouseLeftButtonUp.Add this.preview_mouse_left_button_up

let load_window () =
    let win = MainWindow ()
    let t = new TextBox2 (win.statustext1)
    do
        t.TextWrapping <- TextWrapping.Wrap
        t.AcceptsReturn <- true
        t.Height <- Double.NaN
        win.panel1.Children.Add t |> ignore
    win.Root

[<STAThread>]
(new Application () ).Run(load_window () ) |> ignore
4

2 に答える 2

1

PreviewDragEnterPreviewDragOver、およびDropを使用すると、これをより効果的に行うことができると思います。独自のドラッグ アンド ドロップ テキスト ボックスの作成に関するブログ トピックを書きました。そこからスクロール機能を追加できます。

http://xcalibur37.wordpress.com/2011/12/10/wpf-drag-and-drop-textbox-for-windows-explorer-files/

コード:

/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        // Initialize UI
        InitializeComponent();

        // Loaded event
        this.Loaded += delegate
            {
                TextBox1.AllowDrop = true;
                TextBox1.PreviewDragEnter += TextBox1PreviewDragEnter;
                TextBox1.PreviewDragOver += TextBox1PreviewDragOver;
                TextBox1.Drop += TextBox1DragDrop;
            };
    }

    /// <summary>
    /// We have to override this to allow drop functionality.
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    void TextBox1PreviewDragOver(object sender, DragEventArgs e)
    {
        e.Handled = true;
    }

    /// <summary>
    /// Evaluates the Data and performs the DragDropEffect
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void TextBox1PreviewDragEnter(object sender, DragEventArgs e)
    {
        if (e.Data.GetDataPresent(DataFormats.FileDrop))
        {
            e.Effects = DragDropEffects.Copy;
        }
        else
        {
            e.Effects = DragDropEffects.None;
        }
    }

    /// <summary>
    /// The drop activity on the textbox.
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void TextBox1DragDrop(object sender, DragEventArgs e)
    {
        // Get data object
        var dataObject = e.Data as DataObject;

        // Check for file list
        if (dataObject.ContainsFileDropList())
        {
            // Clear values
            TextBox1.Text = string.Empty;

            // Process file names
            StringCollection fileNames = dataObject.GetFileDropList();
            StringBuilder bd = new StringBuilder();
            foreach (var fileName in fileNames)
            {
                bd.Append(fileName + "\n");
            }

            // Set text
            TextBox1.Text = bd.ToString();
        }
    }
}

ブログのトピックでは、各セクションの内訳分析が提供されます。

于 2013-05-11T14:12:06.253 に答える