2014-09-21 2 views
2

У меня есть проект Windows Forms с WPF RichTextBox (в ElementHost) в форме и вы хотите перетащить & отбросить изображение из проводника (Windows 7 x64), но курсор отображает только символ не разрешен. Это мой код:C# Windows Forms: Отбросьте изображение в WPF RichTextBox (в ElementHost)

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 Forms 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"); 
    } 

ответ

2

Вы должны использовать PreviewDragEnter, PreviewDragOver и PreviewDrop события:

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

Смежные вопросы