Sorry for this question, but I've been Googling "C# vertical menu bar" for a while, and I can't find one that looks something like this:
No, I'm not making a survey locker, but that's the only image I could find of what I'm looking for.
Could anyone tell me how to do this?
You can creat custom User Control that Inherit from Tab Control.
For Windows Forms, Follow Below Steps:
Right Click Project -> Add New Item -> User Control(C#)
Inherit from TabControl and write below code in Default Constructor
3 Override OnPaint Method to manually Design Tab Control
Save it
Add it to your Form from toolbox.
Set Dock Property to Fill and Alignment Property to Left of Control
Add more Tabs
Hope this Helps!
class CustomControl : TabControl
{
public CustomControl()
{
SetStyle(ControlStyles.AllPaintingInWmPaint , true);
SetStyle(ControlStyles.OptimizedDoubleBuffer , true);
SetStyle(ControlStyles.ResizeRedraw, true);
SetStyle(ControlStyles.UserPaint, true);
DoubleBuffered = true;
SizeMode = TabSizeMode.Fixed;
ItemSize = new System.Drawing.Size(30, 120);
}
protected override void OnPaint(PaintEventArgs e)
{
var B = new Bitmap(Width, Height);
var G = (Graphics)Graphics.FromImage(B);
G.Clear(Color.Gainsboro);
for (int i = 0; i < TabCount -1; i++)
{
var TabRectangle = (Rectangle)GetTabRect(i);
if (i == SelectedIndex)
{
G.FillRectangle(Brushes.Navy, TabRectangle);
}
else
{
G.FillRectangle(Brushes.BlueViolet, TabRectangle);
}
G.DrawString(TabPages[i].Text, Font, Brushes.White, TabRectangle, new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center });
TabPages[i].Font = new Font(TabPages[i].Font, FontStyle.Strikeout);
}
e.Graphics.DrawImage((Image)B.Clone(),0,0);
G.Dispose();
B.Dispose();
base.OnPaint(e);
}
Happy Coding!
Assuming WPF, just plop a menu thats taller than its wider and add menu items
Related
I am creating windows Tabbed Application. Everything is good but the tabs are quiet faded and borders are very dull. I have tried changing the border style to 3D as well but no effect. Below is the screenshot
There are forums where people have suggested to use third party library to make Google Chrome type tabs. But I want the native way to get beautiful tabs.
You can take control of how the tabs are drawn by setting the DrawMode = TabDrawMode.OwnerDrawFixed. The example below assumes you have a TabControl named tabControl1 on the form, this will add a new tab with a blue box.
private Rectangle myTabRect;
private Rectangle myInsideRect;
private Rectangle myOutsideRect;
public Form1()
{
InitializeComponent();
TabPage tabPage1 = new TabPage();
// Sets the tabs to be drawn by the parent window Form1.
// OwnerDrawFixed allows access to DrawItem.
tabControl1.DrawMode = TabDrawMode.OwnerDrawFixed;
tabControl1.Controls.Add(tabPage1);
tabControl1.Location = new Point(25, 25);
tabControl1.Size = new Size(250, 250);
tabPage1.TabIndex = 0;
myTabRect = tabControl1.GetTabRect(0);
myInsideRect = new Rectangle(tabControl1.DisplayRectangle.X -1, tabControl1.DisplayRectangle.Y -1, tabControl1.DisplayRectangle.Width + 1, tabControl1.DisplayRectangle.Height + 1);
myOutsideRect = tabControl1.ClientRectangle;
myOutsideRect.Width--;
myOutsideRect.Height--;
ClientSize = new Size(300, 500);
Controls.Add(tabControl1);
tabControl1.DrawItem += new DrawItemEventHandler(OnDrawItem);
}
private void OnDrawItem(object sender, DrawItemEventArgs e)
{
// Draw your tab graphics here
Graphics g = e.Graphics;
Pen p = new Pen(Color.Blue);
g.DrawRectangle(p, myTabRect);
p = new Pen(Color.Red);
g.DrawRectangle(p, myInsideRect);
p = new Pen(Color.Green);
g.DrawRectangle(p, myOutsideRect);
}
You can draw whatever style you like into the graphic context, add text, images, etc
How would I go about drawing a border with a specified width and color around a listbox?
Can this be done without overriding the OnPaint method?
Following Neutone's suggestion, here is a handy function to add and remove a Panel-based border around any control, even if it is nested..
Simply pass in the Color and size you want, and if you want a BorderStyle. To remove it again pass in Color.Transparent!
void setBorder(Control ctl, Color col, int width, BorderStyle style)
{
if (col == Color.Transparent)
{
Panel pan = ctl.Parent as Panel;
if (pan == null) { throw new Exception("control not in border panel!");}
ctl.Location = new Point(pan.Left + width, pan.Top + width);
ctl.Parent = pan.Parent;
pan.Dispose();
}
else
{
Panel pan = new Panel();
pan.BorderStyle = style;
pan.Size = new Size(ctl.Width + width * 2, ctl.Height + width * 2);
pan.Location = new Point(ctl.Left - width, ctl.Top - width);
pan.BackColor = col;
pan.Parent = ctl.Parent;
ctl.Parent = pan;
ctl.Location = new Point(width, width);
}
}
You can place a list box within a panel and have the panel serve as a border. The panel backcolor can be used to create a colored border. This doesn't require much code. Having a colored border around a form component can be an effective way of conveying status.
The problem with the ListBox control is that it does not raise the OnPaint method so you can not use it to draw a border around the control.
There are two methods to paint a custom border around the ListBox:
Use SetStyle(ControlStyles.UserPaint, True) in the constructor, then you can use the OnPaint method to draw the border.
Override WndProc method that handles operating system messages identified in the Message structure.
I used the last method to paint a custom border around the control, this will eliminate the need to use a Panel to provide a custom border for the ListBox.
public partial class MyListBox : ListBox
{
public MyListBox()
{
// SetStyle(ControlStyles.UserPaint, True)
BorderStyle = BorderStyle.None;
}
protected override void WndProc(ref Message m)
{
base.WndProc(m);
var switchExpr = m.Msg;
switch (switchExpr)
{
case 0xF:
{
Graphics g = this.CreateGraphics;
g.SmoothingMode = Drawing2D.SmoothingMode.Default;
int borderWidth = 4;
Rectangle rect = ClientRectangle;
using (var p = new Pen(Color.Red, borderWidth) { Alignment = Drawing2D.PenAlignment.Center })
{
g.DrawRectangle(p, rect);
}
break;
}
default:
{
break;
}
}
}
}
I am making an application in C# .NET. I have 8 picture boxes in it. I used PNG images with transparent background but in my form it is not transparent when it comes above another image.
I am using Visual Studio 2012. This is a screenshot of my form:
One way to do this is by changing the parent of the overlapping picture box to the PictureBox over which it is lapping. Since the Visual Studio designer doesn't allow you to add a PictureBox to a PictureBox, this will have to be done in your code (Form1.cs) and within the Intializing function:
public Form1()
{
InitializeComponent();
pictureBox7.Controls.Add(pictureBox8);
pictureBox8.Location = new Point(0, 0);
pictureBox8.BackColor = Color.Transparent;
}
Just change the picture box names to what ever you need. This should return:
GameBoard is control of type DataGridView;
The image should be type of PNG with transparent alpha channel background;
Image test = Properties.Resources.checker_black;
PictureBox b = new PictureBox();
b.Parent = GameBoard;
b.Image = test;
b.Width = test.Width*2;
b.Height = test.Height*2;
b.Location = new Point(0, 90);
b.BackColor = Color.Transparent;
b.BringToFront();
Try using an ImageList
ImageList imgList = new ImageList;
imgList.TransparentColor = Color.White;
Load the image like this:
picturebox.Image = imgList.Images[img_index];
I've had a similar problem like this.
You can not make Transparent picturebox easily such as picture that shown at top of this page, because .NET Framework and VS .NET objects are created by INHERITANCE! (Use Parent Property).
I solved this problem by RectangleShape and with the below code I removed background,
if difference between PictureBox and RectangleShape is not important and doesn't matter, you can use RectangleShape easily.
private void CreateBox(int X, int Y, int ObjectType)
{
ShapeContainer canvas = new ShapeContainer();
RectangleShape box = new RectangleShape();
box.Parent = canvas;
box.Size = new System.Drawing.Size(100, 90);
box.Location = new System.Drawing.Point(X, Y);
box.Name = "Box" + ObjectType.ToString();
box.BackColor = Color.Transparent;
box.BorderColor = Color.Transparent;
box.BackgroundImage = img.Images[ObjectType];// Load from imageBox Or any resource
box.BackgroundImageLayout = ImageLayout.Stretch;
box.BorderWidth = 0;
canvas.Controls.Add(box); // For feature use
}
One fast solution is set image property for image1 and set backgroundimage property to imag2, the only inconvenience is that you have the two images inside the picture box, but you can change background properties to tile, streched, etc. Make sure that backcolor be transparent.
Hope this helps
Just use the Form Paint method and draw every Picturebox on it, it allows transparency :
private void frmGame_Paint(object sender, PaintEventArgs e)
{
DoubleBuffered = true;
for (int i = 0; i < Controls.Count; i++)
if (Controls[i].GetType() == typeof(PictureBox))
{
var p = Controls[i] as PictureBox;
p.Visible = false;
e.Graphics.DrawImage(p.Image, p.Left, p.Top, p.Width, p.Height);
}
}
you can set the PictureBox BackColor proprty to Transparent
I am using the TableLayoutPanel for example if I have 3 rows and 5 columns. I want to draw only the outer border for the entire panel. By default the the panel provides CellBorderStyle which adds all side borders to all the cells available. Is there any way where we can set only outside borders?
I have provided a sample code below.
TableLayoutPanel tblPanel = new TableLayoutPanel;
tblPanel.CellBorderStyle = TableLayoutPanelCellBorderStyle.Single;
Label lblName;
TextBox txtName;
Button btnAdd;
int colCnt = 0;
for(int rw =0; rw < 3; rw++)
{
lblName = new Label();
lblName.Name = "mylabel" + rw.ToString();
tblPanel.Controls.Add(lblName, colCnt, rw);
colCnt++;
txtName = new TextBox();
txtName.Name = "mytext" + rw.ToString();
tblPanel.Controls.Add(txtName, colCnt, rw);
colCnt++;
btnAdd = new Button();
btnAdd.Name = "mybutton" + rw.ToString();
tblPanel.Controls.Add(btnAdd, colCnt, rw);
colCnt = 0;
}
TableLayoutPanel does in fact support the BorderStyle property, which is what you want. For example:
tableLayoutPanel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
https://msdn.microsoft.com/en-us/library/system.windows.forms.tablelayoutpanel.borderstyle(v=vs.110).aspx
It is decorated with:
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
So Intellisense won't show it to you, but it is documented and it works. I have no insight into why it is non-browsable.
You'd be better off painting the cell border yourself. Something along the following lines, then customize:
public TableForm() {
InitializeComponent();
this.tableLayoutPanel.CellPaint += tableLayoutPanel_CellPaint;
}
private void tableLayoutPanel_CellPaint(object sender, TableLayoutCellPaintEventArgs e) {
var topLeft = e.CellBounds.Location;
var topRight = new Point(e.CellBounds.Right, e.CellBounds.Top);
e.Graphics.DrawLine(Pens.Black, topLeft, topRight);
}
At design-time:
At runtime:
You can achieve by changing the property CellBorderStyle to Single or desired selection.
Property Change :
Sample :
TableLayOutPanel itself does not support a property for border except CellBorderStyle which is not what you want.
I suggest you to put your TableLayOutPanel into a Panel control and set Dock property of your TableLayOutPanel to Fill.
Then Set BorderStyle of Panel to what you want (FixedSingle or Fixed3D)
public TestForm()
{
InitializeComponent();
tableLayoutPanel.Paint += tableLayoutPanel_Paint;
}
private void tableLayoutPanel_Paint(object sender, PaintEventArgs e){
e.Graphics.DrawRectangle(new Pen(Color.Blue), e.ClipRectangle);
}
I have custom tab control where OnPaint method is override.
Then strange growth of tabs occurs. Tabs getting bigger (padding getting bigger) and they width depends on length of the text.
When I use default Tab Control - padding is OK. How to avoid this situation when I use UserPaint?
partial class Tab : TabControl
{
public Tab()
{
InitializeComponent();
Init();
}
private void Init()
{
this.SetStyle(ControlStyles.UserPaint, true);
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.DoubleBuffer, true);
this.SetStyle(ControlStyles.ResizeRedraw, true);
}
protected override void OnPaint(PaintEventArgs e)
{
DrawTabPane(e.Graphics);
}
private void DrawTabPane(Graphics g)
{
if (!Visible)
return;
// here we draw our tabs
for (int i = 0; i < this.TabCount; i++)
DrawTab(g, this.TabPages[i], i);
}
internal void DrawTab(Graphics g, TabPage tabPage, int nIndex)
{
Rectangle recBounds = this.GetTabRect(nIndex);
RectangleF tabTextArea = recBounds;
Point[] pt = new Point[4];
pt[0] = new Point(recBounds.Left + 1, recBounds.Bottom);
pt[1] = new Point(recBounds.Left + 1, recBounds.Top + 1);
pt[2] = new Point(recBounds.Right - 1, recBounds.Top + 1);
pt[3] = new Point(recBounds.Right - 1, recBounds.Bottom);
Brush br = new SolidBrush(clr_tab_norm);
g.FillPolygon(br, pt);
br.Dispose();
StringFormat stringFormat = new StringFormat();
stringFormat.Alignment = StringAlignment.Center;
stringFormat.LineAlignment = StringAlignment.Center;
br = new SolidBrush(clr_txt);
g.DrawString(tabPage.Text, Font, br, tabTextArea, stringFormat);
}
}
Turning on ControlStyles.UserPaint for controls that are built into Windows, like TabControl, is not the proper thing to do. I assume the bug is in GetTabRect(), it isn't visible in the snippet.
Instead, you should use the TabControl.DrawMode property and implement the DrawItem event. There's a good example in the MSDN Library.
It would appear from the image that your code is setting the size of the tabs to be wider than they need to be. The extra padding is present in all your tabs but it is just more visible in the tabs with longer text.
I can't be sure why this is but I'd guess that the code to calculate the size of the tabs (based on font metrics) is using a different font from that used to draw the tabs.