如何将文件拖放到列表框内的WPF图像控件

时间:2012-09-11 14:11:09

标签: .net wpf xaml

我有一个带有这个xaml的WPF窗口:

<Window x:Class="WpfApplication2.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">

    <Window.Resources>
        <Style TargetType="Border" x:Key="BorderStyle">
            <Setter Property="BorderBrush" Value="Black"/>
            <Setter Property="BorderThickness" Value="1"/>
        </Style>
        <Style TargetType="Image" x:Key="ImageStyle">
            <Setter Property="Height" Value="75"/>
            <Setter Property="Width" Value="75"/>
            <Setter Property="AllowDrop" Value="True"/>
        </Style>
    </Window.Resources>
    <Grid>
        <GroupBox>
            <Grid>
                <ListBox x:Name="listbox">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Horizontal" >
                                <TextBlock Text="{Binding}"/>
                                <Border Style="{StaticResource BorderStyle}">
                                    <Image Style="{StaticResource ImageStyle}" Drop="ThisDrop"/>
                                </Border>
                                <Border Style="{StaticResource BorderStyle}">
                                    <Image Style="{StaticResource ImageStyle}" Drop="ThatDrop"/>
                                </Border>
                            </StackPanel>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
            </Grid>
        </GroupBox>
    </Grid>
</Window>

这个代码背后:

using System.Linq;

namespace WpfApplication2
{
    public partial class MainWindow
    {
        public MainWindow()
        {
            InitializeComponent();
            listbox.ItemsSource = Enumerable.Range(1, 3);
        }

        private void ThisDrop(object sender, System.Windows.DragEventArgs e)
        {
            // do something
        }

        private void ThatDrop(object sender, System.Windows.DragEventArgs e)
        {
            // do something else
        }
    }
}

当我从Windows资源管理器拖放图像控件上的文件时,我很难将这些丢弃事件触发。

项目: https://github.com/ronnieoverby/WpfApplication2

4 个答案:

答案 0 :(得分:1)

看起来问题是图像控制源尚未设置。

答案 1 :(得分:0)

这是一个基本的拖放操作:

private void Image_DragEnter(object sender, DragEventArgs e)
{
    if (e.Data.GetDataPresent(DataFormats.FileDrop))
    {
        // Signal the user they can copy files here
        e.Effects = DragDropEffects.Copy;
        e.Handled = true;
    }
}

private void Image_Drop(object sender, DragEventArgs e)
{
    string[] fileList = e.Data.GetData(DataFormats.FileDrop) as string[];

    if (fileList != null)
    {
        foreach (string file in fileList)
        {
            // Do stuff
        }

        e.Handled = true;
    }
}

我通常实现DragOver并让DragEnter只调用DragOver,因为我有时会发现DragEnter事件并不总是触发。但那是使用Windows Forms,可能不是WPF所必需的。

设置DragDropEffects会做两件事。它会更改图标,以便用户可以直观地了解将要发生的事情(复制,移动等)。它还告诉调用者(启动拖放的应用程序)发生的事情,因此它知道如何反应。例如,对于移动操作,它可能会删除原始文件。

您可以使用e.AllowedEffects查看调用者应用程序支持的效果。例如,它可能不支持移动,只支持复制。这取决于两端的开发人员,以确保他们的应用程序符合链接,移动和复制的惯例。就API而言,它仅影响向用户显示的图标。

答案 2 :(得分:0)

试试这个:

<ListBox>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <!-- Using a StackPanel here since DataTemplate can't contain more than one element-->
            <StackPanel Orientation="Horizontal">
                <Image AllowDrop="True" Drop="ImageDrop1"/>
                <Image AllowDrop="True" Drop="ImageDrop2"/>
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

以下是Drop事件处理程序

private void ImageDrop1(object sender, DragEventArgs e)
{
    MessageBox.Show("Dropped onto Image 1");
    e.Handled = true;
}

private void ImageDrop2(object sender, DragEventArgs e)
{
    MessageBox.Show("Dropped onto Image 2");
    e.Handled = true;
}

答案 3 :(得分:0)

也许你应该创建一个AttachedProperty,它可以在这个命令中放置一个ICommand,然后(在视图模型中)来放置代码;在附加属性内部订阅OnDrag事件并执行ICommand,然后在视图(图像)中将附加属性绑定到命令。