How to change Tab Control Background Color (VB.NET) - vb.net

how can I change the grey part into white color?
I want my tabcontrol filled with full white color.
So far what i did is like this:
Private Sub TabControl1_DrawItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawItemEventArgs) Handles TabControl1.DrawItem
Dim g As Graphics = e.Graphics
Dim tp As TabPage = TabControl1.TabPages(e.Index)
Dim br As Brush
Dim sf As New StringFormat
Dim r As New RectangleF(e.Bounds.X, e.Bounds.Y + 2, e.Bounds.Width, e.Bounds.Height - 2)
sf.Alignment = StringAlignment.Center
Dim strTitle As String = tp.Text
'If the current index is the Selected Index, change the color
If TabControl1.SelectedIndex = e.Index Then
'this is the background color of the tabpage header
br = New SolidBrush(Color.White) ' chnge to your choice
g.FillRectangle(br, e.Bounds)
'this is the foreground color of the text in the tab header
br = New SolidBrush(Color.Black) ' change to your choice
g.DrawString(strTitle, TabControl1.Font, br, r, sf)
Else
'these are the colors for the unselected tab pages
br = New SolidBrush(Color.White) ' Change this to your preference
g.FillRectangle(br, e.Bounds)
br = New SolidBrush(Color.Black)
g.DrawString(strTitle, TabControl1.Font, br, r, sf)
End If
End Sub
and I also put this at PageLoad function:
TabControl1.DrawMode = TabDrawMode.OwnerDrawFixed
For Each tg As TabPage In TabControl1.TabPages
tg.BackColor = Color.White
Next

There is no property to do this. However it is possible by using something like this
http://dotnetrix.co.uk/tabcontrol.htm
All controls on this site are freely available under MIT license.

Spending fair time to research if someone find a solution; There could be some work around. But according to MSDN Ref.
TabControl.BackColor Property
NET Framework (current version) This API supports the product
infrastructure and is not intended to be used directly from your code.
This member is not meaningful for this control.
Namespace: System.Windows.Forms Assembly: System.Windows.Forms (in
System.Windows.Forms.dll)
As far as I understand, this is adjustable from user's windows setting. (Highlight Color) of TabControl, Forms and other controls; otherwise MS could simply turn this property on.

I make a trick to get around this, I put on the gray part a white label and I have the following result:

Since that color segment of the tabcontrol is unpaintable and cannot be controlled, you have to use a panel or label, etc. to cover up the background color where there is no tabpage header. I use a panel to do this.

This statement working correctly:
Dim PutBackColor As Boolean = False
Private Sub TabControl1_DrawItem(sender As System.Object, e As System.Windows.Forms.DrawItemEventArgs) Handles TabControl1.DrawItem
If Me.PutBackColor = False Then
e.Graphics.FillRectangle(New SolidBrush(<YourColor>), 0 , 0, e.Bounds.Width + 2, e.Bounds.Height + 2)
Me.PutBackColor = True
End If
e.Graphics.FillRectangle(New SolidBrush(<YourColor>), 0 , 0, e.Bounds.Width + 2, e.Bounds.Height + 2)
e.Graphics.DrawString(Me.TabControl1.TabPages(e.In dex).Text, e.Font, Brushes.White, e.Bounds.X + 5, e.Bounds.Y + 5)
If e.State = DrawItemState.Selected Then
Me.PutBackColor = False
End If
End Sub

Related

vb 2015 GDI+ bitmap placement

I've had little luck trying to find the answer to this either on stackoverflow specifically, or on the internet in general.
I have a form in a vb 2015 Windows Forms project.
On that form, I've placed six controls: four textboxes, a panel, and a button.
When I click the button, it generates a bitmap, like so:
Private Sub btnSetLeft_Click(sender As Object, e As EventArgs) Handles btnSetLeft.Click
Dim R As Integer = CInt(txtRedLeft.Text)
Dim G As Integer = CInt(txtGreenLeft.Text)
Dim B As Integer = CInt(txtBlueLeft.Text)
Dim A As Integer = CInt(txtAlphaLeft.Text)
gcL = Color.FromArgb(A, R, G, B)
Using bm As Bitmap = New Bitmap(9, 9)
Using gBM As Graphics = Graphics.FromImage(bm)
Using br As SolidBrush = New SolidBrush(gcL)
gBM.FillRectangle(br, New Rectangle(0, 0, 8, 8))
End Using
End Using
End Using
End Sub
But, after building the bitmap, I want the button to place the bitmap on the panel and then repaint the panel, thus displaying the new bitmap.
How do I do that?
It's not too hard (I simplified your example):
Dim gcL As Color = Color.Blue
Using bm As New Bitmap(9, 9)
Using gBM As Graphics = Graphics.FromImage(bm)
Using br As New SolidBrush(gcL)
gBM.FillRectangle(br, New Rectangle(0, 0, 8, 8))
End Using
End Using
panel1.BackgroundImage = bm
panel1.BackgroundImageLayout = ImageLayout.Tile
panel1.Update()
End Using

