【问题标题】:C# Windows Forms: Drop a picture into a WPF RichTextBox (in ElementHost)C# Windows 窗体:将图片拖放到 WPF RichTextBox 中(在 ElementHost 中)
【发布时间】:2014-09-21 19:54:17
【问题描述】:

我有一个 c# Windows Forms 项目,表单上有一个 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");
    }

【问题讨论】:

    标签: c# image richtextbox drag elementhost


    【解决方案1】:

    您需要使用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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-11-08
      • 1970-01-01
      • 2015-07-24
      • 1970-01-01
      • 2011-11-05
      • 2011-04-25
      • 1970-01-01
      相关资源
      最近更新 更多