C# 在文本的鼠标悬停时显示工具提示

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/873175/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 05:00:03  来源:igfitidea点击:

Displaying tooltip on mouse hover of a text

c#.netwinformstooltiprichtextbox

提问by Sujay Ghosh

I want to display a tooltip when the mouse hovers over a link in my custom rich edit control. Consider the following text:

当鼠标悬停在我的自定义 Rich Edit 控件中的链接上时,我想显示一个工具提示。考虑以下文本:

We all sleepat night .

我们都在晚上睡觉

In my case the word sleepis a link.

就我而言,睡眠这个词是一个链接。

When the user moves the mouse under the link, in this case "sleep", I want to display a tooltip for the link.

当用户在链接下移动鼠标时,在本例中为“睡眠”,我想显示链接的工具提示。

The following came to my mind, but they are not working

我想到了以下内容,但它们不起作用

1) Trapping OnMouseHover

1) 捕获 OnMouseHover

if(this.Cursor == Cursors.Hand)
   tooltip.Show(textbox,"My tooltip");
else
   tooltip.Hide(textbox);

But this does not work out.

但这行不通。

UPDATE

更新

The links mentioned are notURLs, i.e these are custom links, so Regex won't be of much help here, it can be any text. The user can choose to create it a a link.

提到的链接不是URL,即这些是自定义链接,因此 Regex 在这里不会有太大帮助,它可以是任何文本。用户可以选择创建一个链接。

Though I have not tried GetPositionmethod, I dont think it would be that elegant in terms of design and maintenance.

虽然我没有尝试过这种GetPosition方法,但我认为它在设计和维护方面不会那么优雅。

Let me say I have the following line, in my richedit box

让我说我有以下行,在我的 Richedit 框中

We sleepat night. But the bats stay awake. Cockroaches become activeat night.

我们晚上睡觉。但蝙蝠保持清醒。蟑螂在晚上变得活跃

In the above sentence, I want three different tooltips, when the mouse hovers over them.

在上面的句子中,我想要三个不同的工具提示,当鼠标悬停在它们上面时。

sleep -> Human beings
awake -> Nightwatchman here
active -> My day begins

I trapped OnMouseMoveas follows:

我被困OnMouseMove如下:

Working- with Messagebox

使用 Messagebox

OnMouseMove( )
{

   // check to see if the cursor is over a link
   // though this is not the correct approach, I am worried why does not a tooltip show up
   if(this.Cursor.current == Cursors.hand )
   {
     Messagebox.show("you are under a link");
   }
}

Not Working - with Tooltip - Tooltip does not show up

不工作 - 使用工具提示 - 工具提示不显示

OnMouseMove( MouseventArgs e )
{

   if(cursor.current == cursors.hand )
   {
     tooltip.show(richeditbox,e.x,e.y,1000);
   }
}

回答by jean

This is not elegant, but you might be able to use the RichTextBox.GetCharIndexFromPosition method to return to you the index of the character that the mouse is currently over, and then use that index to figure out if it's over a link, hotspot, or any other special area. If it is, show your tooltip (and you'd probably want to pass the mouse coordinates into the tooltip's Show method, instead of just passing in the textbox, so that the tooltip can be positioned next to the link).

这并不优雅,但您可以使用 RichTextBox.GetCharIndexFromPosition 方法返回鼠标当前所在字符的索引,然后使用该索引确定它是否位于链接、热点或任何其他特殊区域。如果是,请显示您的工具提示(并且您可能希望将鼠标坐标传递到工具提示的 Show 方法中,而不是仅仅传递文本框,以便工具提示可以放置在链接旁边)。

Example here: http://msdn.microsoft.com/en-us/library/system.windows.forms.richtextbox.getcharindexfromposition(VS.80).aspx

这里的例子:http: //msdn.microsoft.com/en-us/library/system.windows.forms.richtextbox.getcharindexfromposition(VS.80).aspx

回答by Shimmy Weitzhandler

Well, take a look, this works, If you have problems please tell me:

好吧,看看,这有效,如果您有问题,请告诉我:

