0

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

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

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

任何建议都会很棒!

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

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

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 时,只需按照你的方式加载它,然后使用第一种方法的返回字符串来获取链接 bak

前任 :

节省:

一些保存 var = richtext.rtf

附加保存值 =richtext.getLinkPositions();

加载回

richtext.rtf = 一些流获取 rtf

richtext.setLinkPositions(来自某个流的额外保存值)

于 2014-10-01T14:30:56.017 回答
0

总而言之,富文本框不会在 .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);  
                }
            }
于 2012-05-03T00:26:23.510 回答
0

好吧,另一个问题是,它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})*)?");

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

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

于 2015-09-24T13:47:51.800 回答