【问题标题】:RichTextBox Help saving *custom* linksRichTextBox 帮助保存*自定义*链接
【发布时间】:2012-05-02 02:01:24
【问题描述】:

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

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

我正在考虑调整我的方法,使其更符合this issue,但如果我能找到保存自定义超链接的方法,我不想改变一切。

任何建议都会很棒!

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

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

【问题讨论】:

  • 您是保存数据以通过同一个界面加载,还是通过另一个界面加载?
  • 同一个界面。我最终 reg-Ex 根据加载的关键字列表检查我的 rtb。这适用于较小的文本,但推送时需要几秒钟的时间,这会冻结应用程序。我不认为我的应用程序会被推到这个限制,如果它确实是一个很好的功能,但不是必需的。

标签: c# hyperlink richtextbox customization


【解决方案1】:

由于这是一个老帖子,我将其发布仅供参考:

这是在CodeProject 上同一篇文章的comments 中找到的(有点)最近的解决方案:

代码:

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

例如:

保存:

一些保存 var = richtext.rtf

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

加载回

richtext.rtf = 某些流获取 rtf

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

【讨论】:

    【解决方案2】:

    总而言之,富文本框不会在 .Rtf 字段中保存超链接(也不是文本)。显示的值被保存,但不是实际的链接。似乎对 RTB 恕我直言的限制很差。

    有一些方法可以解决这种情况,创建自定义链接,例如 this fellow did,或者在加载搜索关键字时重新评估您的数据(我采取的方法是因为数据永远不会太大而导致冻结)。

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

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

    【讨论】:

    • richtextbox 将超链接保存在 RTF 属性中...已测试。
    【解决方案3】:

    嗯,另一个问题是,hyperlink 被“保存”了,但是点击事件和目标却丢失了...... 仅恢复格式和行为(光标更改)。 如果你对这个恢复的文本块进行操作,它就会变得一团糟。 所以在进行任何“恢复”操作之前,您需要清除 &lt;hyperlink&gt; 的东西。

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

    干杯,斯蒂芬

    【讨论】:

      【解决方案4】:

      由于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/

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-04-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-21
        • 2021-08-07
        • 1970-01-01
        相关资源
        最近更新 更多