using System.Drawing;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1() { InitializeComponent(); }

        ToolTip tip = new ToolTip();
        void richTextBox1_MouseMove(object sender, MouseEventArgs e)
        {
            if (!timer1.Enabled)
            {
                string link = GetWord(richTextBox1.Text, richTextBox1.GetCharIndexFromPosition(e.Location));
                //Checks whether the current word i a URL, change the regex to whatever you want, I found it on www.regexlib.com.
//you could also check if current word is bold, underlined etc. but I didn't dig into it.
                if (System.Text.RegularExpressions.Regex.IsMatch(link, @"^(http|https|ftp)\://[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(:[a-zA-Z0-9]*)?/?([a-zA-Z0-9\-\._\?\,\'/\\+&%$#\=~])*$"))
                {
                    tip.ToolTipTitle = link;
                    Point p = richTextBox1.Location;
                    tip.Show(link, this, p.X + e.X,
                        p.Y + e.Y + 32, //You can change it (the 35) to the tooltip's height - controls the tooltips position.
                        1000);
                    timer1.Enabled = true;
                }
            }
        }

        private void timer1_Tick(object sender, EventArgs e) //The timer is to control the tooltip, it shouldn't redraw on each mouse move.
        {
            timer1.Enabled = false;
        }

        public static string GetWord(string input, int position) //Extracts the whole word the mouse is currently focused on.
        {
            char s = input[position];
            int sp1 = 0, sp2 = input.Length;
            for (int i = position; i > 0; i--)
            {
                char ch = input[i];
                if (ch == ' ' || ch == '\n')
                {
                    sp1 = i;
                    break;
                }
            }

            for (int i = position; i < input.Length; i++)
            {
                char ch = input[i];
                if (ch == ' ' || ch == '\n')
                {
                    sp2 = i;
                    break;
                }
            }

            return input.Substring(sp1, sp2 - sp1).Replace("\n", "");
        }
    }
}

回答by Shimmy Weitzhandler

Use:

用:

ToolTip tip = new ToolTip();
private void richTextBox1_MouseMove(object sender, MouseEventArgs e)
{
    Cursor a = System.Windows.Forms.Cursor.Current;
    if (a == Cursors.Hand)
    {
        Point p = richTextBox1.Location;
        tip.Show(
            GetWord(richTextBox1.Text,
                richTextBox1.GetCharIndexFromPosition(e.Location)),
            this,
            p.X + e.X,
            p.Y + e.Y + 32,
            1000);
    }
}

Use the GetWord function from my other answer to get the hovered word. Use timer logic to disable reshow the tooltip as in prev. example.

使用我的其他答案中的 GetWord 函数来获取悬停的单词。使用计时器逻辑禁用重新显示工具提示,如前文所述。例子。

In this example right above, the tool tip shows the hovered word by checking the mouse pointer.

在上面的这个例子中,工具提示通过检查鼠标指针来显示悬停的单词。

If this answer is still not what you are looking fo, please specify the condition that characterizes the word you want to use tooltip on. If you want it for bolded word, please tell me.

如果此答案仍然不是您要查找的内容,请指定表征您要使用工具提示的单词的条件。如果你想要粗体字,请告诉我。

回答by serhio

You shouldn't use the control private tooltip, but the form one. This example works well:

您不应使用控件私有工具提示,而应使用表单 one。这个例子效果很好:

public partial class Form1 : Form
{
    private System.Windows.Forms.ToolTip toolTip1;

    public Form1()
    {
        InitializeComponent();
        this.components = new System.ComponentModel.Container();
        this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);

        MyRitchTextBox myRTB = new MyRitchTextBox();
        this.Controls.Add(myRTB);

        myRTB.Location = new Point(10, 10);
        myRTB.MouseEnter += new EventHandler(myRTB_MouseEnter);
        myRTB.MouseLeave += new EventHandler(myRTB_MouseLeave);
    }


    void myRTB_MouseEnter(object sender, EventArgs e)
    {
        MyRitchTextBox rtb = (sender as MyRitchTextBox);
        if (rtb != null)
        {
            this.toolTip1.Show("Hello!!!", rtb);
        }
    }

    void myRTB_MouseLeave(object sender, EventArgs e)
    {
        MyRitchTextBox rtb = (sender as MyRitchTextBox);
        if (rtb != null)
        {
            this.toolTip1.Hide(rtb);
        }
    }


    public class MyRitchTextBox : RichTextBox
    {
    }

}

