C# Windows 窗体 : Drop a picture into a WPF RichTextBox (in ElementHost)

标签 c# image richtextbox drag elementhost

我有一个 C# Windows 窗体项目,窗体上带有 WPF RichTextBox(在 ElementHost 中),并且想要将图片从资源管理器 (Windows 7 x64) 拖放到其中,但光标仅显示不允许的符号。这是我的代码:

    private void Form1_Load(object sender, EventArgs e)
    {
        this.AllowDrop = true;
        elementHost1.AllowDrop = true;
    }

    public UserControl1()
    {
        InitializeComponent();
        Background = System.Windows.Media.Brushes.Transparent;
        this.AllowDrop = true;
        richTextBox1.AllowDrop = true;
    }

使用设计器订阅事件。他们都没有被解雇:

    private void richTextBox1_DragEnter(object sender, DragEventArgs e)
    {
        MessageBox.Show("Test");
    }

    private void richTextBox1_DragLeave(object sender, DragEventArgs e)
    {
        MessageBox.Show("Test");
    }

    private void richTextBox1_DragOver(object sender, DragEventArgs e)
    {
        MessageBox.Show("Test");
    }

    private void richTextBox1_Drop(object sender, DragEventArgs e)
    {
        MessageBox.Show("Test");
    }

如果我使用 Windows 窗体 RichTextBox 是可行的,但我需要 WPF RichTextBox:

    private void Form1_Load(object sender, EventArgs e)
    {
        richTextBox1.AllowDrop = true;
        richTextBox1.DragDrop += new DragEventHandler(richTextBox1_DragDrop);
    }

    private void richTextBox1_DragDrop(object sender, EventArgs e)
    {
        MessageBox.Show("Test");
    }

最佳答案

您需要使用 PreviewDragEnterPreviewDragOverPreviewDrop 事件:

    public Window1()
    {
        InitializeComponent();

        // mainRTB is the name of my RichTextBox.

        mainRTB.PreviewDragEnter += new DragEventHandler(mainRTB_PreviewDragEnter);

        mainRTB.PreviewDragOver += new DragEventHandler(mainRTB_PreviewDragEnter);

        mainRTB.PreviewDrop += new DragEventHandler(mainRTB_PreviewDrop);

        mainRTB.AllowDrop = true;
    }

    static bool IsImageFile(string fileName)
    {
        return true;  // REPLACE THIS STUB WITH A REAL METHOD.
    }

    void mainRTB_PreviewDrop(object sender, DragEventArgs e)
    {
        if (e.Data.GetDataPresent(DataFormats.FileDrop))
        {
            // Note that you can have more than one file.
            string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
            if (files != null && files.Length > 0)
            {
                // Filter out non-image files
                if (mainRTB.Document.PasteImageFiles(mainRTB.Selection, files.Where(IsImageFile)))
                    e.Handled = true;
            }
        }
    }

    void mainRTB_PreviewDragEnter(object sender, DragEventArgs e)
    {
        string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
        // Filter out non-image files
        if (files != null && files.Length > 0 && files.Where(IsImageFile).Any())
        {
            // Consider using DragEventArgs.GetPosition() to reposition the caret.
            e.Handled = true;
        }
    }

然后以下方法将图像粘贴到当前选择范围内:

    public static bool PasteImageFiles(this FlowDocument doc, TextRange selection, IEnumerable<string> files)
    {
        // Assuming you have one file that you care about, pass it off to whatever
        // handling code you have defined.
        FlowDocument tempDoc = new FlowDocument();
        Paragraph par = new Paragraph();
        tempDoc.Blocks.Add(par);

        foreach (var file in files)
        {
            try
            {
                BitmapImage bitmap = new BitmapImage(new Uri(file));
                Image image = new Image();
                image.Source = bitmap;
                image.Stretch = Stretch.None;

                InlineUIContainer container = new InlineUIContainer(image);
                par.Inlines.Add(container);
            }
            catch (Exception)
            {
                Debug.WriteLine("\"file\" was not an image");
            }
        }

        if (par.Inlines.Count < 1)
            return false;

        try
        {
            var imageRange = new TextRange(par.Inlines.FirstInline.ContentStart, par.Inlines.LastInline.ContentEnd);
            using (var ms = new MemoryStream())
            {
                string format = DataFormats.XamlPackage;

                imageRange.Save(ms, format, true);
                ms.Seek(0, SeekOrigin.Begin);
                selection.Load(ms, format);

                return true;
            }
        }
        catch (Exception)
        {
            Debug.WriteLine("Not an image");
            return false;
        }
    }
}

顺便说一句,此方法避免使用剪贴板将图像粘贴到 RichTextBox 中 - 有时人们会看到这样做,但它并不理想。

您可能希望将图像拖放到当前放置位置,而不是粘贴当前选择。如果是这样,请从以下开始:Get the mouse position during drag and drop这是:How can I insert an image into a WPF RichTextBox at runtime in between text so the text floats around the image

关于C# Windows 窗体 : Drop a picture into a WPF RichTextBox (in ElementHost),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25963244/

相关文章:

c# - 路径上的Window.DataContext错误不能为null

java - 如何将灰度图像的输入流转换为二进制?

php - 使用 PHP 函数 include() 包含一个 png 图像

javascript - CKEditor 和 Wiki 标记(自定义数据处理器?)

c# - 当用户在 richtextbox 中输入时,我可以使用 WPF 进行自动单词替换吗

c# - PHP 控制 C# 应用程序的 MySQL 数据库

c# - 在 .net 中针对来自 visual studio 测试客户端的不同机器对 WCF 进行单元和性能测试的最佳方法是什么

c# - 在 C# 中,如果类或方法未标记为密封或虚拟,那是什么?

Java创建和读取不同的RGB像素值

c# - RichTextBox 粘贴限制为 32k 个字符?