富文本框帮助保存*自定义*链接



我使用此处找到的代码项目在我的 rtb 中实现了任意链接。这些链接不是真正的链接,而是在单击时查找的数据,并返回有关所单击项目的扩展信息。

这一切都很好用。 问题是当我尝试使用RichTextBox1.Rtf方法将数据保存到数据库中时,链接丢失了。 我最终得到了文本的值,但 Rtf 中没有保存链接数据。 超链接没有 Rtf 代码吗? 没有办法解决这个问题吗?

正在考虑将我的方法调整为更符合此问题的方法,但如果能找到保存自定义超链接的方法,我不想改变周围的一切。

任何建议都会很棒!

---------------更新----------------

在提交之前,我做了更多的挖掘并挖掘了这篇博客文章,其中讨论了RTB不保存超链接,所以我想我是SOL。 解决此问题的唯一方法是将文本保存在隐藏文本框中并将该版本保存到数据库中,但这种方式变得笨拙。 我想我会选择我找到的第二个选项,我想无论如何我都会发布这个,因为 StackOverflow 中的数据在这个主题上似乎很渺茫。 现在我知道为什么了。

由于这是一个旧线程,我将发布此内容仅供参考:

这是在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 时,将 getLinkPosition(( 的返回字符串保存到,当你想加载 rtf 时,只需按照你的方式加载它,然后使用来自 1st 方法的返回字符串来获取链接 bak

前任:

救:

一些保存变量=富文本.rtf

附加保存值 = 富文本.getLinkPosition((;

回装

富文本.rtf = 某些流获得 RTF

richtext.setLinkPosition(额外的保存值来自 一些流(

总而言之,富文本框不会在 中保存超链接。RTF 字段(非文本(。 保存显示的值,但不保存实际链接。 对 RTB 恕我直言,这似乎是一个糟糕的限制。

有很多方法可以解决这种情况,像这个家伙一样创建自定义链接,或者在加载搜索关键字时重新评估您的数据(我采取的路线,因为数据永远不会太大而导致冻结(。

我用来执行此操作的代码如下,并在加载时调用:

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

好吧,另一个问题是,hyperlink被"保存",但点击事件和目标丢失了......仅恢复格式和行为(光标更改(。如果你对这个恢复的文本块进行操作,一切都会搞砸。因此,在执行任何"还原"操作之前,您需要清理<hyperlink>内容。

Prajakta Joshi 做了一个自动抄送超链接的例子 - 它还包含一个清理例程:http://blogs.msdn.com/b/prajakta/archive/2006/10/17/autp-detecting-hyperlinks-in-richtextbox-part-i.aspx

干杯,斯蒂芬

由于保存时不会丢失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-fd]{2})+)+|/)+|?|#)?(?#Query)(?:(?:?(?:[-w~!$+|.,*:]|%[a-fd{2}])+=(?:[-w~!$+|.,*:=]|%[a-fd]{2})*)(?:&amp;(?:[-w~!$+|.,*:]|%[a-fd{2}])+=(?:[-w~!$+|.,*:=]|%[a-fd]{2})*)*)*(?#Anchor)(?:#(?:[-w~!$+|.,*:=]|%[a-fd]{2})*)?");

isHyperlink 是检查 URL 的另一种方法 - 代码取自:http://marcangers.com/detect-urls-add-hyperlinks-wpf-richtextbox-automatically/

希望这有帮助!干杯,斯蒂芬

最新更新