Dynamically coloring listview but only one column is the text being colored [duplicate]

I would like to change selection color in a ListView, from a default (blue). I can not adapt any code that I found to my needs.
Here is the code that is closest.
If e.Item.Selected = True Then
e.Graphics.FillRectangle(New SolidBrush(Color.Gray), e.Bounds)
TextRenderer.DrawText(e.Graphics, e.Item.Text, New Font(ListView2.Font, Nothing), New Point(e.Bounds.Left + 3, e.Bounds.Top + 2), Color.White)
Else
e.DrawDefault = True
End If
The main problem is e.Item.Text part. It doesn't work for multi column listview. Here is the result.
Before selection :
...and after :
Is it possible to preserve values from other columns and still have full row selection?
Thanks.
The thing to keep in mind with an OwnerDraw Listview is that there are 2 events to respond to (or override if you are subclassing) if the control is Details View: DrawColumnHeader and DrawSubItem.
DrawItem would be used when the control is using a different View and there are no SubItems to draw.
Since SubItems(0) is the same as Item.Text, you can use DrawSubItem to draw the item and subitem text. I cannot tell where that snippet is located, but this will work:
Private Sub lv1_DrawSubItem(sender As Object,
e As DrawListViewSubItemEventArgs) Handles lv1.DrawSubItem
' use sender instead of a hardcodes control ref so
' you can paste this to another LV
Dim myLV As ListView = CType(sender, ListView)
If e.ItemIndex > 0 AndAlso e.Item.Selected Then
Using br As New SolidBrush(Color.Gray)
e.Graphics.FillRectangle(br, e.Bounds)
End Using
Using fnt As New Font(myLV .Font, Nothing)
' use e.SubItem.Text
TextRenderer.DrawText(e.Graphics, e.SubItem.Text,
fnt,
New Point(e.Bounds.Left + 3, e.Bounds.Top + 2),
Color.White)
End Using ' dispose!
Else
e.DrawDefault = True
End If
End Sub
It would appear that you may be using the correct event, but by usingItem.Text rather than e.SubItem.Text the Item text will be also be drawn for all SubItems (DrawSubItem will be called as many times as there are subitems).
Note that I also wrapped the Font in a Using block to dispose of it. Using LimeGreen, the result:

Listview - Multi column - Change selection color for the whole row

I would like to change selection color in a ListView, from a default (blue). I can not adapt any code that I found to my needs.
Here is the code that is closest.
If e.Item.Selected = True Then
e.Graphics.FillRectangle(New SolidBrush(Color.Gray), e.Bounds)
TextRenderer.DrawText(e.Graphics, e.Item.Text, New Font(ListView2.Font, Nothing), New Point(e.Bounds.Left + 3, e.Bounds.Top + 2), Color.White)
Else
e.DrawDefault = True
End If
The main problem is e.Item.Text part. It doesn't work for multi column listview. Here is the result.
Before selection :
...and after :
Is it possible to preserve values from other columns and still have full row selection?
Thanks.
The thing to keep in mind with an OwnerDraw Listview is that there are 2 events to respond to (or override if you are subclassing) if the control is Details View: DrawColumnHeader and DrawSubItem.
DrawItem would be used when the control is using a different View and there are no SubItems to draw.
Since SubItems(0) is the same as Item.Text, you can use DrawSubItem to draw the item and subitem text. I cannot tell where that snippet is located, but this will work:
Private Sub lv1_DrawSubItem(sender As Object,
e As DrawListViewSubItemEventArgs) Handles lv1.DrawSubItem
' use sender instead of a hardcodes control ref so
' you can paste this to another LV
Dim myLV As ListView = CType(sender, ListView)
If e.ItemIndex > 0 AndAlso e.Item.Selected Then
Using br As New SolidBrush(Color.Gray)
e.Graphics.FillRectangle(br, e.Bounds)
End Using
Using fnt As New Font(myLV .Font, Nothing)
' use e.SubItem.Text
TextRenderer.DrawText(e.Graphics, e.SubItem.Text,
fnt,
New Point(e.Bounds.Left + 3, e.Bounds.Top + 2),
Color.White)
End Using ' dispose!
Else
e.DrawDefault = True
End If
End Sub
It would appear that you may be using the correct event, but by usingItem.Text rather than e.SubItem.Text the Item text will be also be drawn for all SubItems (DrawSubItem will be called as many times as there are subitems).
Note that I also wrapped the Font in a Using block to dispose of it. Using LimeGreen, the result:

ComboBox DrawItem event handling for Font Combo Box - WinForms, VB.NET

