C# ToolStripProfessionalRender, event OnRenderItemText applied only on the first item - c#

I'm drawing a custom toolstrip using ToolStripProfessionalRender and editing the OnRenderItemText event as follows:
protected override void OnRenderItemText(ToolStripItemTextRenderEventArgs e)
{
e.Item.ForeColor = Clr.White;
e.Item.TextAlign = ContentAlignment.MiddleLeft;
e.Item.Alignment = ToolStripItemAlignment.Left;
base.OnRenderItemText(e);
if (e.Item.GetType() == typeof(ToolStripDropDownButton))
{
ToolStripDropDownButton tsmi = (ToolStripDropDownButton)e.Item;
if (tsmi.HasDropDownItems && tsmi.OwnerItem == null)
{
Rectangle bounds = tsmi.Bounds;
bounds.X = bounds.Right - 25;
bounds.Width = 25;
bounds.Y = 10;
// Draw the corner
Graphics G = e.Graphics;
SolidBrush brushw = new SolidBrush(Color.FromArgb(70,70,70));
Point[] points =
{
new Point(bounds.Right - 3, bounds.Height - 11), // point top right
new Point(bounds.Right - 3, bounds.Bottom - 14), // point bottom right
new Point(bounds.Right - 10, bounds.Bottom - 14) // point bottom left
};
G.FillPolygon(brushw, points);
}
}
}
and basically the output i'm trying to obtain is the following:
So drawing a little triangle on the bottom right corner when i got a ToolStripDropDownButton. The problem is that the little triangle is drawn only first item.
To end up the question i draw this toolstrip dynamically using a function that adds a dropdownbutton at each call.
ToolStripDropDownButton m_Item = new ToolStripDropDownButton(text, image);
m_Item.ImageAlign = ContentAlignment.MiddleCenter;
m_Item.ImageScaling = ToolStripItemImageScaling.None;
m_Item.Name = name;
m_Item.ForeColor = Color.White;
m_Item.BackColor = Color.FromArgb(95, 95, 95);
m_Item.Padding = new Padding(5);
m_Item.ShowDropDownArrow = false;
m_Item.Paint += new PaintEventHandler(this.PaintButtonBorder);
if (tabPage != null)
m_Item.Click += (sender, e) => AddClickTab(sender, e, tabPage);
((ToolStripDropDownMenu)m_Item.DropDown).ShowImageMargin = false;
((ToolStripDropDownMenu)m_Item.DropDown).ShowCheckMargin = false;
((ToolStripDropDownMenu)m_Item.DropDown).Cursor = Cursors.Hand;
toolStrip1.Items.Add(m_Item);
if (SubItems != null)
{
for(int i = 0; i < SubItems.Length; i++)
{
object[] subitem = (object[])SubItems[i];
FnAddToolStripMenuItem(
subitem[0].ToString(),
subitem[1].ToString(),
(Bitmap)subitem[2],
m_Item,
(TabPage)subitem[3]
);
}
}
Am i missing some "new" maybe?

Override the OnRenderItemText method only to draw the text part as it says, and/or to set the default properties used when rendering the text. To change the look and the shape of the arrows of the dropdown items, override the OnRenderArrow method.
Example
using System.Drawing;
using System.Drawing.Drawing2D;
protected override void OnRenderArrow(ToolStripArrowRenderEventArgs e)
{
// Optional: to be the default color of the arrows.
e.ArrowColor = Color.FromArgb(70, 70, 70);
if (e.Item is ToolStripDropDownButton item && item.OwnerItem == null)
{
var g = e.Graphics;
var r = new Rectangle(item.Bounds.Width - 10, item.Bounds.Height - 10, 8, 8);
g.SmoothingMode = SmoothingMode.AntiAlias;
g.PixelOffsetMode = PixelOffsetMode.Half;
using (var br = new SolidBrush(e.ArrowColor))
g.FillPolygon(br, new[]
{
new Point(r.Left, r.Bottom),
new Point(r.Right, r.Top),
new Point(r.Right, r.Bottom)
});
g.SmoothingMode = SmoothingMode.None;
g.PixelOffsetMode = PixelOffsetMode.Default;
}
else
base.OnRenderArrow(e);
}
protected override void OnRenderItemText(ToolStripItemTextRenderEventArgs e)
{
e.Item.ForeColor = Color.White;
e.Item.TextAlign = ContentAlignment.MiddleLeft;
e.Item.Alignment = ToolStripItemAlignment.Left;
base.OnRenderItemText(e);
}
Make sure to enable the ShowDropDownArrow property of the dropdown buttons. So comment this m_Item.ShowDropDownArrow = false;.
If you are also interested to change the color according to the current state of the dropdown button (Selected, Pressed), then you can do for example:
using (var br = new SolidBrush(item.Selected
? Color.FromArgb(150, 150, 150) : item.Pressed
? Color.FromArgb(100, 100, 100) :
Color.FromArgb(70, 70, 70)))
//...