回答by Shujaat Abdi

I would also like to add something here that if you load desired form that contain tooltip controll before the program's run then tool tip control on that form will not work as described below...

我还想在这里添加一些内容,如果您在程序运行之前加载包含工具提示控件的所需表单,那么该表单上的工具提示控件将无法如下所述工作...

    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        objfrmmain = new Frm_Main();
        Showtop();//this is procedure in program.cs to load an other form, so if that contain's tool tip control then it will not work
        Application.Run(objfrmmain);


    }

so I solved this problem by puting following code in Fram_main_load event procedure like this

所以我通过将以下代码放在 Fram_main_load 事件过程中来解决这个问题

    private void Frm_Main_Load(object sender, EventArgs e)
    {
        Program.Showtop();
    }

回答by Mawardy

Just add ToolTip tool from toolbox to the form and add this code in a mousemove event of any control you want to make the tooltip start on its mousemove

只需将工具箱中的 ToolTip 工具添加到窗体中,然后将此代码添加到您希望使工具提示在其 mousemove 上开始的任何控件的 mousemove 事件中

private void textBox3_MouseMove(object sender, MouseEventArgs e)
    {
      toolTip1.SetToolTip(textBox3,"Tooltip text"); // you can change the first parameter (textbox3) on any control you wanna focus
    }

hope it helps

希望能帮助到你

peace

和平

回答by Jesse Chisholm

As there is nothing in this question (but its age) that requires a solution in Windows.Forms, here is a way to do this in WPFin code-behind.

由于这个问题中没有任何内容(但它的年龄)需要在 中解决Windows.Forms,这里有一种WPF在代码隐藏中执行此操作的方法。

TextBlock tb = new TextBlock();
tb.Inlines.Add(new Run("Background indicates packet repeat status:"));
tb.Inlines.Add(new LineBreak());
tb.Inlines.Add(new LineBreak());
Run r = new Run("White");
r.Background = Brushes.White;
r.ToolTip = "This word has a White background";
tb.Inlines.Add(r);
tb.Inlines.Add(new Run("\t= Identical Packet received at this time."));
tb.Inlines.Add(new LineBreak());
r = new Run("SkyBlue");
r.ToolTip = "This word has a SkyBlue background";
r.Background = new SolidColorBrush(Colors.SkyBlue);
tb.Inlines.Add(r);
tb.Inlines.Add(new Run("\t= Original Packet received at this time."));

myControl.Content = tb;

回答by S G

If you are using RichTextBox control. You can simply define the ToolTip object and show the tool-tip as the text is selected by moving the mouse inside the RichTextBox control.

如果您使用的是 RichTextBox 控件。您可以简单地定义 ToolTip 对象并在通过在 RichTextBox 控件内移动鼠标来选择文本时显示工具提示。

    ToolTip m_ttInput = new ToolTip(); // define as member variable

    private void rtbInput_SelectionChanged(object sender, EventArgs e)
    {
        if (rtbInput.SelectedText.Length > 0) 
        {
            m_ttInput.Show(rtbInput.SelectedText.Length.ToString(), rtbInput, 1000);
        }
    }

回答by RugerSR9

For the sake of ease of use and understandability.

为了便于使用和理解。

You can simply put a Tooltip anywhere on your form (from toolbox). You will then be given an options in the Properties of everything else in your form to determine what is displayed in that Tooltip (it reads something like "ToolTip on toolTip1"). Anytime you hover on an object, the text in that property will be displayed as a tooltip.

您可以简单地将工具提示放在表单上的任何位置(来自工具箱)。然后,您将在表单中其他所有内容的“属性”中获得一个选项,以确定该工具提示中显示的内容(其内容类似于“工具提示上的工具提示”)。每当您将鼠标悬停在对象上时,该属性中的文本将显示为工具提示。

This does notcover custom on-the-fly tooltips like the original question is asking for. But I am leaving this here for others that do not need

包括原始问题要求的自定义即时工具提示。但我把这个留给其他不需要的人