0

ここにあるCodeProjectを使用して、rtbに任意のリンクを実装しました。リンクは実際のリンクではなく、クリックされたときに検索され、クリックされたアイテムに関する拡張情報を返したデータです。

これはすべてうまくいきます。問題は、RichTextBox1.Rtfメソッドを使用してデータをデータベースに保存しようとすると、リンクが失われることです。テキストの値になりますが、Rtfに保存されたリンクデータがありません。ハイパーリンク用のRtfコードはありませんか?この問題を回避する方法はありませんか?

この問題に合わせてアプローチを調整することを検討していますが、カスタムハイパーリンクを保存する方法が見つかった場合は、すべてを変更したくありません。

どんな提案も素晴らしいでしょう!

- - - - - - - -アップデート - - - - - - - -

送信する前に、RTBがハイパーリンクを保存しないことを説明しているこのブログ記事をもう少し掘り下げて掘り下げたので、私はSOLだと思います。これを回避する唯一の方法は、非表示のテキストボックスにテキストを保存し、そのバージョンをデータベースに保存することですが、その方法は不格好になります。StackOverflowのデータはこのトピックに関してスリムに見えるので、私が見つけた2番目のオプションを使用すると思いますが、とにかくこれを投稿すると思いました。今、私はその理由を知っています。

4

4 に答える 4

1

これは古いスレッドなので、参考のために投稿します。

これがCodeProjectの同じ記事のコメントにある(やや)最近の解決策です:

コード:

/// <summary>
/// This additional code block checks the locations of links
/// and desc. it via a string which contains informations of how many links are there
/// .Split('&')-1 and the select information .Select(.Split('&')[i].Split('-')[0],.Split('&')[i].Split('-')[1])
/// After we select the links we can SetSelectionLink(true) to get our links back.
/// </summary>
public string getLinkPositions()
{
string pos = "";
for (int i = 0; i < this.TextLength; i++)
{
this.Select(i, 1);
int isLink = GetSelectionLink();
if (isLink == 1)
{
//the selected first character is a part of link, now find its last character
for (int j = i + 1; j <= this.TextLength; j++)
{
this.Select(j, 1);
isLink = GetSelectionLink();
if (isLink != 1 || j == this.TextLength)
{
//we found the last character's +1 so end char is (j-1), start char is (i)
pos += (i) + "-" + ((j - 1) - (i - 1)) + "&"; //j-1 to i but i inserted -1 one more so we can determine the right pos
i = j; //cont. from j+1
break; //exit second for cont. from i = j+1 (i will increase on new i value)
}
}
}
}
this.DeselectAll();
return pos;
}
/// <summary>
/// This method generates the links back only created via InsertLink(string text)
/// and overloaded InsertLink(string text,int position)
/// </summary>
/// <param name="pos">the pos string from getLinkPositions</param>
public void setLinkPositions(string pos)
{
string[] positions = pos.Split('&');
for (int i = 0; i < positions.Length - 1; i++)
{
string[] xy = positions[i].Split('-');
this.Select(Int32.Parse(xy[0]), Int32.Parse(xy[1]));
this.SetSelectionLink(true);
this.Select(Int32.Parse(xy[0]) + Int32.Parse(xy[1]), 0);
}
this.DeselectAll();
}

コードの使用方法[原文のまま]:

rtfを保存するときは、getLinkPositions()の戻り文字列をに保存します。rtfをロードするときは、その方法でロードしてから、1番目のメソッドからの戻り文字列を使用してリンクを取得します。

元 :

保存する:

いくつかの保存変数=richtext.rtf

追加の保存値=richtext.getLinkPositions();

ロードバック

richtext.rtf=一部のストリームがrtfを取得します

richtext.setLinkPositions(一部のストリームからの追加の保存値)

于 2014-10-01T14:30:56.017 に答える
0

要約すると、リッチテキストボックスは.Rtfフィールド(またはテキスト)にハイパーリンクを保存しません。表示の値は保存されますが、実際のリンクは保存されません。RTBのIMHOに対する制限が不十分なようです。

このケースを回避する方法はあります。この仲間が行ったようにカスタムリンクを作成するか、キーワードのロード検索でデータを再評価します(データが大きくなりすぎてフリーズすることはないため、私がたどったルート)。

