【问题标题】:Links inside rich textbox?富文本框中的链接?
【发布时间】:2012-04-08 23:06:37
【问题描述】:

我知道richtextboxes 可以检测链接(如http://www.yahoo.com),但是我有没有办法向它添加看起来像文本但实际上是链接的链接?喜欢在哪里可以选择链接的标签?例如,它不是显示为http://www.yahoo.com,而是显示为Click here to go to yahoo

编辑:忘了,我用的是windows窗体

编辑:有没有更好用的东西(因为更容易格式化)?

【问题讨论】:

  • 它是自动的。只需开始输入“www”。或“http://”和 Shazam!这是一个链接。也可以在代码中工作。使用 LinkClicked 事件来检测对它们的点击。
  • 阅读问题,“而不是显示为 http://... 它显示为单击此处...”
  • 嗯,这是一个沙赞!评论。 EM_SETPARAFORMAT 看起来很不高兴。

标签: c# winforms hyperlink richtextbox rtf


【解决方案1】:

我找到了一种可能不是最优雅的方法,但它只需几行代码就可以完成工作。即通过字体变化来模拟超链接的外观,通过检测鼠标指针的位置来模拟超链接的行为。

代码:

public partial class Form1 : Form
{
    private Cursor defaultRichTextBoxCursor = Cursors.Default;
    private const string HOT_TEXT = "click here";
    private bool mouseOnHotText = false;

    // ... Lines skipped (constructor, etc.)

    private void Form1_Load(object sender, EventArgs e)
    {
        // save the right cursor for later
        this.defaultRichTextBoxCursor = richTextBox1.Cursor;

        // Output some sample text, some of which contains
        // the trigger string (HOT_TEXT)
        richTextBox1.SelectionFont = new Font("Calibri", 11, FontStyle.Underline);
        richTextBox1.SelectionColor = Color.Blue;
        // output "click here" with blue underlined font
        richTextBox1.SelectedText = HOT_TEXT + "\n";

        richTextBox1.SelectionFont = new Font("Calibri", 11, FontStyle.Regular);
        richTextBox1.SelectionColor = Color.Black;
        richTextBox1.SelectedText = "Some regular text";
    }

    private void richTextBox1_MouseMove(object sender, MouseEventArgs e)
    {
        int mousePointerCharIndex = richTextBox1.GetCharIndexFromPosition(e.Location);
        int mousePointerLine = richTextBox1.GetLineFromCharIndex(mousePointerCharIndex);
        int firstCharIndexInMousePointerLine = richTextBox1.GetFirstCharIndexFromLine(mousePointerLine);
        int firstCharIndexInNextLine = richTextBox1.GetFirstCharIndexFromLine(mousePointerLine + 1);
        if (firstCharIndexInNextLine < 0)
        {
            firstCharIndexInNextLine = richTextBox1.Text.Length;
        }

        // See where the hyperlink starts, as long as it's on the same line
        // over which the mouse is
        int hotTextStartIndex = richTextBox1.Find(
            HOT_TEXT, firstCharIndexInMousePointerLine, firstCharIndexInNextLine, RichTextBoxFinds.NoHighlight);

        if (hotTextStartIndex >= 0 && 
            mousePointerCharIndex >= hotTextStartIndex && mousePointerCharIndex < hotTextStartIndex + HOT_TEXT.Length)
        {
            // Simulate hyperlink behavior
            richTextBox1.Cursor = Cursors.Hand;
            mouseOnHotText = true;
        }
        else
        {
            richTextBox1.Cursor = defaultRichTextBoxCursor;
            mouseOnHotText = false;
        }
        toolStripStatusLabel1.Text = mousePointerCharIndex.ToString();
    }

    private void richTextBox1_MouseClick(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left && mouseOnHotText)
        {
            // Insert your own URL here, to navigate to when "hot text" is clicked
            Process.Start("http://www.google.com");
        }
    }
}

为了改进代码,可以创建一种优雅的方式来将多个“热门文本”字符串映射到它们自己的链接 URL(可能是 Dictionary&lt;K, V&gt;)。另一个改进是继承 RichTextBox 以封装上面代码中的功能。

【讨论】:

    【解决方案2】:

    这里可以找到通过linkLabel在富文本框中添加链接的示例:

        LinkLabel link = new LinkLabel();
        link.Text = "something";
        link.LinkClicked += new LinkLabelLinkClickedEventHandler(this.link_LinkClicked);
        LinkLabel.Link data = new LinkLabel.Link();
        data.LinkData = @"C:\";
        link.Links.Add(data);
        link.AutoSize = true;
        link.Location =
            this.richTextBox1.GetPositionFromCharIndex(this.richTextBox1.TextLength);
        this.richTextBox1.Controls.Add(link);
        this.richTextBox1.AppendText(link.Text + "   ");
        this.richTextBox1.SelectionStart = this.richTextBox1.TextLength;
    

    这里是处理程序:

        private void link_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            System.Diagnostics.Process.Start(e.Link.LinkData.ToString());
        }
    

    【讨论】:

    • 这不适用于可滚动的richTextBox。链接悬停在控件上...
    • 非常感谢您提供的示例代码,即使滚动也能正常工作。我放了link.Tag = link.Location;来备份链接位置,然后在richTextBox1_VScrollrichTextBox1_HScroll上用Point p = (Point)l.Tag;l.Top = richTextBox1.GetPositionFromCharIndex(0).Y + p.Y;替换它的位置。
    【解决方案3】:

    当然可以通过在控件中调用一些 WIN32 功能来实现,但是如果您正在寻找一些标准方法,请查看这篇文章: Create hyperlink in TextBox control

    有一些关于不同集成方式的讨论。

    问候

    更新 1: 最好的方法是遵循以下方法: http://msdn.microsoft.com/en-us/library/f591a55w.aspx

    因为 RichText 框控件为“DetectUrls”提供了一些功能。然后你可以很容易地处理点击的链接:

    this.richTextBox1.LinkClicked += new System.Windows.Forms.LinkClickedEventHandler(this.richTextBox1_LinkClicked);
    

    您可以通过扩展基类来简单地创建自己的 RichTextBox 控件 - 在那里您可以覆盖您需要的方法,例如 DetectUrls。

    【讨论】:

      【解决方案4】:

      标准的 RichTextBox 控件(假设您使用的是 Windows 窗体)公开了一组相当有限的功能,因此不幸的是,您需要执行一些 Win32 互操作来实现这一点(沿着 SendMessage()、CFM_LINK、EM_SETCHARFORMAT 等行)。 )。

      您可以在 SO 上的this answer 中找到有关如何执行此操作的更多信息。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-06-16
        • 1970-01-01
        • 2015-04-20
        • 1970-01-01
        • 1970-01-01
        • 2012-08-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多