如何:打开放置在 RichTextBox 控件上的文件

在 Windows Presentation Foundation(WPF)中,TextBoxRichTextBoxFlowDocument 控件都具有内置的拖放功能。 内置功能可在控件之间和控件之间拖放文本。 但是,它不支持将文件拖放到控件上来打开文件。 这些控件还会将拖放事件标记为已处理。 因此,默认情况下,无法添加自己的事件处理程序来提供打开已删除文件的功能。

若要在这些控件中添加拖放事件的其他处理,请使用 AddHandler(RoutedEvent, Delegate, Boolean) 方法为拖放事件添加事件处理程序。 将参数 handledEventsToo 设置为 true,以便即使某个路由事件已被事件路由中的其他元素标记为已处理,也可以调用指定的处理程序。

小窍门

可以通过处理拖放事件的预览版本并将预览事件标记为已处理来取代 TextBoxRichTextBoxFlowDocument 的内置拖放功能。 但是,这将禁用内置的拖放功能,不建议这样做。

示例:

以下示例演示如何在 DragOver上为 DropRichTextBox 事件添加处理程序。 此示例使用 AddHandler(RoutedEvent, Delegate, Boolean) 方法并将 handledEventsToo 参数设置为 true,以便即使 RichTextBox 将这些事件标记为已处理,也会调用事件处理程序。 事件处理程序中的代码添加了打开拖放到 RichTextBox 上的文本文件的功能。

若要测试此示例,请将文本文件或 RTF(富文本格式)文件从 Windows 资源管理器拖动至 RichTextBox。 该文件将在 RichTextBox 中打开。 如果在删除文件之前按 Shift 键,该文件将作为纯文本打开。

<RichTextBox x:Name="richTextBox1"
             AllowDrop="True" />
public MainWindow()
{
    InitializeComponent();

    // Add using System.Windows.Controls;
    richTextBox1.AddHandler(RichTextBox.DragOverEvent, new DragEventHandler(RichTextBox_DragOver), true);
    richTextBox1.AddHandler(RichTextBox.DropEvent, new DragEventHandler(RichTextBox_Drop), true);
}

private void RichTextBox_DragOver(object sender, DragEventArgs e)
{
    if (e.Data.GetDataPresent(DataFormats.FileDrop))
    {
        e.Effects = DragDropEffects.All;
    }
    else
    {
        e.Effects = DragDropEffects.None;
    }
    e.Handled = false;
}

private void RichTextBox_Drop(object sender, DragEventArgs e)
{
    if (e.Data.GetDataPresent(DataFormats.FileDrop))
    {
        string[] docPath = (string[])e.Data.GetData(DataFormats.FileDrop);

        // By default, open as Rich Text (RTF).
        var dataFormat = DataFormats.Rtf;

        // If the Shift key is pressed, open as plain text.
        if (e.KeyStates == DragDropKeyStates.ShiftKey)
        {
            dataFormat = DataFormats.Text;
        }

        System.Windows.Documents.TextRange range;
        System.IO.FileStream fStream;
        if (System.IO.File.Exists(docPath[0]))
        {
            try
            {
                // Open the document in the RichTextBox.
                range = new System.Windows.Documents.TextRange(richTextBox1.Document.ContentStart, richTextBox1.Document.ContentEnd);
                fStream = new System.IO.FileStream(docPath[0], System.IO.FileMode.OpenOrCreate);
                range.Load(fStream, dataFormat);
                fStream.Close();
            }
            catch (System.Exception)
            {
                MessageBox.Show("File could not be opened. Make sure the file is a text file.");
            }
        }
    }
}
Public Sub New()
    InitializeComponent()

    richTextBox1.AddHandler(RichTextBox.DragOverEvent, New DragEventHandler(AddressOf RichTextBox_DragOver), True)
    richTextBox1.AddHandler(RichTextBox.DropEvent, New DragEventHandler(AddressOf RichTextBox_Drop), True)

End Sub

Private Sub RichTextBox_DragOver(sender As Object, e As DragEventArgs)
    If e.Data.GetDataPresent(DataFormats.FileDrop) Then
        e.Effects = DragDropEffects.All
    Else
        e.Effects = DragDropEffects.None
    End If
    e.Handled = False
End Sub

Private Sub RichTextBox_Drop(sender As Object, e As DragEventArgs)
    If e.Data.GetDataPresent(DataFormats.FileDrop) Then
        Dim docPath As String() = TryCast(e.Data.GetData(DataFormats.FileDrop), String())

        ' By default, open as Rich Text (RTF).
        Dim dataFormat = DataFormats.Rtf

        ' If the Shift key is pressed, open as plain text.
        If e.KeyStates = DragDropKeyStates.ShiftKey Then
            dataFormat = DataFormats.Text
        End If

        Dim range As TextRange
        Dim fStream As IO.FileStream
        If IO.File.Exists(docPath(0)) Then
            Try
                ' Open the document in the RichTextBox.
                range = New TextRange(richTextBox1.Document.ContentStart, richTextBox1.Document.ContentEnd)
                fStream = New IO.FileStream(docPath(0), IO.FileMode.OpenOrCreate)
                range.Load(fStream, dataFormat)
                fStream.Close()
            Catch generatedExceptionName As System.Exception
                MessageBox.Show("File could not be opened. Make sure the file is a text file.")
            End Try
        End If
    End If
End Sub