【解決方法】WPF リッチテキスト ボックスのハイパーリンクの検出


こんにちは、私は WPF リッチテキストボックスの開発を始めましたが、Windows リッチテキストボックスのような自動 URL 検出などの機能がないようです。 リッチテキストボックス(wpf)にデータを貼り付けるときにハイパーリンクを検出するのに助けが必要です。 www.google.com と入力し、「m」の後にスペースキーまたは Enter キーを押したときなど、入力された単語で正常に機能するコードブロックをすでにいくつか見つけました。 「www.google.com」は、遡って前のスペースをチェックするか、ハイパーリンクを入力して検出し、ハイパーリンクにします。

次のコードを使用して作業しました

[^]

ほとんどの場合は正常に機能しますが、私の問題は、すべての文字を走査した後にリンクに移動することであり、大量のデータがある場合、これはより良い解決策ではないことです。 また、複数の段落では機能しません。

次の関数を使用して、リンクワードに直接ジャンプしてそれを検出し、ハイパーリンクにする別のオプションを試しました

ここでの match は、URL のすべての一致を含む一致コレクションです。
ここでは次の正規表現値を使用しました
“(?<=\w{1})?(((ht|f)tp(s?))\://)?(www.[a-zA-Z]。)[a-zA-Z0-9\-\.]+\.(com|edu|gov|mil|net|org|biz|info|name|museum|us|ca|uk)(\:[0-9]+)*(/($|[a-zA-Z0-9\.\,\;\?\'\\\+&amp;%\$#\=~_\-]+))*" GetPositionAtOffset(match.index, LogicalDirection.Forward) そして要点を理解する
しかし、次のエラーが発生します。

1) ハイパーリンクは他のハイパーリンクの境界内に存在できません (catch ブロックでキャッチできるため、大きな問題はありません)

誰かがテキストを貼り付けるときにURLを検出するのを手伝ってくれませんか。

2 )エラーコード0x80131623(Googleで検索すると詳細が見つかります)、私にとっては非常に困難です。

(文法や英語の間違いについては本当に申し訳ありません)
ありがとう

解決策 2

もしかしたらここで何か助けになるかもしれません…

RichTextBox のハイパーリンクの自動検出 – パート I[^]
RichTextBox のハイパーリンクの自動検出 – パート II[^]

*編集* あるいは、そうではないかもしれません…URLを検出する方法ではなく、正規表現のヘルプが必要のようです…:)

解決策 1

richtextbox の detecturl プロパティが true に設定されていることを確認する必要があると思います。

次のリンクを見てください

http://msdn.microsoft.com/en-us/library/system.windows.forms.richtextbox.detecturls.aspx[^]

これがお役に立てば幸いです。


AJ

解決策 3

私は数か月間、断続的にこの問題に悩まされてきました。 今日はBing Chatにその方法を聞いてみることにしました。 私は Bing に次の指示を出しました。 WPF アプリケーションで .net RichTextBox コントロールを拡張する C# コードを記述して、URL をクリックできるようにします。

Bing は次の解決策を提供しました…

————————————————– ————————-

C# を使用して WPF アプリケーションで .NET RichTextBox コントロールを拡張し、URL をクリック可能にするには、TextPointer クラスを使用してテキスト内の URL の開始位置と終了位置を見つけることができます。 次に、RichTextBox コントロールの拡張メソッドを作成する方法の例を示します。

C#
public static class RichTextBoxExtensions
{
    public static void MakeUrlsClickable(this RichTextBox self)
    {
        TextPointer pointer = self.Document.ContentStart;
        while (pointer != null)
        {
            if (pointer.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text)
            {
                string textRun = pointer.GetTextInRun(LogicalDirection.Forward);
                MatchCollection matches = Regex.Matches(textRun, @"(https?://[^\s]+)");
                foreach (Match match in matches)
                {
                    TextPointer start = pointer.GetPositionAtOffset(match.Index);
                    TextPointer end = start.GetPositionAtOffset(match.Length);
                    Hyperlink hyperlink = new Hyperlink(start, end);
                    hyperlink.NavigateUri = new Uri(match.Value);
                }
            }
            pointer = pointer.GetNextContextPosition(LogicalDirection.Forward);
        }
    }
}

その後、WPF アプリケーションの任意の RichTextBox コントロールでこのメソッドを使用できるようになります。 たとえば、myRichTextBox という名前の RichTextBox コントロールがある場合、次のように MakeUrlsClickable 拡張メソッドを呼び出すことができます。

C#
myRichTextBox.MakeUrlsClickable();

————————————————– ————————-

この答えで80%解決できました。 そのコードに加えて、XAML コードにセッターを適切に追加し、さらにそのセッター用のコードを追加する必要があります。

そこで、Bing のコードをいじった後、最終的に実装したものが次のとおりです。

————————————————– ————————-

XAML コードでは次のようになります。

XAML
<RichTextBox>
    <RichTextBox.Resources>
        <Style TargetType="Hyperlink">
            <Setter Property="Cursor" Value="Hand" />
            <EventSetter Event="MouseLeftButtonDown" Handler="Hyperlink_MouseLeftButtonDown" />
        </Style>
    </RichTextBox.Resources>
</RichTextBox>

背後のコードでは次のようになります。

C#
private void Hyperlink_MouseLeftButtonDown(object sender, MouseEventArgs e)
        {
            var hyperlink = (Hyperlink)sender;
            Process.Start(new ProcessStartInfo(hyperlink.NavigateUri.ToString())
            {
                UseShellExecute = true,
            });
            e.Handled = true;
        }

RichTextBox コントロールの拡張機能:

C#
namespace RichTextBoxExtensions
{
    public static class RichTextBoxExtensions
    {
        /// <summary>
        /// Scan the content of a RichTextBox control and make any https URLs
        /// clickable.  The initial version of this method was written by Bing Chat,
        /// and then tidied up by me and Intellicode.
        /// </summary>
        /// <param name="self"></param>
        public static void MakeUrlsClickable(this RichTextBox self)
        {
            TextPointer pointer = self.Document.ContentStart;
            while (pointer != null)
            {
                if (pointer.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text)
                {
                    string textRun = pointer.GetTextInRun(LogicalDirection.Forward);
                    MatchCollection matches = Regex.Matches(textRun, @"(https?://[^\s]+)");
                    foreach (Match match in matches.Cast<Match>())
                    {
                        TextPointer start = pointer.GetPositionAtOffset(match.Index);
                        TextPointer end = start.GetPositionAtOffset(match.Length);
                        Hyperlink hyperlink = new(start, end)
                        {
                            NavigateUri = new Uri(match.Value)
                        };
                    }
                }
                pointer = pointer.GetNextContextPosition(LogicalDirection.Forward);
            }
        }
}

myRichTextBox という名前の RichTextBox コントロールがある場合は、次のように MakeUrlsClickable 拡張メソッドを呼び出すことができます。

C#
myRichTextBox.MakeUrlsClickable();

コメント

タイトルとURLをコピーしました