I changed in the properties OwnerDraw to true.
and added the Draw event.
private void toolTip1_Draw(object sender, DrawToolTipEventArgs e)
{
using (StringFormat sf = new StringFormat())
{
sf.Alignment = StringAlignment.Center;
sf.LineAlignment = StringAlignment.Center;
sf.HotkeyPrefix = System.Drawing.Text.HotkeyPrefix.None;
sf.FormatFlags = StringFormatFlags.NoWrap;
using (Font f = new Font("Tahoma", 12))
{
e.Graphics.DrawString(e.ToolTipText, f,
SystemBrushes.ActiveCaptionText, e.Bounds, sf);
}
}
}
First time i put the mouse over a control with a tooltip the text is bigger but then next on other controls the tooltip get black :
before using the Draw event it was working fine but i want to resize the text font size.
You need clear the graphics first.
e.Graphics.Clear(((Control)sender).BackColor);
Or just use the methods defined in DrawToolTipEventArgs
e.DrawBackground();
e.DrawBorder();
Related
I am currently implementing a tooltip which has at least two sentences worth inside of it, so I need to somehow create a large rectangle which would hold it.
My issue is the height of the rectangle.
Snip:
As you can see the green rectangle does not have the required size.
Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Discounting.Module
{
public partial class Benefits : UserControl
{
public Benefits()
{
InitializeComponent();
}
private void ToolTip1_Draw(object sender, DrawToolTipEventArgs e)
{
var newEventArgs = new DrawToolTipEventArgs(
e.Graphics,
e.AssociatedWindow,
e.AssociatedControl,
e.Bounds, e.ToolTipText,
this.BackColor,
this.ForeColor,
Font);
DrawToolTip(e);
}
private void DrawToolTip(DrawToolTipEventArgs e)
{
using (var sf = new StringFormat())
{
sf.LineAlignment = StringAlignment.Center;
sf.Alignment = StringAlignment.Center;
using (var graphics = e.Graphics)
{
var linearGradientBrush = new LinearGradientBrush(new Rectangle(e.Bounds.X, e.Bounds.Y,
8000, 1000), Color.GreenYellow, Color.MintCream, 45f);
graphics.FillRectangle(linearGradientBrush, linearGradientBrush.Rectangle);
graphics.DrawString(e.ToolTipText, new Font("Aerial",12.0f, FontStyle.Bold), Brushes.Silver,
new PointF(linearGradientBrush.Rectangle.X + 6, linearGradientBrush.Rectangle.Y + 6)); // shadow layer
graphics.DrawString(e.ToolTipText, new Font("Aerial",12.0f, FontStyle.Bold), Brushes.Black,
new PointF(linearGradientBrush.Rectangle.X + 5, linearGradientBrush.Rectangle.Y + 5)); // top layer
linearGradientBrush.Dispose();
}
}
}
private void ToolTip2_Draw(object sender, DrawToolTipEventArgs e)
{
DrawToolTip(e);
}
private void ToolTip3_Draw(object sender, DrawToolTipEventArgs e)
{
DrawToolTip(e);
}
private void ToolTip4_Draw(object sender, DrawToolTipEventArgs e)
{
DrawToolTip(e);
}
}
}
If you require further details I would be happy to provide them.
Well, since there might be some quirks when mixing TextRenderer and the Graphics object, here's an example:
The ToolTip.PopUp event provides means to set the Size of the ToolTip rectangle. You just need to measure the Text and set its PopupEventArgs.ToolTipSize property to the measured Size.
This allows to use multi-line strings as well, using Environment.NewLine to separate the lines.
The PopupEventArgs object doesn't provide a Graphics object that can be use to measure the Text. We can use TextRenderer.MeasureText instead.
TextRenderer.MeasureText is very precise: it will give back the exact measure of the Text. Since you are using Graphics.DrawString to draw the Text, we better be generous and add some more space to the measured Width, to avoid text wrapping and also because the Text looks better if the container rectangle is not too tight.
In the Popup event, after measuring the Text, I'm adding 5 pixels to both the Width and Height (Size.Add([Measured Size], new Size(5, 5))). Modify as required
Note:
Here, the Font family and Size are hard-coded. Of course you may want to use a more dynamic Font object, possibly linked to a property of your UserControl. The Font can be changed at any time: the PopUp event will use it to measure the test bounds.
TextFormatFlags toolTipFlags = TextFormatFlags.VerticalCenter |
TextFormatFlags.LeftAndRightPadding | TextFormatFlags.HorizontalCenter | TextFormatFlags.NoClipping;
Font toolTipFont = new Font("Arial", 12.0f, FontStyle.Bold);
private void toolTip1_Popup(object sender, PopupEventArgs e)
{
string toolTipText = (sender as ToolTip).GetToolTip(e.AssociatedControl);
using (var g = e.AssociatedControl.CreateGraphics()) {
var textSize = Size.Add(TextRenderer.MeasureText(
g, toolTipText, toolTipFont, Size.Empty, flags), new Size(10, 5));
e.ToolTipSize = textSize;
}
}
private void toolTip1_Draw(object sender, DrawToolTipEventArgs e) => DrawToolTip(e);
private void DrawToolTip(DrawToolTipEventArgs e)
{
using (var linearGradientBrush = new LinearGradientBrush(e.Bounds, Color.GreenYellow, Color.MintCream, 45f)) {
e.Graphics.FillRectangle(linearGradientBrush, e.Bounds);
}
var shadowBounds = new Rectangle(new Point(e.Bounds.X + 1, e.Bounds.Y + 1), e.Bounds.Size);
TextRenderer.DrawText(e.Graphics, e.ToolTipText, toolTipFont, shadowBounds, Color.LightGray, toolTipFlags);
TextRenderer.DrawText(e.Graphics, e.ToolTipText, toolTipFont, e.Bounds, Color.Black, toolTipFlags);
}
I want to display some information in tab control This is what I want.
I have used the methods that I found on your side to make changes in properties of tab control and using Draw Event but the output is not like what i needed.The output comes likeThis is what I am getting..
I want the text to be horizontal. Also my VS is 2008
I followed these instructions in VB and converted them to C#. Worked for me. Basically in tab control properties set the following:
Alignment = Left
SizeMode = Fixed
ItemSize = 30, 120: Width = 30 Height = 120
DrawMode = OwnerDrawFixed
Then you have to handle DrawItem event like that:
private void tabControl1_DrawItem(object sender, DrawItemEventArgs e)
{
var g = e.Graphics;
var text = this.tabControl1.TabPages[e.Index].Text;
var sizeText = g.MeasureString(text, this.tabControl1.Font);
var x = e.Bounds.Left + 3;
var y = e.Bounds.Top + (e.Bounds.Height - sizeText.Height) / 2;
g.DrawString(text, this.tabControl1.Font, Brushes.Black, x, y);
}
And the result is:
Set the SizeMode property to Fixed, so that all tabs are the same width.
Set the ItemSize property to the preferred fixed size for the tabs. Keep in mind that the ItemSize property behaves as though the tabs were on top, although they are left-aligned. As a result, in order to make the tabs wider, you must change the Height property, and in order to make them taller, you must change the Width property. [I set the ItemSize as: 25, 150].
Set the DrawMode property to OwnerDrawFixed.
private void tabControl1_DrawItem(object sender, DrawItemEventArgs e)
{
Graphics g = e.Graphics;
Brush _textBrush;
// Get the item from the collection.
TabPage _tabPage = tabControl1.TabPages[e.Index];
// Get the real bounds for the tab rectangle.
Rectangle _tabBounds = tabControl1.GetTabRect(e.Index);
if (e.State == DrawItemState.Selected)
{
// Draw a different background color, and don't paint a focus rectangle.
_textBrush = new SolidBrush(Color.Red);
g.FillRectangle(Brushes.Gray, e.Bounds);
}
else
{
_textBrush = new System.Drawing.SolidBrush(e.ForeColor);
e.DrawBackground();
}
// Use our own font.
Font _tabFont = new Font("Arial", (float)10.0, FontStyle.Bold, GraphicsUnit.Pixel);
// Draw string. Center the text.
StringFormat _stringFlags = new StringFormat();
_stringFlags.Alignment = StringAlignment.Center;
_stringFlags.LineAlignment = StringAlignment.Center;
g.DrawString(_tabPage.Text, _tabFont, _textBrush, _tabBounds, new StringFormat(_stringFlags));
}
Since I'm a C# beginner I don't know what's to do in my case. I wanted a side-aligned tab control so I have found this:
https://msdn.microsoft.com/en-us/library/ms404305%28v=vs.110%29.aspx
Now the tabpage names are not getting displayed at all. How do I "draw" them? I hope someone can help me. The DrawItem method:
private void tabControl1_DrawItem(object sender, DrawItemEventArgs e)
{
Graphics g = e.Graphics;
Brush _textBrush;
// Get the item from the collection.
TabPage _tabPage = tabControl1.TabPages[e.Index];
// Get the real bounds for the tab rectangle.
Rectangle _tabBounds = tabControl1.GetTabRect(e.Index);
if (e.State == DrawItemState.Selected)
{
// Draw a different background color, and don't paint a focus rectangle.
_textBrush = new SolidBrush(Color.Red);
g.FillRectangle(Brushes.Gray, e.Bounds);
}
else
{
_textBrush = new System.Drawing.SolidBrush(e.ForeColor);
e.DrawBackground();
}
// Use our own font.
Font _tabFont = new Font("Arial", (float)10.0, FontStyle.Bold, GraphicsUnit.Pixel);
// Draw string. Center the text.
StringFormat _stringFlags = new StringFormat();
_stringFlags.Alignment = StringAlignment.Center;
_stringFlags.LineAlignment = StringAlignment.Center;
g.DrawString(_tabPage.Text, _tabFont, _textBrush, _tabBounds, new StringFormat(_stringFlags));
}
I am using a ToolTip control in my project. I want to set its backcolor red. I have changed ownerdraw property to true and backcolor to red. But no result. Any suggestion?
Regards,
skpaul.
Set these propeties:
yourTooltip.OwnerDraw = true;
yourTooltip.BackColor = System.Drawing.Color.Red;
then on the Draw event use this :
private void yourTooltip_Draw(object sender, DrawToolTipEventArgs e)
{
e.DrawBackground();
e.DrawBorder();
e.DrawText();
}
Add Event to toolstrip and set OwnerDraw to true:
public Form1() {
InitializeComponent();
toolTip1.OwnerDraw = true;
toolTip1.Draw += new DrawToolTipEventHandler(toolTip1_Draw);
}
Then do add a method for Draw Event:
void toolTip1_Draw(object sender, DrawToolTipEventArgs e) {
Font f = new Font("Arial", 10.0f);
toolTip1.BackColor = System.Drawing.Color.Red;
e.DrawBackground();
e.DrawBorder();
e.Graphics.DrawString(e.ToolTipText, f, Brushes.Black, new PointF(2, 2));
}
When you set a Control to OwnerDraw, you have to handle the drawing of the control yourself.
Here's a quick and dirty example (adapt to your taste):
Private Sub ToolTip1_Draw(sender As Object, e As DrawToolTipEventArgs) Handles ToolTip1.Draw
Dim tt As ToolTip = CType(sender, ToolTip)
Dim b As Brush = New SolidBrush(tt.BackColor)
e.Graphics.FillRectangle(b, e.Bounds)
Dim sf As StringFormat = New StringFormat
sf.Alignment = StringAlignment.Center
sf.LineAlignment = StringAlignment.Center
e.Graphics.DrawString(e.ToolTipText, SystemFonts.DefaultFont, SystemBrushes.ActiveCaptionText, e.Bounds, sf)
sf.Dispose()
b.Dispose()
End Sub
Cheers
I found an article that does exactly what I need. It draws multiple colors on the same line on a text box. But the problem is that it was written in VB.NET and I'm writing my program in C#. Any good soul can convert this to C# if it is possible and if it isn't can you give me other options? Thanks.
This is the article: http://www.vbrad.com/article.aspx?id=34.
here is the conversion of what you posted Nicolas
if you need to change / get anything else working you will need to test it on your end..
Happy coding
private void MeasureItemHandler(object sender, MeasureItemEventArgs e)
{
Graphics g = Graphics.FromHwnd(lstColor.Handle);
StringFormat sf = new StringFormat(StringFormat.GenericTypographic);
SizeF size = default(SizeF);
float height = 0;
Font oFont = new Font("Arial", 10);
//measure the height of what you are about to draw
//and let the listbox know this
size = g.MeasureString(data(e.Index), oFont, 500, sf);
height = size.Height + 5;
e.ItemHeight = height;
}
private void DrawItemHandler(object sender, DrawItemEventArgs e)
{
Graphics g = Graphics.FromHwnd(lstColor.Handle);
StringFormat sf = new StringFormat(StringFormat.GenericTypographic);
SizeF size = default(SizeF);
float width = 0;
Font oFont = new Font("Arial", 10);
//get the width of the string you are about to write
//this info is needed so that we can offset the next
//string that will be drawn in a different color.
size = g.MeasureString(data(e.Index), oFont, 500, sf);
width = size.Width + 16;
//prepare the list for drawing
e.DrawBackground();
e.DrawFocusRectangle();
//draw the first string in a certain color
e.Graphics.DrawString(data(e.Index), oFont, new SolidBrush(color(e.Index)), e.Bounds.X, e.Bounds.Y);
//draw the second string in a different color
e.Graphics.DrawString(data(data.Length - 1 - e.Index), oFont, new SolidBrush(color(color.Length - 1 - e.Index)), width, e.Bounds.Y);
}
First of all, they aren't using a Textbox in this article, they are using a Listbox but what follows is a conversion of the code from VB.Net to C# like you asked. It needs tidied up a bit but it does the job.
Just create a new Windows Form, place a Listbox called lstColor onto this form, change the DrawMode property to OwnerDrawFixed inside the properties window, then add event handlers for DrawItem and MeasureItem (you can add event handlers by clicking on the lightning bolt in the Properties window, and double clicking the whitespace beside these two words in the list).
In the DrawItem event handler, add the following:
private void lstColor_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e)
{
var size = g.MeasureString(data[e.Index], oFont, 500, sf);
var width = size.Width + 16;
e.DrawBackground();
e.DrawFocusRectangle();
e.Graphics.DrawString(data[e.Index], oFont, new SolidBrush(color[e.Index]), e.Bounds.X, e.Bounds.Y);
e.Graphics.DrawString(data[data.Length - 1 - e.Index], oFont, new SolidBrush(color[color.Length - 1 - e.Index]), width, e.Bounds.Y);
}
In the MeasureItem event handler, add this:
private void lstColor_MeasureItem(object sender, MeasureItemEventArgs e)
{
var size = g.MeasureString(data[e.Index], oFont, 500, sf);
var height = size.Height;
e.ItemHeight = Convert.ToInt32(height);
}
Add five private fields outside the scope of any methods but inside your Form1 (or whatever you've called your form) class like so:
private string[] data;
private Color[] color;
private Font oFont;
private Graphics g;
private StringFormat sf;
Put the following three lines inside your Form1_Load event:
private void Form1_Load(object sender, EventArgs e)
{
oFont = new Font("Arial", 10);
data = new string[] { "This is Red", "This is Blue", "This is Green", "This is Yellow", "This is Black", "This is Aqua", "This is Brown", "This is Cyan", "This is Gray", "This is Pink" };
color = new Color[] {Color.Red, Color.Blue, Color.Green, Color.Yellow, Color.Black, Color.Aqua, Color.Brown, Color.Cyan, Color.Gray,Color.Pink};
lstColor.DataSource = data;
g = Graphics.FromHwnd(lstColor.Handle);
sf = new StringFormat(StringFormat.GenericTypographic);
}
And you are all set.
Hope this helps
Check out http://converter.telerik.com/ It converts code from VB.NET to C# and C# to VB.NET. It wont work on complex code, but could prove useful to you.