I am creating a combobox which shows fonts in the list, with every font item displayed in its own font style. The combobox loads without errors but the list that shows is all in just one font. I have set DrawMode = OwnerDrawVariable and IntegralHeight = false, but still no result. The DrawItem code that you can see here is from the MSDN website, with a few changes as per my requirement. Here is my code:
BindCOmboboxes() is called when the form loads.
Private Sub w_BindComboBoxes() (StyleControl is a User Control containing the combobox)
'Set Properties
Dim tFont As Font = Nothing
StyleControl.TS1Font.DrawMode = DrawMode.OwnerDrawVariable
For Each fntfam As FontFamily In FontFamily.Families
If fntfam.IsStyleAvailable(FontStyle.Regular) Then
tFont = New Font(fntfam, 12, FontStyle.Regular)
StyleControl.TS1Font.Items.Add(tFont.Name & ",Regular")
End If
If fntfam.IsStyleAvailable(FontStyle.Italic) Then
tFont = New Font(fntfam, 12, FontStyle.Italic)
StyleControl.TS1Font.Items.Add(tFont.Name & ",Italic")
End If
If fntfam.IsStyleAvailable(FontStyle.Bold) Then
tFont = New Font(fntfam, 12, FontStyle.Bold)
StyleControl.TS1Font.Items.Add(tFont.Name & ",Bold")
End If
Next
End Sub
DrawItem function for TS1Font combobox
Private Sub FontComboBoxDrawItems(sender As Object, e As DrawItemEventArgs)
Dim size As Integer = 12
Dim myFont As System.Drawing.Font
Dim family As FontFamily = new FontFamily("Arial", 12) <-- to avoid crash
Dim fntStyle As FontStyle = FontStyle.Regular <-- To avoid crash
Dim animalColor As System.Drawing.Color = Color.Black
Dim str As String = DirectCast(sender, ComboBox).Items(e.Index).ToString.Trim
Dim brk() As String = str.Split(",")
For Each fam As FontFamily In FontFamily.Families
If fam.Name = brk(0) Then family = fam
Next
Select Case brk(1)
Case "Regular"
fntStyle = FontStyle.Regular
Case "Bold"
fntStyle = FontStyle.Bold
Case "Italic"
fntStyle = FontStyle.Italic
End Select
' Draw the background of the item.
e.DrawBackground()
' Draw each string in the array, using a different size, color,
' and font for each item.
myFont = New Font(family, size, fntStyle)
e.Graphics.DrawString(DirectCast(sender, ComboBox).Items(e.Index).ToString, myFont, System.Drawing.Brushes.Black,
New PointF(e.Bounds.X, e.Bounds.Y))
' Draw the focus rectangle if the mouse hovers over an item.
e.DrawFocusRectangle()
End Sub
On debugging in the DrawItem function, the values in the statement e.Graphics.DrawString = shows proper font family, style and size values. So why doesn't it draw the items that way?
Result:

Can't centre Listview Item when using OwnerDrawn

When trying to custom draw my coloumn headers and listview items, I was getting jagged text (not anti-aliased) which looked crappy. I came across the following code snippet to render the text and display much more nicely - which works. However, I can't work out how to centre my text in the column. Currently, setting my flags to HorizontalCentre actually centres the text within the entire listview control.
Private Sub lsvOverdueCalls_DrawItem(sender As Object, e As DrawListViewItemEventArgs) Handles lsvOverdueCalls.DrawItem
If e.Item.Selected AndAlso e.Item.ListView.Focused Then
e.Item.BackColor = SystemColors.Highlight
e.Item.ForeColor = e.Item.ListView.BackColor
ElseIf e.Item.Selected AndAlso Not e.Item.ListView.Focused Then
e.Item.BackColor = SystemColors.Control
e.Item.ForeColor = e.Item.ListView.ForeColor
Else
e.Item.BackColor = e.Item.ListView.BackColor
e.Item.ForeColor = e.Item.ListView.ForeColor
End If
e.DrawBackground()
' Draw the header text.
Dim rec As New Rectangle(e.Bounds.X + 2, e.Bounds.Y + 2, e.Bounds.Width - 4, e.Bounds.Height - 4)
Dim flags As TextFormatFlags = TextFormatFlags.HorizontalCenter Or TextFormatFlags.EndEllipsis Or TextFormatFlags.ExpandTabs Or TextFormatFlags.SingleLine
TextRenderer.DrawText(e.Graphics, e.Item.Text, e.Item.ListView.Font, rec, e.Item.ForeColor, flags)
End Sub
My result is this:
I need the Call Number (26155) to sit centre of the Call ID Column.
e.Bounds is the entire width. To get the width of your column, try referencing the Width property of the ListView column.
If you gave your columns keys, reference them by key:
listView1.Columns("callID").Width
or index:
listView1.Columns(0).Width
Then your drawing rectangle would look something like this:
Dim colWidth As Integer = listView1.Columns("callID").Width
Dim rec As New Rectangle(e.Bounds.X, e.Bounds.Y, _
colWidth, e.Bounds.Height)