web-dev-qa-db-ja.com

Wpf:テキストボックスにドラッグアンドドロップ

私はこの問題をグーグルで調べ、人々は同様の質問に答えましたが、何らかの理由で何も動作しません。ここで何かを見逃していたに違いありません...とにかく、次のコードを実行すると、TextBox_DragEnterハンドラーが呼び出されません。ただし、xamlのTextBox要素をTextBlock要素に変更すると、それが呼び出されます。 TextBox要素から同じ動作を取得する方法はありますか?次のコードは問題を完全に分離します...

MainWindow.xaml:

<Window x:Class="Wpf1.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">
    <Grid Name="myGrid">
        <TextBox AllowDrop="True" PreviewDragEnter="TextBox_DragEnter" PreviewDrop="TextBox_Drop" />
    </Grid>
</Window>

MainWindow.xaml.cs:

using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Collections.ObjectModel;

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

        private void TextBox_DragEnter(object sender, DragEventArgs e)
        {
            e.Effects = DragDropEffects.Copy;
        }

        private void TextBox_Drop(object sender, DragEventArgs e)
        {

        }
    }
}

よろしくお願いします!

アンドリュー

編集:

明確にするために、カスタムオブジェクトをテキストボックスにドロップできるようにしたいと思います。次に、テキストボックスのドロップハンドラーで、テキストボックスのテキストをオブジェクトのプロパティに設定し、TextBoxのIsReadOnlyプロパティをfalseに設定します。 TextBoxのドラッグアンドドロップを有効にするのに問題があります...

34
Andrew

PreviewDragOverのハンドラーを追加する場合は、e.Handled = trueに設定すると機能します。

とにかく私のために働く。

53
Liz

TextBoxには、DragAndDropのデフォルトの処理がすでにいくつかあるようです。データオブジェクトが文字列の場合、それは単に機能します。他のタイプは処理されず、Forbiddenマウス効果が得られ、ドロップハンドラーが呼び出されることはありません。

trueイベントハンドラーでe.HandledからPreviewDragOverを使用して独自の処理を有効にできるようです。

詳細についてはMSDNで確認できませんでしたが、 http://www.codeproject.com/Articles/42696/Textbox-Drag-Drop-in-WPF が役立ちました。

17
trapicki

また、PreviewDragOverと同じ方法でPreviewDragEnterを処理することもできます。そうしないと、デフォルトで最初のピクセルでForbiddenマウスになります。

ハンドラーで、DragEventArgs.Dataがドロップするタイプであることを確認します。ある場合は、DragEventsArgs.EffectsをDragDropEffects.MoveまたはAllowedEffectsの他の何かに設定します。ドロップするタイプでない場合は、DragDropEffects.Noneに設定してドロップを無効にします。

MVVM LightのXAML:

<i:Interaction.Triggers>
        <i:EventTrigger EventName="Drop">
            <cmd:EventToCommand Command="{Binding DragDropCommand}" PassEventArgsToCommand="True" />
        </i:EventTrigger>
        <i:EventTrigger EventName="PreviewDragOver">
            <cmd:EventToCommand Command="{Binding PreviewDragEnterCommand}" PassEventArgsToCommand="True" />
        </i:EventTrigger>
        <i:EventTrigger EventName="PreviewDragEnter">
            <cmd:EventToCommand Command="{Binding PreviewDragEnterCommand}" PassEventArgsToCommand="True" />
        </i:EventTrigger>
    </i:Interaction.Triggers>

ViewModelのハンドラ:

        private void ExecutePreviewDragEnterCommand(DragEventArgs drgevent)
        {
            drgevent.Handled = true;


            // Check that the data being dragged is a file
            if (drgevent.Data.GetDataPresent(DataFormats.FileDrop))
            {
                // Get an array with the filenames of the files being dragged
                string[] files = (string[])drgevent.Data.GetData(DataFormats.FileDrop);

                if ((String.Compare(System.IO.Path.GetExtension(files[0]), ".xls", true) == 0)
                    && files.Length == 1)
                    drgevent.Effects = DragDropEffects.Move;
                else
                    drgevent.Effects = DragDropEffects.None;

            }
            else
                drgevent.Effects = DragDropEffects.None;
        }
6
haps

Textboxを実装する独自のTextboxクラスを作成することをお勧めします。次に、OnDrag-Eventsをオーバーライドし、e.handledfalseに設定するか、必要な操作を行います。

本来の必要な動作のために作成されていないイベントを使用するのは少し汚いです。プレビューは、実際のDragDrop-Eventsをコミットする前に、いくつかのものをチェックして、元に戻すオプションを用意することです。

0
Tost