Related

How to add callout in picturebox using C#?

I need to add WedgeRectCallout callout on picturebox using C#.
Is there a way to do it?
please refer image using below link to know about the callout.
In word document, I can do the same using Spire.Doc library and writing below code:
ShapeObject Shape1 = para1.AppendShape(30, 50, ShapeType.WedgeRectCallout);
Here is a minimal example. It creates a Panel subclass with a nested TextBox.
Note that you can't add controls to a PictureBox in the designer. Instead you can put it on top and use the Nest function to embed it in the PBox..
(I use a trick to simplify the drawing of the border: since shrinking a GraphicsPath is hard and I am too lazy to write out two of them, I draw the border twice and add a little offset. The effect is a shadow effect, which looks rather nice for a cheat..)
Here is the class in action:
And here is the class code:
class WedgeCallout : Panel
{
public WedgeCallout()
{
tb = new TextBox();
Controls.Add(tb);
}
TextBox tb = null;
GraphicsPath gp = new GraphicsPath();
protected override void OnLayout(LayoutEventArgs levent)
{
tb.Size = new Size(Width - 10, (int)(Height * 0.66));
tb.Location = new Point(5, 5);
tb.BackColor = BackColor;
tb.ForeColor = ForeColor ;
tb.BorderStyle = BorderStyle.None;
tb.Text = "Hiho";
tb.Multiline = true;
tb.TextAlign = HorizontalAlignment.Center;
tb.Font = Font;
SetRegion();
base.OnLayout(levent);
}
protected override void OnBackColorChanged(EventArgs e)
{
base.OnBackColorChanged(e);
if (BackColor != Color.Transparent)
tb.BackColor = BackColor;
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
if (Tag == null) return;
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
using(SolidBrush brush = new SolidBrush(tb.BackColor))
e.Graphics.FillPath(brush, (GraphicsPath)Tag);
using (Pen pen = new Pen(Color.DarkGray, 2f))
e.Graphics.DrawPath(pen, (GraphicsPath)Tag);
e.Graphics.TranslateTransform(-1, -1);
using (Pen pen = new Pen(ForeColor, 2f))
e.Graphics.DrawPath(pen, (GraphicsPath)Tag);
}
void SetRegion()
{
Rectangle r = ClientRectangle;
int h = (int)(r.Height * 0.75f);
if (gp != null) gp.Dispose();
gp = new GraphicsPath();
gp.AddPolygon(new PointF[]{ new Point(0,0),
new Point(r.Width-1, 0), new Point(r.Width-1, h),
new PointF(50, h) , new Point(0, r.Height-1),
new PointF(20, h), new PointF(0, h)});
Region = new Region(gp);
Tag = gp;
}
}
You can set the colors and the Font in the designer..
And the Nest function:
void Nest(Control child, Control parent)
{
Point p0 = parent.PointToScreen(Point.Empty);
Point p1 = child.PointToScreen(Point.Empty);
child.Location = new Point(p1.X - p0.X, p1.Y - p0.Y);
child.Parent = parent;
}
It is called from the Form where the controls sit: Nest(wedgeCallout1, pictureBox1);
Note that to save to callout with the pbox in one image you need to
Nest the callout in the PBox
Use pbox.DrawToBitmap
Temporarily set the backcolor to transparent
Example:
private void saveBtn_Click(object sender, EventArgs e)
{
Size sz = pictureBox1.ClientSize;
using (Bitmap bmp = new Bitmap(sz.Width, sz.Height))
{
Color old = wedgeCallout1.BackColor;
wedgeCallout1.BackColor = Color.Transparent;
pictureBox1.DrawToBitmap(bmp, pictureBox1.ClientRectangle);
bmp.Save(filename, ImageFormat.Png);
wedgeCallout1.BackColor = old;
}
}

