2014-09-21 34 views
2

폼에 WPF RichTextBox (ElementHost)가있는 # Windows Forms 프로젝트가 있고 끌어 놓기 위해 & 탐색기에서 그림을 놓습니다 (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"); 
    } 

나는 윈도우를 RichTextBox는 작품이다 양식 사용,하지만 난이 WPF를 RichTextBox해야하는 경우 :

당신은 PreviewDragEnter, PreviewDragOverPreviewDrop 이벤트를 사용할 필요가
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

:

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