45592


WPFのListBoxでドラッグ＆ドロップを実現するためにListBoxにDragDrop関連のイベントを実装したのですが、DragEnter,DragLeaveイベントがListBoxの出入りでなくListBoxItemの出入りで発生するような挙動になってしまっています。

最終的には項目状態毎にドラッグの受け入れエフェクトを変更しようと思っているのですが、上記の現象の影響かドラッグエフェクトがちらついてしまうのが気になっています。

**質問**

Q1. どうしてこのような挙動になってしまうのでしょうか。  
Q2.
ListBoxの出入りでのみDragEnter,DragLeaveを発生させ、ListBox内ではDragOverイベントのみ発生させるようにするにはどうしたらよいのでしょうか。

**環境**

  * Windows 10
  * VisualStudio 2017
  * .Net Framework 4.6.2

**サンプルコード**

MainWindow.xaml

[code]

    <Window x:Class="Work.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:Work"
            mc:Ignorable="d"
            Title="MainWindow" Height="500" Width="500">
        <Grid>
            <ListBox x:Name="ListBox01" Margin="10" ItemsSource="{Binding Items}"
                      AllowDrop="True"
                      DragEnter="ListBox_DragEnter"
                      DragLeave="ListBox_DragLeave"
                      PreviewDragOver="ListBox_PreviewDragOver">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <Grid MouseMove="Item_MouseMove">
                            <TextBlock Text="{Binding}"/>
                        </Grid>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
        </Grid>
    </Window>
    
[/code]

MainWindow.xaml.cs

[code]

    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;
    using System.Windows;
    using System.Windows.Input;
    
    namespace Work
    {
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
                this.DataContext = this;
            }
    
            public List<string> Items { get; set; } = Enumerable.Range(1, 100).Select(e => $"Item.{e:0000}").ToList();
    
            private void ListBox_DragEnter(object sender, DragEventArgs e)
            {
                Debug.WriteLine("DragEnter");
            }
    
            private void ListBox_DragLeave(object sender, DragEventArgs e)
            {
                Debug.WriteLine("DragLeave");
            }
    
            private void ListBox_PreviewDragOver(object sender, DragEventArgs e)
            {
                Debug.WriteLine("PreviewDragOver");
                e.Effects = DragDropEffects.None;
                e.Handled = true;
            }
    
            private void Item_MouseMove(object sender, MouseEventArgs e)
            {
                if (e.LeftButton == MouseButtonState.Pressed)
                {
                    Debug.WriteLine("DoDragDrop");
                    DragDrop.DoDragDrop((DependencyObject)sender, "FooBar", DragDropEffects.All);
                }
            }
        }
    }
    
[/code]


CC BY-SA 4.0
2018-07-06T05:53:59.880
45355
2018-07-13T17:20:53.080
14817
question
c# .net wpf
WPFのListBoxのDragEnter,DragLeaveの挙動について


> Q1. どうしてこのような挙動になってしまうのでしょうか。

仕様のようです。ドロップターゲットの出入りではなく、ドロップターゲット上で動作している表示要素の出入りで発生します。

> Q2.
> ListBoxの出入りでのみDragEnter,DragLeaveを発生させ、ListBox内ではDragOverイベントのみ発生させるようにするにはどうしたらよいのでしょうか。

上記仕様のため、難しそうです。


CC BY-SA 4.0
2018-07-13T17:20:53.080
45592
2018-07-13T17:20:53.080
14817
45355
answer