CheckedListBox: How to increase size of checkbox and change color of tick mark

I want to override default look of CheckedListBox as below:
Please Note the increased size of checkbox and colored tick mark.
For this you need to create own custom control by inheriting CheckedListbox and need to override OnDrawItem(DrawItemEventArgs e) event
Below is the Code :
class BigCheckedListBox : CheckedListBox
{
public BigCheckedListBox()
{
ForeColor = Color.Turquoise;
Font = new Font("Segoe UI", 12f);
}
protected override void OnDrawItem(DrawItemEventArgs e)
{
e.DrawBackground();
var b = e.Bounds;
var state = GetItemChecked(e.Index) ? CheckBoxState.CheckedNormal : CheckBoxState.UncheckedNormal;
Size glyphSize = CheckBoxRenderer.GetGlyphSize(e.Graphics, state);
int checkPad = (b.Height - glyphSize.Height) / 2;
var pt = new Point(b.X + checkPad, b.Y + checkPad);
Rectangle rect = new Rectangle(pt, new Size(20, 20));
e.Graphics.DrawRectangle(Pens.Green, rect);//This is for Checkbox rectangle
//This is for drawing string text
using (SolidBrush brush = new SolidBrush(ForeColor))
e.Graphics.DrawString(this.Items[e.Index].ToString(), Font, brush, pt.X + 27f, pt.Y);
if (state == CheckBoxState.CheckedNormal)
{
using (SolidBrush brush = new SolidBrush(ForeColor))
using (Font wing = new Font("Wingdings", 17f, FontStyle.Bold))
e.Graphics.DrawString("ΓΌ", wing, brush, pt.X-4, pt.Y-1); //This is For tick mark
}
}
}
Hope this will serve the purpose.

How to move PictureBox in TableLayoutPanel grid from keyboard?

