C# vertical tab control - c#

Can I make a tab control to look like the attached picture? I managed to add a tab control, but the text is still vertical. And I would want it to be horizontal.

There is an MSDN article about how to achieve this. How to: Display Side-Aligned Tabs with TabControl
The following procedure shows how to render right-aligned tabs, with the tab text running from left to right, by using the "owner draw" feature.

Try this TabStrip control. I believe this is what you want.

i think this is default selected color
private void tabControl1_DrawItem(Object sender, System.Windows.Forms.DrawItemEventArgs e)
{
...
if (e.State == DrawItemState.Selected)
{
// Draw a different background color, and don't paint a focus rectangle.
_textBrush = new SolidBrush(Color.Black);
g.FillRectangle(Brushes.White, e.Bounds);
}
else
{
_textBrush = new System.Drawing.SolidBrush(e.ForeColor);
g.FillRectangle(Brushes.WhiteSmoke, e.Bounds);
}
...
image

Related

How to set the margins of text box red if error is present

I was just wondering if its was easily possible to set the margins of a textbox a particular color? Im using winforms and in my validating event handlers i have a series of error providers, which if return false I want to set just the margins red and if successful green. is this possible with out having a any controls hidden behind ? I know how to set the foreground and panel colour but it just seems so sloppy to have to have this all hidden behind it. this is my validating event handler.
private void txt_LndLine_Validating(object sender, CancelEventArgs e)
{
if (utility.isNum,(txt_LndLine.Text))
{
epLandline.SetError(txt_LndLine, "Please use unknown Entity!!!");
return;
}
else
{
epLandline.Clear();
_IsValid = true;
}
}
Just a query, as the event hadnler works fine just wouldn't mind a smarter way of presenting the errors rather than the icon
Here is an alternative solution, which won't add any extra controls. It paints the border onto the TextBoxes' Parent.
Set it up by hooking the routine into the Paint event of your TextBox's Parent once, maybe like this:
textBox1.Parent.Paint += DrawMargins;
Now you can set the Tag to hold the Brush you want to use:
textBox1.Tag = Brushes.Red;
textBox2.Tag = Brushes.Green;
After changing the Brush you need to trigger the routine, by Invalidating the Parent:
textBox1.Parent.Invalidate();
To take one TextBox out of the painting reset the Tag to null:
textBox1.Tag = null;
You can also un-hook the whole event of course:
textBox1.Parent.Paint -= DrawMargins;
Here is the drawing method:
private void DrawMargins(object sender, PaintEventArgs e)
{
Control parent = sender as Control;
foreach ( Control ctl in parent.Controls)
{
SolidBrush brush = ctl.Tag as SolidBrush;
if (brush == null) continue;
e.Graphics.FillRectangle(brush, ctl.Left - ctl.Margin.Left,
ctl.Top - ctl.Margin.Top,
ctl.Width + ctl.Margin.Horizontal,
ctl.Height + ctl.Margin.Vertical);
}
}
Note that this will work for any control which has a SolidBrush in the Tag and is a child of the same parent. If some controls as nested, say in a Panel or a GroupBox, I guees you should replace the loop over the parent.Controls collection by a List<Control> of the participating controls..
I have enlarged the left margin of the 1st TextBox, as you can see..
May be the answer in comments is a good one (#RudyTheHunter).
I have a simple way of doing.
Put a panel control right below the text box and change the border color of the panel.
I tried it and looks as shown in below image.
Code:
if (utility.isNum,(txt_LndLine.Text))
{
epLandline.SetError(txt_LndLine, "Please use unknown Entity!!!");
//PANEL COLOR
this.panel1.BackColor = System.Drawing.Color.Green;
this.panel1.Padding = new System.Windows.Forms.Padding(5);
return;
}
else
{
epLandline.Clear();
//PANEL COLOR
this.panel1.BackColor = System.Drawing.Color.Red;
this.panel1.Padding = new System.Windows.Forms.Padding(5);
_IsValid = true;
}

How to add Back and Fore Color on ContextMenu

I am Showing a ContextMenu whenever the user right clicks on a specific location in a DataGridView.
I want the items of that ContextMenu to have a back color and fore color depending on their content.
How can I do this since ContextMenu has no back color or Fore color property?
I tried looking up ContextMenuStrip but this has to be connected to a ToolStripButton which I do not have and do not want.
In order to change the back color of a MenuItem you need to specify a draw item handler and set owner-draw to true for each item. Also for the color to actually take some space you need to implement a MeasureMenuItem handler.
So for example
color.MenuItems.Add(new MenuItem("#123456", menuHandler));
color.MenuItems.Add(new MenuItem("Green", menuHandler));
color.MenuItems.Add(new MenuItem("Red", menuHandler));
foreach (MenuItem item in color.MenuItems)
{
item.OwnerDraw = true;
item.DrawItem += item_DrawItem;
item.MeasureItem += MeasureMenuItem;
}
The above codes hooks up the items and their handlers.
void item_DrawItem(object sender, DrawItemEventArgs e)
{
MenuItem cmb = sender as MenuItem;
string color = SystemColors.Window.ToString();
if (e.Index > -1)
{
color = cmb.Text;
}
if (checkHtmlColor(color))
{
e.DrawBackground();
e.Graphics.FillRectangle(new SolidBrush(ColorTranslator.FromHtml(color)), e.Bounds);
e.Graphics.DrawString(color, new Font("Lucida Sans", 10), new SolidBrush(ColorTranslator.FromHtml(color)), e.Bounds);
}
}
The above code takes the MenuItem contents, converts it to a color, creates a rectangle for that color and draws it.
void MeasureMenuItem(object sender, MeasureItemEventArgs e)
{
MenuItem m = (MenuItem)sender;
Font font = new Font(Font.FontFamily, Font.Size, Font.Style);
SizeF sze = e.Graphics.MeasureString(m.Text, font);
e.ItemHeight = (int)sze.Height;
e.ItemWidth = (int)sze.Width;
}
And lastly the above few lines simply measure the area the MenuItem should take before drawing (basically measures the space of it's string content) so the draw_item handler knows how much space to take up
I allow myself to dig up the post because I've had the same problem (add background color to MenuItem in ContextMenu) and found this post.
But the answer seemed very complicated. So I continued to search and find a simplet solution : Use ContextMenuStrip and ToolStripMenuItem
Here is an example for users who has the same problem :
ContextMenuStrip cMenu=new ContextMenuStrip();
ToolStripMenuItem mi;
// Item 1, null in constructor to say : no picture on the label
mi=new ToolStripMenuItem("item 1",null , (s,a)=> actionOnClicItem1());
mi.BackColor = Color.Red;
cMenu.Items.add(mi);
// Separator
cMenu.Items.Add(new ToolStripSeparator());
// Item 2
mi=new ToolStripMenuItem("item 2",null , (s,a)=> actionOnClicItem2());
mi.BackColor = Color.Blue;
cMenu.Items.add(mi);
// show the context menu near by the mouse pointer
cMenu.Show(myDataGridView,new Point(e.X,e.Y));
myToolStripMenuItem.GetCurrentParent().BackColor = Color.Red

change height of combobox in winform application

I'm developing an application for kind of touch screen device. In order be user friendly, I need to change size of combobox.
I've checked many thing including DrawItemEventHandler and MeasureItemEventHandler, but it didn't work as I want.
Basically I would like to change height of combobox without touching font size. When I change font size of combobox, it looks like left side of the image.
How can I set my combobox which will look like right side of the image?
By the way, don't know if it's effect solution, I am not using array string. I'm binding data like.
combobox.DisplayMember = "Name";
combobox.ValueMember = "ID";
combobox.DataSource = new BindingSource { DataSource = datalist };
Thanks in advance.
With TaW solution, I managed to set items as I want. The only thing I couldn't set text in middle when combobox items not droped down. How can I set this text position to the centre?
You can set the ItemHeight property and then draw the items yourself in the DrawItem event.
Not terribly hard, search for 'ownerdraw' & 'combobox'. There is one example on Code Project
Here is a minimal version, pulled from the above link:
private void comboBox1_DrawItem(object sender, DrawItemEventArgs e)
{
if (e.Index < 0) return;
Font f = comboBox1.Font;
int yOffset = 10;
if ((e.State & DrawItemState.Focus) == 0)
{
e.Graphics.FillRectangle(Brushes.White, e.Bounds);
e.Graphics.DrawString(comboBox1.Items[e.Index].ToString(), f, Brushes.Black,
new Point(e.Bounds.X, e.Bounds.Y + yOffset));
}
else
{
e.Graphics.FillRectangle(Brushes.Blue, e.Bounds);
e.Graphics.DrawString(comboBox1.Items[e.Index].ToString(), f, Brushes.White,
new Point(e.Bounds.X, e.Bounds.Y + yOffset));
}
}
You also have to set the DropDownStyle to DropDownList to get the highlighting to work and you need to set the DrawMode to OwnerDrawFixed. (Or to OwnerDrawVariable, if you want to have different heights for some itmes..)

tab control, vertically aligned tabs with vertically aligned text

I want to use a tab control and have the tabs displayed on the left, as opposed to at the top. I have set the alignment to the left and the tabs are displayed there. However, how do I get the text to be displayed on the tab, vertically? I have looked at the msdn and it gives an example of a left aligned tab control but the tab label is still displayed horisontally!
The other thing, does anybody know how to use the tab control with left aligned tabs with the default layout so that it looks better?
Please no third party apps unless they are free, and yes I have looked at code project already.
Thanks, R.
It is an age-old bug in the visual styles renderer for the native Windows tab control. It only supports tabs at the top, the Microsoft programmer that worked on it was run over by a bus before she could finish the job, I guess.
The only thing you can do about it is selectively turn off visual styles for the control. Add a new class to your project and paste the code shown below. Compile. Drop the new control from the top of the toolbox onto your form, replacing the original.
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
public class FixedTabControl : TabControl {
[DllImportAttribute("uxtheme.dll")]
private static extern int SetWindowTheme(IntPtr hWnd, string appname, string idlist);
protected override void OnHandleCreated(EventArgs e) {
SetWindowTheme(this.Handle, "", "");
base.OnHandleCreated(e);
}
}
If you create your own DrawItem event, you can manually write the tab headers. You could use this process:
1) Set the following properties of the TabControl:
Property | Value
----------|----------------
Alignment | Right (or left, depending on what you want)
SizeMode | Fixed
DrawMode | OwnerDrawFixed
2) Set the ItemSize.Width property to 25 and the ItemSize.Height property to 100. Adjust these values as you want, but remember that basically, the width is the height and vice versa.
3) Add an event handler for the DrawItem event and add the following code:
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. Because we CAN.
Font _TabFont = new Font("Arial", 10, 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));
}
4) Profit!
(original source: http://en.csharp-online.net/TabControl)

One word bold inside a text in winform control

I want some way to make a given word bold(the first two characters of each item in a listbox), and nothing else, something like this:
01 car
02 house
03 market
As for these three, being items in a listbox control, ALWAYS the first two characters, the rest should not be bold.
Is there any practical way for doing so ?
Data:
Visual Studio 2008
.NET 3.5
request:
private void lstMaster_DrawItem(object sender, DrawItemEventArgs e)
{
//TEST
e.DrawBackground();
Brush myBrush = Brushes.Black;
Pen pen = new Pen(myBrush);
e.Graphics.DrawRectangle(pen, 0, 0, 10, 10); //BREAKPOINT HERE
e.Graphics.DrawString("aaa" + lstMaster.Items[e.Index].ToString(),
e.Font, myBrush, e.Bounds, StringFormat.GenericDefault);
e.DrawFocusRectangle();
}
It just keept the same, no rectangle, no "AAA", or square no breakpoint reached...
It is possible, You will need to use the listbox's DrawItem event and from there you can draw your items however you would like to:
DrawItem event on MSDN
Here is an example that draws each item with different color:
private void ListBox1_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e)
{
// Draw the background of the ListBox control for each item.
e.DrawBackground();
// Define the default color of the brush as black.
Brush myBrush = Brushes.Black;
// Determine the color of the brush to draw each item based
// on the index of the item to draw.
switch (e.Index)
{
case 0:
myBrush = Brushes.Red;
break;
case 1:
myBrush = Brushes.Orange;
break;
case 2:
myBrush = Brushes.Purple;
break;
}
// Draw the current item text based on the current Font
// and the custom brush settings.
e.Graphics.DrawString(ListBox1.Items[e.Index].ToString(),
e.Font, myBrush, e.Bounds, StringFormat.GenericDefault);
// If the ListBox has focus, draw a focus rectangle around the selected item.
e.DrawFocusRectangle();
}
According to the documentation you will also need to change the DrawMode property of the listbox in order the fire the event:
This event is used by an owner-drawn ListBox. The event is only raised when the DrawMode property is set to DrawMode.OwnerDrawFixed or DrawMode.OwnerDrawVariable. You can use this event to perform the tasks needed to draw items in the ListBox.
I think that you can use HTML markup from VS 2008 onwards e.g. <b>01</b> car for 01 car, for some text. I'd have to check whether this applies to listboxes.

Categories

Resources