Let's take an example from android. Assume you send a message to someone and after message was send you can see (for a few seconds) kind of notification on the screen like Your message was send.
That is exactly what I would like to find in Winform. In my Winform app user click on the button and I would like to make kind of UI response, show him a message for a few sec, like Button clicked.
How to do it?
P.S. Actually I tried to find out how to do it, but everything that I found is kind of notification on the screen at the right bottom corner. It is not actually what I am looking for. I need something like you can see on screenshot. This text should appear in the form, not on the corner of the screen.
P.S 2 Tooltip also not what I am looking for. Tooltip is something that binded close to the button(view). I need kind of general UI response. User click on buttons and instead to show him a dialog that force user to move his mouse and close the dialog, I need kind of softy message that disappear after a few sec.
I need kind of softy message that disappear after a few sec.
I think the tooltips are what you are looking for. The idea is you can programmatically control where to show a tooltip and when to hide it.
Please start a new WinForms project. Add three buttons, ToolTip and Timer to the form. Write the next event handlers (and bind them to the corresponding components):
private void button_Click(object sender, EventArgs e)
{
toolTip1.Show(((Button)sender).Text + " is pressed", this, 300, 300);
timer1.Enabled = true;
}
private void timer1_Tick(object sender, EventArgs e)
{
timer1.Enabled = false;
toolTip1.Hide(this);
}
After demo starting you'll see a tooltip with certain text appearing at the same position for the 1 second.
#Miamy's solution not a bad one, however you have to center text in notification box, and you don't need to use timer. Here the custom tooltip class which centers the tooltip text location and you can see the output below:
Moreover I added some coloring features along with default timer implementation.
class CustomToolTip : ToolTip
{
public int SIZE_X = 500;
public int SIZE_Y = 50;
public CustomToolTip()
{
this.OwnerDraw = true;
this.Popup += new PopupEventHandler(this.OnPopup);
this.Draw += new DrawToolTipEventHandler(this.OnDraw);
}
string m_EndSpecialText;
Color m_EndSpecialTextColor = Color.Black;
public Color EndSpecialTextColor
{
get { return m_EndSpecialTextColor; }
set { m_EndSpecialTextColor = value; }
}
public string EndSpecialText
{
get { return m_EndSpecialText; }
set { m_EndSpecialText = value; }
}
private void OnPopup(object sender, PopupEventArgs e) // use this event to set the size of the tool tip
{
e.ToolTipSize = new Size(SIZE_X, SIZE_Y);
}
private void OnDraw(object sender, DrawToolTipEventArgs e) // use this event to customise the tool tip
{
Graphics g = e.Graphics;
LinearGradientBrush b = new LinearGradientBrush(e.Bounds,
Color.AntiqueWhite, Color.LightCyan, 45f);
g.FillRectangle(b, e.Bounds);
g.DrawRectangle(new Pen(Brushes.Black, 1), new Rectangle(e.Bounds.X, e.Bounds.Y,
e.Bounds.Width - 1, e.Bounds.Height - 1));
System.Drawing.Size toolTipTextSize = TextRenderer.MeasureText(e.ToolTipText, e.Font);
g.DrawString(e.ToolTipText, new Font(e.Font, FontStyle.Bold), Brushes.Black,
new PointF((SIZE_X - toolTipTextSize.Width)/2, (SIZE_Y - toolTipTextSize.Height) / 2));
b.Dispose();
}
}
You can call this tooltip as below code:
CustomToolTip notifyError = new CustomToolTip();
notifyError.Show("Please enter a number.", this, 100, 100, 2000);
Above code creates notification box at 100, 100 location for 2 seconds.
Related
So i tried to make a button more animated by making that when i hover my mouse over the button its back colour goes slowly from a darker gray to lighter gray, sadly the the MouseHover didn't worked out great for me because i had to use it with if (while, do and for isn't working at all) so i changed it to MouseMove And well that created its own problems, right now the colour getting lighter only when i move my mouse on it, here is the code:
private void BtnPlay_MouseMove(object sender, MouseEventArgs e)
{
byte coloDat = btnPlay.FlatAppearance.MouseOverBackColor.B;
if (btnPlay.FlatAppearance.MouseOverBackColor != Color.FromArgb(68, 68, 68))
{
coloDat++;
btnPlay.FlatAppearance.MouseOverBackColor = Color.FromArgb(coloDat, coloDat, coloDat);
System.Threading.Thread.Sleep(1);
}
}
Im gonna use the code multiple times in the project so is there a way to do this without making a wall of text?
Edit: For avoiding confusion; im trying to do my project with Button.FlatAppearance.MouseOverBackColor and not Button.BackgroundColour.
If you want to create this in WPF, just create a style with a storyboard. In windows forms, you need to use a timer.
The reason a loop didn't work for you is that the loop was running on the same thread as the UI, so the UI wasn't being updated until after your loop was over. To animate an effect in windows forms, you have to let the event function end so that the UI can update and then have your function called again for the next frame. That is what the timer element does.
I created a demo program with two animated buttons. To create buttons with animated background colors I first set up a start color, end color, the amount I want the color to change in each frame, the button the mouse is currently over and the transition progress of each button. I added that last so that I could have the buttons gradually transition back after the mouse was over something else.
private Color startColor = Color.AliceBlue;
private Color endColor = Color.BlueViolet;
private double step = 0.01;
private Button lastOver = null;
private Dictionary<Button, double> transitionProgress = new Dictionary<Button, double>();
Then I attached the event handlers of both of my buttons to the same functions, the functions below. The first uses ContainsKey so that I can make more buttons animated by just assigning them to these event handler functions.
private void demoButton_MouseHover(object sender, EventArgs e)
{
if (sender != lastOver)
{
lastOver = (Button)sender;
if (!transitionProgress.ContainsKey(lastOver))
{
transitionProgress[lastOver] = 0.0;
}
}
}
private void demoButton_MouseLeave(object sender, EventArgs e)
{
lastOver = null;
}
Then I created a Timer with the following event handler. It goes through each button and transitions it based on whether the mouse is currently over that button. It also only updates the background color if it has changed to improve performance.
private void styleUpdate_Tick(object sender, EventArgs e)
{
for (int i = 0; i < transitionProgress.Count; i++)
{
Button button = transitionProgress.Keys.ElementAt(i);
bool changing = false;
if (button == lastOver)
{
if (transitionProgress[button] < 1.0)
{
transitionProgress[button] = Math.Min(1.0, transitionProgress[button] + step);
changing = true;
}
}
else
{
if (transitionProgress[button] > 0.0)
{
transitionProgress[button] = Math.Max(0.0, transitionProgress[button] - step);
changing = true;
}
}
if (changing)
{
double progress = transitionProgress[button];
button.BackColor = Color.FromArgb(
(int)Math.Floor((endColor.R - startColor.R) * progress + startColor.R),
(int)Math.Floor((endColor.G - startColor.G) * progress + startColor.G),
(int)Math.Floor((endColor.B - startColor.B) * progress + startColor.B)
);
}
}
}
The timer has to be enabled and the interval set to 16
this.styleUpdate.Enabled = true;
this.styleUpdate.Interval = 16;
this.styleUpdate.Tick += new System.EventHandler(this.styleUpdate_Tick);
That does seem like a lot of code, but to add it to another button, you just need two more lines of code.
this.yourButtonName.MouseLeave += new System.EventHandler(this.demoButton_MouseLeave);
this.yourButtonName.MouseHover += new System.EventHandler(this.demoButton_MouseHover);
I have created a text box, inside a PictureBox, on mouse click at run time. Now I want to resize it using mouse drag. Is there some simple way to do this ?
Here is the code I have so far:
public partial class Form1 : Form
{
public static TextBox PTB; //declaring text box to be created
public static bool textOption; //stores the state of button , i.e whether or not text box button is clicked before or not
public Form1()
{
InitializeComponent();
this.pictureBox1.Click += new System.EventHandler(this.pictureBox1_Click);
}
private void pictureBox1_Click(object sender, EventArgs e)
{
if (textOption == true)//if user selected option to draw text box
{
MouseEventArgs eM = (MouseEventArgs)e; //create an instance of mouse event
PTB = new TextBox();//dynamically creating text box
PTB.Location = new System.Drawing.Point(eM.X, eM.Y);//settign position of textbox where mouse was clicked
PTB.Name = "textBox1";
PTB.Size = new System.Drawing.Size(100, 20);//size of text box
this.pictureBox1.Controls.Add(PTB);//adding the textbox to the picture box
}
}
Update
I'm sorry I have totally misread your question.
The reason is probably that you seem to be under the impression that Paint programs have TextBoxes sitting on their canvas. They don't. They draw text the same way as they draw lines or circles etc..
Also: Resizing the TextBox will not change the Font size, in case that's is what you want.
Finally: A TextBox will never be transparent, it will always sit on the PictureBox and look, well, like a TextBox. Not like anything in a Paint programm..
But: If you actually do want to resize the TextBox here are a few hints:
You need some way to show the user they are on the right spot by changing the cursor to the right icon
You need to store the mouse down point (attention: it will be inside the TextBox!) and keep track of the increments in the MouseMove. As long as the Button is down all rported e.Location will still be in the TextBox coordinates.
Use the increments (not the absolute values) to increase the size of the TextBox.
It is really hard to get the resizing right on the top and left sides. (Because it will involve moving at the same time), so better don't try!
Do include moving, which is easy and will suffice for all you need.
No, this is a good deal harder than increasing font size. 200-300 lines of code, the last time I did it..
But you may find another somewhat simpler answer; look for "Resize Control with Mouse winforms c#" on Google..
I leave the old answer in place, even if it not what you were looking for..
Old answer about changing font size while placing text:
It is not very hard but you need to get it right; it is basically the same as drawing a Rectangle
with a live preview. You need these things: four events, a Point or two, a Size and a font variable..
The events are:
MouseDown
MouseMove
MouseUp
Paint
You need to store a point for the placement (in the MouseDown event) and a size you update in the MouseMove.
From that size you can calculate the maximum Font size you can fit in the Rectangle.
On MouseUp you finalize things.
In the Paint event you draw string at the down Point with the current Font size.
In the MouseMove you call Invalidate on the PictureBox to trigger the Paint event.
in the MouseMouve you should check the Button to be the left one.
For extra good UI you can also check the keyboard for space and use it to move the DownPoint..
The Click event is rather useless, btw..
Here is a minimal code example to get you started:
Point mDown = Point.Empty;
float fSize = 12f;
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
using (Font font = new Font("Consolas", fSize))
e.Graphics.DrawString("Hello World", font, Brushes.Black, mDown);
}
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
mDown = e.Location;
pictureBox1.Invalidate();
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
fSize = Math.Abs(e.Y - mDown.Y) / 2f + 1;
pictureBox1.Invalidate();
}
I left out the MouseUp. Here you would store the final state (font, location..) of the drawn string somewhere or persist it by drawing into a Bitmap etc..
I also didn't do a full Rectangle calculation but determined the font size by simply scaling the y-movement down a little.. You could improve with a little pythagoras ;-)
The ability to resize a window is innate behavior, provided by the default window procedure built into Windows. All you have to do is give the control a resizable border. Everything else is for free, you'll get the correct cursor and dragging a corner or edge resizes the control.
using System;
using System.Windows.Forms;
class ResizeableTextBox : TextBox {
protected override CreateParams CreateParams {
get {
var cp = base.CreateParams;
cp.Style |= 0x840000; // Turn on WS_BORDER + WS_THICKFRAME
return cp;
}
}
}
This sample will create the TextBox on the MouseDown event and start resizing, the final size of the TextBox will be where the mouse button is released on the MouseUp event. It will let you create multiple textboxes as well.
I realize this might not be exactly what you want but it might be a start.
private int _textBoxCounter;
private TextBox _textBoxCurrentResizing;
public Form1()
{
InitializeComponent();
pictureBox1.MouseDown += PictureBox1OnMouseDown;
pictureBox1.MouseUp += PictureBox1OnMouseUp;
pictureBox1.MouseMove += PictureBox1OnMouseMove;
}
public Point RelativeMousePosition { get { return PointToClient(MousePosition); } }
private void PictureBox1OnMouseMove(object sender, MouseEventArgs mouseEventArgs)
{
ResizeTextBox();
}
private void PictureBox1OnMouseUp(object sender, MouseEventArgs mouseEventArgs)
{
EndResizeTextBox();
}
private void PictureBox1OnMouseDown(object sender, MouseEventArgs mouseEventArgs)
{
var tb = CreateTextBox();
StartResizeTextBox(tb);
}
private TextBox CreateTextBox()
{
var tb = new TextBox
{
Location = RelativeMousePosition,
Size = new Size(100, 20),
Multiline = true,
Name = "textBox" + _textBoxCounter++,
};
pictureBox1.Controls.Add(tb);
return tb;
}
private void StartResizeTextBox(TextBox tb)
{
_textBoxCurrentResizing = tb;
}
private void ResizeTextBox()
{
if (_textBoxCurrentResizing == null) return;
var width = Math.Abs(_textBoxCurrentResizing.Left - RelativeMousePosition.X);
var height = Math.Abs(_textBoxCurrentResizing.Top - RelativeMousePosition.Y);
_textBoxCurrentResizing.Size = new Size(width, height);
}
private void EndResizeTextBox()
{
_textBoxCurrentResizing = null;
}
I am new to C# but I have a lot of Java experience so I've been told that C# is fairly easy to comprehend based on that.
So far it is. At the moment though, I want to make a simple TicTacToe as part of an exercise. However what I want to do, is draw clickable squares that I can reference so I can check if the box is already clicked or not.
I am currently using Visual Studio Express 2012. I am making a Windows Form Application for Desktop usage.
I looked around for solutions but I can't seem to find something that does this.
How would I go about doing this?
internal sealed class Box : Control
{
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.DrawRectangle(Pens.Black, new Rectangle(Point.Empty, new Size(Width - 1, Height - 1)));
}
protected override void OnClick(EventArgs e)
{
MessageBox.Show("You Clicked The Box!");
}
}
Create a class that derives from Control. From here you can override a whole bunch of virtual members including the OnPaint method where you can perform all of your drawing logic. It's all very intuitive with the assistance of IntelliSense (DrawRectangle, Draw Line etc).
If you want you can override OnClick like I did here but otherwise you can subscribe to an the controls' Click event just as you would a standard control.
You can also derive from ContainerControl for your 'grid' which will behave similarly to a Panel or GroupBox control.
Here's a quick example I just put together to get you started. The border is a tiny bit bugged at some resolutions, I'll leave that down to my abysmal mathematics skills.
internal sealed class GameGrid : ContainerControl
{
protected override void OnCreateControl()
{
for (int y = 0; y < 3; y++)
{
for (int x = 0; x < 3; x++)
{
GameButton button = new GameButton
{
Width = Width/3,
Height = Height/3,
};
button.Location = new Point(x*button.Width++, y*button.Height++);
Controls.Add(button);
button.Click += button_Click;
}
}
}
static void button_Click(object sender, EventArgs e)
{
GameButton gameButton = (GameButton)sender;
gameButton.CircleCheck = true;
}
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
e.Graphics.DrawRectangle(Pens.Black, new Rectangle(ClientRectangle.Location, new Size(Width - 1, Height - 1)));
}
}
internal sealed class GameButton : Control
{
private bool _cricleCheck;
public bool CircleCheck
{
get
{
return _cricleCheck;
}
set
{
_cricleCheck = value;
Invalidate();
}
}
private readonly Pen circlePen = new Pen(Brushes.Black, 2.0f);
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
e.Graphics.DrawRectangle(Pens.Black, new Rectangle(ClientRectangle.Location, new Size(Width - 1, Height - 1)));
if (CircleCheck)
{
e.Graphics.DrawEllipse(circlePen, new Rectangle(ClientRectangle.Location.X + 10, ClientRectangle.Location.Y + 10, Width - 30, Height - 30));
}
}
}
The most common clickable square is a button.
If the button is clickable in the current gamestate and what icon should be presented there if it was clicked sounds like a job for your background logic.
Try this:
Create a new Form
Drop a PictureBox control inside the form in order to render the Tic Tac Toe board
Handle the Paint event to do the graphics rendering
Handle the MouseClick event to detect if the user has clicked inside the board and use the event arguments to determine on which of the 9 squares of the board the user has clicked
Hope this helps.
I did a similar exercise 2days ago,
Just check this tutorial, it will be enough I guess:
http://www.codeproject.com/Articles/2400/Tic-Tac-Toe-in-C
And for the Square you can either use buttons or you could use PictureBox like this tutorial (although they used vb.net not c# but it's easy to translate):
http://vbprogramming.8k.com/tutorials/tic-tac-toe.htm
I think the easiest solution is using simple buttons with background color or image.
Have a variable for currently playing user and change
button.Text
on click event.
Set all button texts for "" at the beginning- that way you can check if the button was clicked:
if (button.Text!="")
//it was already clicked
I am writing a screensaver program in C#. And I want it to do the following:
Start with a text. After about 3 seconds or more, hide the text and show an image. After the next 3 seconds, hide the image show the text and keep going round the loop until the user does something that exits the screensaver.
What I have done:
I started with a simple textlabel and a timer control. I was able to get the textlabel change positions on screen after every 3 seconds. I updated my code to include a picturebox, and in my timer_tick method, I inserted an if-else statement to check, when the method is called,
if the textlabel is shown, hide it and show the picturebox.
else if the picturebox is shown, hide it and show the textbox. Code is shown below:
private void Form1_Load(object sender, EventArgs e)
{
Cursor.Hide();
TopMost = true;
moveTimer.Interval = 3000;
moveTimer.Tick += new EventHandler(moveTimer_Tick);
moveTimer.Start();
}
private void moveTimer_Tick(object sender, System.EventArgs e)
{
//Move text to new Location
//textLabel.Left = rand.Next(Math.Max(1, Bounds.Width - textLabel.Width));
//textLabel.Top = rand.Next(Math.Max(1, Bounds.Height - textLabel.Height));
if (pictureBox1.Enabled == true)
{
pictureBox1.Hide();
textLabel.Show();
}
if (textLabel.Enabled == true)
{
textLabel.Hide();
pictureBox1.Show();
}
}
Here's the problem:
WHen I run the screensaver program, the screen starts with the text, changes to the picture after 3 seconds and stops there.
What do I do to get it moving in a continous loop, showing/hiding the textlabel or picturebox?
Have I implemented this in the right way?
Please clear and concise explanations/answers will be highly appreciated.
Thanks!
Perhaps you could keep the state in a variable that you can switch
private bool state = false;
private void moveTimer_Tick(object sender, System.EventArgs e)
{
//Move text to new Location
//textLabel.Left = rand.Next(Math.Max(1, Bounds.Width - textLabel.Width));
//textLabel.Top = rand.Next(Math.Max(1, Bounds.Height - textLabel.Height));
if (state)
{
pictureBox1.Hide();
textLabel.Show();
}
else
{
textLabel.Hide();
pictureBox1.Show();
}
state = !state;
}
How about something like this?
Enabled says whether the object can receive input.
Visible is what says if its visible or not.
You see it change once and only once because all the objects are enabled. The first if succeeds, hiding the picture and showing the text. But then the second if also succeeds, showing the picture and hiding the text. Since this is all in one event callback, you never see the first if happen, because the second overrides it.
As you're realizing in the comments, the answer is to not check enabled. Instead, check Visible. Make sure to use an else as well, otherwise you may still get the same issue of both being true.
private void moveTimer_Tick(object sender, System.EventArgs e)
{
//Move text to new Location
//textLabel.Left = rand.Next(Math.Max(1, Bounds.Width - textLabel.Width));
//textLabel.Top = rand.Next(Math.Max(1, Bounds.Height - textLabel.Height));
if (pictureBox1.Visible == true)
{
pictureBox1.Hide();
textLabel.Show();
}
else
{
textLabel.Hide();
pictureBox1.Show();
}
}
I want to display a tooltip when the mouse hovers over a link in my custom rich edit control. Consider the following text:
We all sleep at night .
In my case the word sleep is 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
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 not URLs, 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.
Though I have not tried GetPosition method, I dont think it would be that elegant in terms of design and maintenance.
Let me say I have the following line, in my richedit box
We sleep at night. But the bats stay awake. Cockroaches become active at 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 OnMouseMove as follows:
Working- with 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);
}
}
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
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
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", "");
}
}
}
You shouldn't use the control private tooltip, but the form one. This example works well:
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
{
}
}
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).
Example here:
http://msdn.microsoft.com/en-us/library/system.windows.forms.richtextbox.getcharindexfromposition(VS.80).aspx
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.
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.
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
private void Frm_Main_Load(object sender, EventArgs e)
{
Program.Showtop();
}
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.
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);
}
}
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 not cover custom on-the-fly tooltips like the original question is asking for. But I am leaving this here for others that do not need
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 WPF in code-behind.
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;