I'm quite new at C#, but I'm trying to move a picturebox, by pressing the up-down-left-right keys from the keyboard, in a grid TableLayoutPanel(I made the grid at runtime). The grid is 23x23, has brickblock images border(each cell at the border contains a brickblock image in an imagebox) and an imagebox with a mouse in the middle. What I'm trying to do is moving the mouse image from the central cell(which is 11x11) in another cell by pressing one of the control keys mentioned above. It seems I can't get a grip on the idea of eventHandler... . The code works very good 'till I want to make the picturebox move. I've put the whole code, maybe the problem is in a place I didn't notice, but I think that the problem is KeyDown += new KeyEventHandler(Form2_KeyDown) or/end private void Form2_KeyDown(object sender, KeyEventArgs e){...} .
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace IndividualProject
{
public partial class Form2 : Form
{
PictureBox picturebox5 = new PictureBox
{
Visible = true,
Anchor = AnchorStyles.Top,
SizeMode = PictureBoxSizeMode.Normal,
Dock = DockStyle.Fill,
Margin = new Padding(0)
};
public Form2()
{
InitializeComponent();
// MaximizeBox = false;
//size
int h = Screen.PrimaryScreen.WorkingArea.Height / 2;
int w = Screen.PrimaryScreen.WorkingArea.Width / 2;
Size = new Size(w / 2 + w / 7, h + h / 4 + h / 7);
//location
StartPosition = FormStartPosition.CenterScreen;
//form style
FormBorderStyle = FormBorderStyle.FixedSingle;
//menuStrip1.BackColor = Color.Beige;
//lives and score container
#region livesAndScore
lasContainer.Size = new Size(Width / 2 + Width / 3 + Width / 7, Height / 13);
lasContainer.BackColor = Color.Lavender;
lasContainer.BorderStyle = BorderStyle.Fixed3D;
lasContainer.Dock = DockStyle.Top;
lasContainer.SplitterDistance = Width / 2 - Width / 69;
//labels
lives.Location = new Point(lasContainer.Panel1.Width / 12, lives.Height / 2);
score.Location = new Point(lasContainer.Panel2.Width / 12, score.Height / 2);
//picturebox
live3.Location = new Point(lasContainer.Panel1.Width / 3, lives.Height / 2);
live2.Location = new Point(lasContainer.Panel1.Width / 2, lives.Height / 2);
live1.Location = new Point(lasContainer.Panel1.Width / 2 + lasContainer.Panel1.Width / 6, lives.Height / 2);
#endregion livesAndScore
//gamePanel
gamePanel.Dock = DockStyle.Fill;
gamePanel.BackColor = Color.SkyBlue;
gamePanel.CellBorderStyle = TableLayoutPanelCellBorderStyle.Single; // REMOVE WHEN FINISHED !!!!!!!!!!!
//making the grid
#region grid
gamePanel.ColumnCount = 23;
gamePanel.RowCount = 23;
gamePanel.ColumnStyles.Clear();
gamePanel.RowStyles.Clear();
int iIndex, jIndex = 0;
for (iIndex = 0; iIndex < gamePanel.ColumnCount; iIndex++)
{
gamePanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 4.34F));
gamePanel.RowStyles.Add(new RowStyle(SizeType.Percent, 4.34F));
}
#endregion grid
while(jIndex < gamePanel.ColumnCount)
{
#region picturebox1
PictureBox picturebox1 = new PictureBox
{
Visible = true,
Anchor = AnchorStyles.Top,
SizeMode = PictureBoxSizeMode.Normal,
BackColor = Color.Sienna,
Dock = DockStyle.Fill,
Margin = new Padding(0)
};
if(jIndex < gamePanel.ColumnCount - 1)
{
gamePanel.Controls.Add(picturebox1, jIndex, 0);
picturebox1.ImageLocation = #"..\..\ResourcesPh\brickblock.png";
}
#endregion picturebox1
#region picturebox2
PictureBox picturebox2 = new PictureBox
{
Visible = true,
Anchor = AnchorStyles.Top,
SizeMode = PictureBoxSizeMode.Normal,
BackColor = Color.Sienna,
Dock = DockStyle.Fill,
Margin = new Padding(0)
};
if (jIndex < gamePanel.ColumnCount - 1)
{
gamePanel.Controls.Add(picturebox2, 0, jIndex + 1);
picturebox2.ImageLocation = #"..\..\ResourcesPh\brickblock.png";
}
#endregion picturebox2
#region picturebox3
PictureBox picturebox3 = new PictureBox
{
Visible = true,
Anchor = AnchorStyles.Top,
SizeMode = PictureBoxSizeMode.Normal,
BackColor = Color.Sienna,
Dock = DockStyle.Fill,
Margin = new Padding(0)
};
if(jIndex < gamePanel.ColumnCount - 1)
{
gamePanel.Controls.Add(picturebox3, gamePanel.ColumnCount - 1 - jIndex, gamePanel.RowCount - 1);
picturebox3.ImageLocation = #"..\..\ResourcesPh\brickblock.png";
}
#endregion picturebox3
#region picturebox4
PictureBox picturebox4 = new PictureBox
{
Visible = true,
Anchor = AnchorStyles.Top,
SizeMode = PictureBoxSizeMode.Normal,
BackColor = Color.Sienna,
Dock = DockStyle.Fill,
Margin = new Padding(0),
};
if(jIndex < gamePanel.ColumnCount - 1)
{
gamePanel.Controls.Add(picturebox4, gamePanel.ColumnCount - 1, gamePanel.RowCount - 1 - jIndex - 1);
picturebox4.ImageLocation = #"..\..\ResourcesPh\brickblock.png";
}
#endregion picturebox4
jIndex++;
}
//the starting point of the mouse
#region mouseStartPoint
//PictureBox picturebox5 = new PictureBox
//{
// Visible = true,
// Anchor = AnchorStyles.Top,
// SizeMode = PictureBoxSizeMode.Normal,
// BackColor = Color.Sienna,
// Dock = DockStyle.Fill,
// Margin = new Padding(0)
//};
gamePanel.Controls.Add(picturebox5, 11, 11);
picturebox5.ImageLocation = #"..\..\ResourcesPh\mouse.png";
#endregion mouseStartPoint
KeyDown += new KeyEventHandler(Form2_KeyDown);
}
private void Form2_KeyDown(object sender, KeyEventArgs e)
{
int x = 11, y = 11;
if (e.KeyCode == Keys.Right)
x += 1;
if (e.KeyCode == Keys.Left)
x -= 1;
if (e.KeyCode == Keys.Up)
y -= 1;
if (e.KeyCode == Keys.Down)
y += 1;
gamePanel.Controls.Remove(picturebox5);
gamePanel.Controls.Add(picturebox5, x, y);
picturebox5.ImageLocation = #"..\..\ResourcesPh\mouse.png";
Refresh();
}
private void howToPlayToolStripMenuItem_Click(object sender, EventArgs e)
{
Hide();
Form3 f3 = new Form3();
f3.FormClosed += (s, args) => Close(); //event handler on closing Form2 after Form3 is opened
f3.Show();
}
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
Application.Exit();
}
}
}
TableLayoutPanel Grid
You are always setting the starting position back to 11, 11 on every key click. Move your declaration outside of that scope:
int x = 11, y = 11;
private void Form2_KeyDown(object sender, KeyEventArgs e) {
Here's a greatly simplified approach for moving your mouse, I get straight to the point and kept things to a bare minimum, yet effective :D
Here are the tiles I've used:
And here's the code !
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
namespace WindowsFormsApplication3
{
public partial class Form1 : Form
{
private Dictionary<int, Image> _dictionary;
private Size _imageSize;
private int[] _level;
private Size _levelSize;
private Point _mousePos;
public Form1()
{
InitializeComponent();
pictureBox1.Paint += PictureBox1_Paint;
}
private void Form1_Load(object sender, EventArgs e)
{
InitializeLevel();
Redraw();
}
private void InitializeLevel()
{
var imageEmpty = Image.FromFile("empty.png");
var imageMouse = Image.FromFile("mouse.png");
var imageWall = Image.FromFile("wall.png");
_level = new[]
{
0, 0, 0, 0, 0,
0, 1, 1, 1, 0,
0, 1, 1, 1, 0,
0, 1, 1, 1, 0,
0, 0, 0, 0, 0
};
_levelSize = new Size(5, 5);
_imageSize = new Size(25, 25);
_dictionary = new Dictionary<int, Image>();
_dictionary.Add(0, imageWall);
_dictionary.Add(1, imageEmpty);
_dictionary.Add(2, imageMouse);
_mousePos = new Point();
}
private void Redraw()
{
pictureBox1.Invalidate();
}
private void PictureBox1_Paint(object sender, PaintEventArgs e)
{
var graphics = e.Graphics;
graphics.Clear(Color.Transparent);
// draw level
var i = 0;
foreach (var tile in _level)
{
var x = i % _levelSize.Width;
var y = i / _levelSize.Width;
var image = _dictionary[tile];
graphics.DrawImage(image, new Point(x * _imageSize.Width, y * _imageSize.Height));
i++;
}
// draw hero !
graphics.DrawImage(_dictionary[2], _mousePos);
}
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
var up = keyData == Keys.Up;
var down = keyData == Keys.Down;
var left = keyData == Keys.Left;
var right = keyData == Keys.Right;
var processed = up || down || left || right;
if (!processed) return base.ProcessCmdKey(ref msg, keyData);
// move the hero !
var x = 0;
var y = 0;
if (left) x--;
if (right) x++;
if (up) y--;
if (down) y++;
_mousePos.X += x;
_mousePos.Y += y;
Redraw();
return true;
}
}
}
Obviously you'll still want to check collisions, define your logic and such ...
Go on and give it a try !
Welcome to SO and good luck :D

