使用VirtualFileDataObject在WPF中实现虚拟文件删除



我正在使用此项目的解决方案:http://dlaa.me/blog/post/9913083#comment-2930777923

我想让我的WPF程序能够处理虚拟文件掉入其中,但是我坚持阅读MemoryStream中的相关数据,我从DrageVentargs e.data.getData((中收到的内容。

我读了很多帖子。最接近的是:

  • https://blogs.msdn.microsoft.com/delay/2009/11/11/04/creating-something-something-from-nothing-nothing-ashonchronely-developer-frright-frright-firlight-firtual-firtual-firle-file-file-for-for-net-net-net-impreved-net-mimpreve-10040454
  • https://www.codeproject.com/articles/23139/transferring-virtual-files-to-windows-ecplorer-in
  • 和上述,当然
  • 和许多其他人拖动本地文件,显然无济于事

,但所有这些都仅处理我的应用程序对文件系统案例。

没有任何花哨的MVVM东西...

我没有进一步的地方是

private void Label_Drop(object sender, DragEventArgs e){...}

我的代码中的方法背后:

using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows;
using System.Windows.Input;
using Delay;
using System.Runtime.Serialization.Formatters.Binary;
namespace VirtualFileDataObjectDemo
{
    public partial class Window1 : Window
    {
        private static TextWriterTraceListener traceListener;
        private string logPath;
        private string filePath;
        // From Windows SDK header files
        private const string CFSTR_INETURLA = "UniformResourceLocator";
        public Window1()
        {
            //logPath = Path.Combine(@"d:Temp", @"LogTextWriterOutput.log");
            logPath = Path.Combine(Directory.GetCurrentDirectory(), @"LogTextWriterOutput.log");
            filePath = Path.Combine(Directory.GetCurrentDirectory(), @"Log");
            traceListener = new TextWriterTraceListener(logPath, "traceListener");
            InitializeComponent();
            // Attach to interesting events
            Text.MouseLeftButtonDown += new MouseButtonEventHandler(Text_MouseButtonDown);
            Text.MouseRightButtonDown += new MouseButtonEventHandler(Text_MouseButtonDown);
            TextUrl.MouseLeftButtonDown += new MouseButtonEventHandler(TextUrl_MouseButtonDown);
            TextUrl.MouseRightButtonDown += new MouseButtonEventHandler(TextUrl_MouseButtonDown);
            VirtualFile.MouseLeftButtonDown += new MouseButtonEventHandler(VirtualFile_MouseButtonDown);
            VirtualFile.MouseRightButtonDown += new MouseButtonEventHandler(VirtualFile_MouseButtonDown);
            MoreVirtualFiles.MouseLeftButtonDown += new MouseButtonEventHandler(TextUrlVirtualFile_MouseButtonDown);
            MoreVirtualFiles.MouseRightButtonDown += new MouseButtonEventHandler(TextUrlVirtualFile_MouseButtonDown);
        }
        private void Text_MouseButtonDown(object sender, MouseButtonEventArgs e) //TEXT
        {
            var virtualFileDataObject = new VirtualFileDataObject();
            // Provide simple text (in the form of a NULL-terminated ANSI string)
            virtualFileDataObject.SetData(
                (short)(DataFormats.GetDataFormat(DataFormats.Text).Id),
                Encoding.Default.GetBytes("This is some sample text"));
            DoDragDropOrClipboardSetDataObject(e.ChangedButton, Text, virtualFileDataObject, DragDropEffects.Copy);
        }
        private void TextUrl_MouseButtonDown(object sender, MouseButtonEventArgs e) //WEBADDRESS
        {
            var virtualFileDataObject = new VirtualFileDataObject();
            // Provide simple text and an URL in priority order
            // (both in the form of a NULL-terminated ANSI string)
            virtualFileDataObject.SetData(
                (short)(DataFormats.GetDataFormat(CFSTR_INETURLA).Id),
                Encoding.Default.GetBytes("http://blogs.msdn.com/delay/"));
            virtualFileDataObject.SetData(
                (short)(DataFormats.GetDataFormat(DataFormats.Text).Id),
                Encoding.Default.GetBytes("http://blogs.msdn.com/delay/"));
            DoDragDropOrClipboardSetDataObject(e.ChangedButton, TextUrl, virtualFileDataObject, DragDropEffects.Copy);
        }
        private void VirtualFile_MouseButtonDown(object sender, MouseButtonEventArgs e) //VIRTUALFILE
        {
            var virtualFileDataObject = new VirtualFileDataObject(
                null,
                (vfdo) =>
                {
                    if (DragDropEffects.Move == vfdo.PerformedDropEffect)
                    {
                        // Hide the element that was moved (or cut)
                        // BeginInvoke ensures UI operations happen on the right thread
                        Dispatcher.BeginInvoke((Action)(() => VirtualFile.Visibility = Visibility.Hidden));
                    }
                });
            // Provide a virtual file (generated on demand) containing the letters 'a'-'z'
            virtualFileDataObject.SetData(new VirtualFileDataObject.FileDescriptor[]
            {
                new VirtualFileDataObject.FileDescriptor
                {
                    Name = "Alphabet.txt",
                    Length = 26,
                    ChangeTimeUtc = DateTime.Now.AddDays(-1),
                    StreamContents = stream =>
                        {
                            var contents = Enumerable.Range('a', 26).Select(i => (byte)i).ToArray();
                            stream.Write(contents, 0, contents.Length);
                        }
                },
            });
            DoDragDropOrClipboardSetDataObject(e.ChangedButton, TextUrl, virtualFileDataObject, DragDropEffects.Move | DragDropEffects.Copy);
        }
        private void TextUrlVirtualFile_MouseButtonDown(object sender, MouseButtonEventArgs e) //ALL THREE TOGETHER
        {
            var virtualFileDataObject = new VirtualFileDataObject(
                  // BeginInvoke ensures UI operations happen on the right thread
                  (vfdo) => Dispatcher.BeginInvoke((Action)(() => BusyScreen.Visibility = Visibility.Visible)),
                  (vfdo) => Dispatcher.BeginInvoke((Action)(() => BusyScreen.Visibility = Visibility.Collapsed)));

            virtualFileDataObject.SetData(new VirtualFileDataObject.FileDescriptor[]
            {
                new VirtualFileDataObject.FileDescriptor
                {
                    Name = "Example.xml",
                    StreamContents = stream =>
                        {
                            using(var webClient = new WebClient())
                            {
                                var data = webClient.DownloadData("https://www.w3schools.com/xml/note.xml");
                                stream.Write(data, 0, data.Length);
                            }
                        }
                },
                new VirtualFileDataObject.FileDescriptor
                {
                    Name = "Example2.xml",
                    StreamContents = stream =>
                        {
                            using(var webClient = new WebClient())
                            {
                                var data = webClient.DownloadData("https://www.w3schools.com/xml/cd_catalog.xml");
                                stream.Write(data, 0, data.Length);
                            }
                        }
                },
                new VirtualFileDataObject.FileDescriptor
                {
                    Name = "Example3.xml",
                    StreamContents = stream =>
                        {
                            using(var webClient = new WebClient())
                            {
                                var data = webClient.DownloadData("https://www.w3schools.com/xml/plant_catalog.xml");
                                stream.Write(data, 0, data.Length);
                            }
                        }
                },
            });
            DoDragDropOrClipboardSetDataObject(e.ChangedButton, MoreVirtualFiles, virtualFileDataObject, DragDropEffects.Move | DragDropEffects.Copy);
        }
        private static void DoDragDropOrClipboardSetDataObject(MouseButton button, DependencyObject dragSource, VirtualFileDataObject virtualFileDataObject, DragDropEffects allowedEffects)
        {
            try
            {
                if (button == MouseButton.Left)
                {
                    // Left button is used to start a drag/drop operation
                    VirtualFileDataObject.DoDragDrop(dragSource, virtualFileDataObject, allowedEffects);
                }
                else if (button == MouseButton.Right)
                {
                    // Right button is used to copy to the clipboard
                    // Communicate the preferred behavior to the destination
                    virtualFileDataObject.PreferredDropEffect = allowedEffects;
                    Clipboard.SetDataObject(virtualFileDataObject);
                }
            }
            catch (COMException ce)
            {
                traceListener.WriteLine("COM Exception");
                traceListener.WriteLine(ce);
                traceListener.WriteLine(ce.Message);
                traceListener.WriteLine(ce.InnerException);
                // Failure; no way to recover
            }
        }
        private void Label_Drop(object sender, DragEventArgs e)
        {
            try
            {
            dropLabel.Content = "";
            string[] retrievedFormats = e.Data.GetFormats();
            foreach (string retFormat in retrievedFormats)
            {
                object retrievedData = e.Data.GetData(retFormat);
                dropLabel.Content = dropLabel.Content + Environment.NewLine + retrievedData.ToString() + " - " + retFormat;
            }
        }
            catch (Exception ex)
            {
                traceListener.WriteLine("-------------");
                traceListener.WriteLine(ex + Environment.NewLine);
                traceListener.WriteLine(ex.Message + Environment.NewLine);
                traceListener.WriteLine(ex.StackTrace + Environment.NewLine);
                traceListener.WriteLine("-------------");
                traceListener.Flush();
            }
}

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

和XAML:

<Window x:Class="VirtualFileDataObjectDemo.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="VirtualFileDataObjectDemo"
    Height="800"
    Width="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="auto"/>
        </Grid.RowDefinitions>
        <UniformGrid
            Rows="5"
            Background="#ffdddddd"
            TextElement.FontSize="22"
            TextElement.FontWeight="Bold">
            <UniformGrid.Resources>
                <Style TargetType="{x:Type Label}">
                    <Setter Property="Background" Value="Orange"/>
                    <Setter Property="Foreground" Value="White"/>
                    <Setter Property="BorderBrush" Value="Black"/>
                    <Setter Property="BorderThickness" Value="1"/>
                    <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
                    <Setter Property="VerticalContentAlignment" Value="Center"/>
                    <Setter Property="Margin" Value="10"/>
                </Style>
            </UniformGrid.Resources>
            <ContentControl
                Content="Drag an item or right-click to copy it:"
                FontSize="18"
                VerticalAlignment="Center"
                Margin="20"/>
            <Label
                x:Name="Text"
                Content="Text only"/>
            <Label
                x:Name="TextUrl"
                Content="Text and URL"/>
            <Label
                x:Name="VirtualFile">
                <DockPanel>
                    <ContentControl
                        Content="Virtual file"
                        DockPanel.Dock="Left"
                        VerticalAlignment="Center"/>
                    <ContentControl
                        Content="[Drag moves; paste cuts]"
                        FontSize="14"
                        HorizontalAlignment="Right"
                        VerticalAlignment="Center"/>
                </DockPanel>
            </Label>
            <Label
                x:Name="MoreVirtualFiles"
                Content="More virtual files"/>
        </UniformGrid>
        <Grid
            x:Name="BusyScreen"
            Background="LightGray"
            Visibility="Collapsed">
            <StackPanel
                VerticalAlignment="Center"
                Margin="50">
                <Viewbox>
                    <TextBlock Text="Busy..."/>
                </Viewbox>
                <ProgressBar IsIndeterminate="True" Height="20"/>
            </StackPanel>
        </Grid>
        <Label Name="dropLabel" Grid.Row="1" Content="Drop Area" MinHeight="50" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" FontSize="20" AllowDrop="True" Drop="Label_Drop" DragEnter="Label_DragEnter"/>
    </Grid>
</Window>

可以从这里下载VirtualFileDataObject:http://dlaa.me/samples/virtualfiledataobjectdemo/virtualfiledataobjectDemo.zip

感谢詹姆斯·巴拉斯(James Barrass(。他在此主题上的解决方案:

丢弃的zip文件会导致e.data.getdata(" filecontents; quot; quot(抛出异常

解决了我的问题。

最新更新