これを実行するために使用したコードは次のとおりで、ロード時に呼び出されます。

            foreach (ListViewItem keyword in Keywords.Items)
            {
                System.Text.RegularExpressions.Regex oKeyword = new System.Text.RegularExpressions.Regex(@"\b" + keyword.Text + @"\b");

                foreach (System.Text.RegularExpressions.Match match in oKeyword.Matches(rtb.Text))
                {
                    int index = match.Index;
                    int length = match.Length;

                    rtb.Select(index, length);
                    //This next bit is made available through the use of http://www.codeproject.com/Articles/9196/Links-with-arbitrary-text-in-a-RichTextBox
                    rtb.InsertLink(match.Value);  
                }
            }
于 2012-05-03T00:26:23.510 に答える
0

もう1つの問題は、hyperlinkが「保存」されているが、クリックイベントとターゲットが失われることです...形式と動作(カーソルの変更)のみが復元されます。そして、この復元されたテキストのチャンクを操作すると、すべてが台無しになります。したがって、「復元」操作を実行する前に、内容をクリーンアップする必要があります<hyperlink>

Prajakta Joshiは、ハイパーリンクの自動デッティングの例を作成しました。これには、クリーンアップルーチンも含まれています:http: //blogs.msdn.com/b/prajakta/archive/2006/10/17/autp-detecting-hyperlinks-in-richtextbox-part- i.aspx

乾杯、ステファン

于 2015-09-23T20:40:30.437 に答える
0

Hyperlinkタグは保存しても失われないため、別のアプローチとして、ロードされたドキュメントでこれらのタグをスキャンし、そのプロパティ(クリックイベントとナビゲートURI)を再適用します。

void restoreHyperlinks()
{
    TextRange tr = new TextRange(_richTextBox.Document.ContentStart, _richTextBox.Document.ContentEnd);
    TextPointer tp = tr.Start;
    bool bFound = false;
    foreach (System.Text.RegularExpressions.Match match in UrlRegex.Matches(tr.Text))
    {
        if (tp == null)
            tp = tr.Start;
        bFound = false;
        while (tp != null && !bFound)
        {

            if (tp.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text)
            {
                string textRun = tp.GetTextInRun(LogicalDirection.Forward);
                int indexInRun = textRun.IndexOf(match.Value);
                if (indexInRun > -1)
                {
                    bFound = true;
                    Inline parent = tp.Parent as Inline;
                    while (parent != null && !(parent is Hyperlink))
                    {
                        parent = parent.Parent as Inline;
                    }
                    if (parent is Hyperlink)
                    {
                        Hyperlink hyperlink = (Hyperlink)parent;
                        if (isHyperlink(match.Value))
                        {
                            Uri uri = new Uri(match.Value, UriKind.RelativeOrAbsolute);
                            if (!uri.IsAbsoluteUri)
                            {
                                uri = new Uri(@"http://" + match.Value, UriKind.Absolute);
                            }
                            if (uri != null)
                            {
                                hyperlink.NavigateUri = uri;
                                hyperlink.Click += Hyperlink_Click;
                            }
                        }
                    }
               }

            }
            tp = tp.GetNextContextPosition(LogicalDirection.Forward);
        }
    }

}

正規表現は次のとおりです。

private static readonly System.Text.RegularExpressions.Regex UrlRegex = new System.Text.RegularExpressions.Regex(@"(?#Protocol)(?:(?:ht|f)tp(?:s?)\:\/\/|~/|/)?(?#Username:Password)(?:\w+:\w+@)?(?#Subdomains)(?:(?:[-\w]+\.)+(?#TopLevel Domains)(?:com|org|net|gov|mil|biz|info|mobi|name|aero|jobs|museum|travel|[a-z]{2}))(?#Port)(?::[\d]{1,5})?(?#Directories)(?:(?:(?:/(?:[-\w~!$+|.,=]|%[a-f\d]{2})+)+|/)+|\?|#)?(?#Query)(?:(?:\?(?:[-\w~!$+|.,*:]|%[a-f\d{2}])+=(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)(?:&amp;(?:[-\w~!$+|.,*:]|%[a-f\d{2}])+=(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)*)*(?#Anchor)(?:#(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)?");

isHyperlinkURLをチェックする別の方法です-コードは次の場所から取得されます:http: //marcangers.com/detect-urls-add-hyperlinks-wpf-richtextbox-automatically/

お役に立てれば!乾杯、ステファン

于 2015-09-24T13:47:51.800 に答える