How to change the background color of unused space tab in C# winforms?

Ex
|Tab1|Tab2|Tab3| { }
| |
| |
| |
| |
|_____________________|
I am able to change the backcolor and forecolor of Tab.. but I want to change the color of that { } -- > Empty space is this possible to do that. .. It shows default winforms color..help me in dis..
private void Form1_Load(object sender, EventArgs e)
{
}
private void tabControl1_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e)
{
Font fntTab;
Brush bshBack;
Brush bshFore;
if ( e.Index == this.tabControl1.SelectedIndex)
{
fntTab = new Font(e.Font, FontStyle.Bold);
bshBack = new System.Drawing.Drawing2D.LinearGradientBrush(e.Bounds, SystemColors.Control, SystemColors.Control, System.Drawing.Drawing2D.LinearGradientMode.BackwardDiagonal);
bshFore = Brushes.Black;
//bshBack = new System.Drawing.Drawing2D.LinearGradientBrush(e.Bounds, Color.LightSkyBlue , Color.LightGreen, System.Drawing.Drawing2D.LinearGradientMode.BackwardDiagonal);
//bshFore = Brushes.Blue;
}
else
{
fntTab = e.Font;
bshBack = new SolidBrush(Color.Red);
bshFore = new SolidBrush(Color.Aqua);
//bshBack = new SolidBrush(Color.White);
//bshFore = new SolidBrush(Color.Black);
}
string tabName = this.tabControl1.TabPages[e.Index].Text;
StringFormat sftTab = new StringFormat();
e.Graphics.FillRectangle(bshBack, e.Bounds);
Rectangle recTab = e.Bounds;
recTab = new Rectangle( recTab.X, recTab.Y + 4, recTab.Width, recTab.Height - 4);
e.Graphics.DrawString(tabName, fntTab, bshFore, recTab, sftTab);
}
Try adding the following code to your DrawItem event handler. Don't forget to set the DrawMode to "OwnerdrawFixed".
You might have to tweak it a bit to cover some margins which aren't painted.
private void tabControl1_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e)
{
SolidBrush fillbrush= new SolidBrush(Color.Red);
//draw rectangle behind the tabs
Rectangle lasttabrect = tabControl1.GetTabRect(tabControl1.TabPages.Count - 1);
Rectangle background = new Rectangle();
background.Location = new Point(lasttabrect.Right, 0);
//pad the rectangle to cover the 1 pixel line between the top of the tabpage and the start of the tabs
background.Size = new Size(tabControl1.Right - background.Left, lasttabrect.Height+1);
e.Graphics.FillRectangle(fillBrush, background);
}
'This answer is much better than prior one. But the tabCtrl is not defined. It has to be tabControl1 control.
I think the only way to give that space a color is to override the OnPaintBackground method of the window, so just paste this on your form (window)
you must also change the Appearance Property to "Normal"
private void Form1_Load(object sender, EventArgs e)
{
}
protected override void OnPaintBackground(PaintEventArgs e)
{
base.OnPaintBackground(e);
Rectangle lasttabrect = tabControl1.GetTabRect(tabControl1.TabPages.Count - 1);
RectangleF emptyspacerect = new RectangleF(
lasttabrect.X + lasttabrect.Width + tabControl1.Left,
tabControl1.Top + lasttabrect.Y,
tabControl1.Width - (lasttabrect.X + lasttabrect.Width),
lasttabrect.Height);
Brush b = Brushes.BlueViolet; // the color you want
e.Graphics.FillRectangle(b, emptyspacerect );
}
for me it's working perfectly
you can also create a custom tabcontrol as you did
public class mytab : TabControl
{
public mytab()
: base()
{
this.DrawMode = TabDrawMode.OwnerDrawFixed;
this.DrawItem += new DrawItemEventHandler(tabControl1_DrawItem);
}
private void tabControl1_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e)
{
Font fntTab;
Brush bshBack;
Brush bshFore;
if (e.Index == this.SelectedIndex)
{
fntTab = new Font(e.Font, FontStyle.Bold);
bshBack = new System.Drawing.Drawing2D.LinearGradientBrush(e.Bounds, SystemColors.Control, SystemColors.Control, System.Drawing.Drawing2D.LinearGradientMode.BackwardDiagonal);
bshFore = Brushes.Black;
//bshBack = new System.Drawing.Drawing2D.LinearGradientBrush(e.Bounds, Color.LightSkyBlue , Color.LightGreen, System.Drawing.Drawing2D.LinearGradientMode.BackwardDiagonal);
//bshFore = Brushes.Blue;
}
else
{
fntTab = e.Font;
bshBack = new SolidBrush(Color.Red);
bshFore = new SolidBrush(Color.Aqua);
//bshBack = new SolidBrush(Color.White);
//bshFore = new SolidBrush(Color.Black);
}
string tabName = this.TabPages[e.Index].Text;
StringFormat sftTab = new StringFormat();
e.Graphics.FillRectangle(bshBack, e.Bounds);
Rectangle recTab = e.Bounds;
recTab = new Rectangle(recTab.X, recTab.Y + 4, recTab.Width, recTab.Height - 4);
e.Graphics.DrawString(tabName, fntTab, bshFore, recTab, sftTab);
Rectangle r = this.GetTabRect(this.TabPages.Count - 1);
RectangleF tf =
new RectangleF(r.X + r.Width,
r.Y-5, this.Width - (r.X + r.Width)+5, r.Height+5);
Brush b = Brushes.BlueViolet;
e.Graphics.FillRectangle(b, tf);
}
}

picture box invalidate method in C#

I want to draw something in a picture box and remove them.
in this case i need to draw a fill circle and after a time remove it and draw a circle without fill it.
i use below code but when i want to remove a shape i need to draw picturebox another time with new shape and it causes a sensitive change in picture box.now i know i should use invalidate() method. but i do not know where and how should i use that.
void pbmapDo()
{
Graphics graphicPBMap = pbMap.CreateGraphics();
// usually Values : gridNeedUpdate = true; rulersNeedUpdate = true; rulerNeedUpdate = true; backGroundNeedUpdate = true; nodesNeedUpdate = true;
if (backGroundNeedUpdate)
{
Bitmap srce = new Bitmap(BackGround);
Bitmap dest = new Bitmap(pbMap.Width, pbMap.Height, System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
Graphics gr = Graphics.FromImage(dest);
gr.DrawImage(srce, new Rectangle(Point.Empty, dest.Size));
graphicPBMap.DrawImage(dest, 0, 0);
}
backGroundNeedUpdate = false;
if (isGridShow && gridNeedUpdate)
{
for (int i = 0; i < pbMap.Width / 60 + 1; i++)
{
graphicPBMap.DrawLine(gridPen, pbMap.Width - i * 60, 0, pbMap.Width - i * 60, pbMap.Height);
}
for (int i = 0; i < pbMap.Height / 60 + 1; i++)
{
graphicPBMap.DrawLine(gridPen, pbMap.Width, i * 60, 0, i * 60);
}
}
gridNeedUpdate = false;
if (isShowRulers && rulersNeedUpdate )
{
graphicPBMap.DrawLine(new Pen(Brushes.Black, 46), pbMap.Width - 1, pbMap.Height - 1, 0 - 1, pbMap.Height - 1);
graphicPBMap.DrawLine(new Pen(Brushes.Black, 49), 0, 0, 0, pbMap.Height);
for (int i = 0; i < pbMap.Width / 60 + 1; i++)
{
graphicPBMap.DrawString(XPixelToLong((double)pbMap.Width - i * 60).ToString(), new Font("Tahoma", 7), Brushes.White, pbMap.Width - i * 60, pbMap.Height - 15);
graphicPBMap.DrawLine(gridPen, pbMap.Width - i * 60, pbMap.Height - 24, pbMap.Width - i * 60, pbMap.Height);
}
for (int i = 0; i < pbMap.Height / 60 + 1; i++)
{
graphicPBMap.DrawLine(gridPen, 0, i * 60, 25, i * 60);
graphicPBMap.DrawString(YPixelToLat(i * 60).ToString(), new Font("Tahoma", 7), Brushes.White, 0, i * 60);
}
}
rulersNeedUpdate = false;
if (rulerNeedUpdate)
{
if (x0ruler != -1 && y0ruler != -1)
{
if (x1ruler != -1 && y1ruler != -1)
{
Rectangle rectAngle = new Rectangle((int)(x1ruler - 1), (int)(y1ruler - 1), 2, 2);
graphicPBMap.DrawEllipse(rulerPen, rectAngle);
graphicPBMap.DrawLine(rulerPen, x0ruler, y0ruler, x1ruler, y1ruler);
rectAngle = new Rectangle((int)(x0ruler - 1), (int)(y0ruler - 1), 2, 2);
graphicPBMap.DrawEllipse(rulerPen, rectAngle);
}
else
{
Rectangle rectAngle = new Rectangle((int)(x0ruler - 1), (int)(y0ruler - 1), 2, 2);
graphicPBMap.DrawEllipse(rulerPen, rectAngle);
}
}
}
rulerNeedUpdate = false;
if (nodesNeedUpdate)
{
nodesNeedUpdate = false;
Node node;
for (int i = 0; i < nodes.Count; i++)
{
node = (Node)(nodes[i]);
if (node.IsOn)
{
drawOnCircle(graphicPBMap,node.Longitude, node.Latitude, node.RInMeter, node.IsSelected);
}
else
{
drawOffCircle(graphicPBMap, node.Longitude, node.Latitude, node.RInMeter, node.IsSelected);
}
}
}
}
EDIT 1 :
i changed code once.
You can use
invalidate() or pictureBox.image = null; where you need to change the image of your picturebox.
Anyway, it is not required to change the background always. Instead you can make your bitmap and place it as pictureBox.Image = bitmap.
If you need exact sample source code let me know.
sorry for the late.
try this
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
Bitmap bckMap = null;
private void Form1_Load(object sender, EventArgs e)
{
bckMap = new Bitmap(this.pictureBox1.Width, this.pictureBox1.Height);
using (Graphics g = Graphics.FromImage(bckMap))
{
g.FillRectangle(new SolidBrush(Color.Black), new Rectangle(0, 0, bckMap.Width, bckMap.Height));
g.Dispose();
}
pictureBox1.BackgroundImage = bckMap;
}
private void button2_Click(object sender, EventArgs e)
{
pictureBox1.Image = null;
Bitmap ellips = new Bitmap(this.pictureBox1.Width, this.pictureBox1.Height);
using (Graphics g = Graphics.FromImage(ellips))
{
g.FillEllipse(new SolidBrush(Color.Red), new Rectangle(0, 0, ellips.Width, ellips.Height));
g.Dispose();
}
this.pictureBox1.Image = ellips;
}
private void button1_Click(object sender, EventArgs e)
{
pictureBox1.Image = null;
Bitmap ellips = new Bitmap(this.pictureBox1.Width, this.pictureBox1.Height);
using (Graphics g = Graphics.FromImage(ellips))
{
g.FillRectangle(new SolidBrush(Color.Green), new Rectangle(5, 5, ellips.Width-10, ellips.Height-10));
g.Dispose();
}
this.pictureBox1.Image = ellips;
}
I finally find a solution.
I need to use paint event of picture box.
private void pbMap_Paint(object sender, PaintEventArgs e)
{
//do every think you want with picture box like draw circle or change background
}
in this event i put every think i want to do with pbMap picture box.
and when i changed some i call below function to apply my changes,
public void updateMap()
{
if (pbMap.InvokeRequired) // just if you call in thread
{
pbMap.Invoke(new Action(() => pbMap.Invalidate()));
}
else
{
pbMap.Invalidate();
}
}

Categories

Resources