Color-picker showing color names - vb.net

Does anyone know of a color-picker for Visual Studio (Visual Basic) that shows the names of the standard colors?
For example, in Visual Studio, you can alter the color of a control using a color-picker that has tabs of "Custom", "Web" and "System". The Web & System options show a list of the color names, whereas Custom supplies (mainly) RGB (which is what the VB ColorPicker control does).
Thanks!

there is precious little to one of these until you want to do like VS and present System Colors apart from Named Colors, make it a popup or some such. Example using colors as the BackGround:
' capture the names
Private _Colors As String()
' get the names
' add qualifiers to skip SystemCOlors or
' Transparent as needed
Function GetColorNames As String()
For Each colorName As String In KnownColor.GetNames(GetType(KnownColor))
_Colors.Add(colorName)
End If
Next
' post the names to a CBO:
cboBackColor.Items.AddRange(_Colors)
On the form CBO, set the DrawMode to OwnerDrawFixed, then:
Private Sub cboSheetBackColor_DrawItem(ByVal sender As Object,
ByVal e As System.Windows.Forms.DrawItemEventArgs)
Handles cboSheetBackColor.DrawItem
Dim Bclr As Color, Fclr As Color
' get the colors to use for this item for this
Bclr = Color.FromName(_Colors(e.Index).ToString)
Fclr = GetContrastingColor(Bclr) ' see below
With e.Graphics
Using br As New SolidBrush(Bclr)
.FillRectangle(br, e.Bounds)
End Using
Using br As New SolidBrush(Fclr)
.DrawString(cboSheetBackColor.Items(e.Index).ToString,
cboSheetBackColor.Font, br,
e.Bounds.X, e.Bounds.Y)
End Using
End With
e.DrawFocusRectangle()
End Sub
You can just draw a swatch like Windows/VS does by defining a rectangle to fill. Generally, thats swell, but in the case where you are doing something like defining a background color it rather helps to show how it looks with text on it and more of the color than the little bitty swatch - hence the filled CBO Item rect.
The standard window Text color will not show up on all of them. For a "light" theme, Violet and Black etc will hide/make the color name impossible to read. GetContrastingColor is a function which evaluates the Brightness of the current color and then returns either White or Black:
Public Function GetContrastingColor(ByVal clrBase As Color) As Color
' Y is the "brightness"
Dim Y As Double = (0.299 * clrBase.R) _
+ (0.587 * clrBase.G) _
+ (0.114 * clrBase.B)
If (Y < 140) Then
Return Color.White
Else
Return Color.Black
End If
End Function
You can then use all this in a Class which inherits from ComboBox, or build a UserControlif you like distinct controls. You can also leave it as code in a DLL which is called on those occasions. I should mention there are also perhaps a dozen such critters on CodeProject.

I don't know about an existing control but you can use the KnownColor enumeration and the SystemColors class to get all the names of those Color values. You can then build your own control, e.g. custom ComboBox, with that data.

Related

Type "Record" is not defined in custom class vb.net

I'm following the thread below to create the multi-line combobox. I'm currently using Visual Studio 2019, and that thread is from 2013.
Any way for a combo box with 2 values per line?
Code that I copied:
Public Class MultiLineComboBox : Inherits ComboBox
Public Sub New()
' Call the base class.
MyBase.New()
' Typing a value into this combobox won't make sense, so make it impossible.
Me.DropDownStyle = ComboBoxStyle.DropDownList
' Set the height of each item to be twice its normal value
' (because we have two lines instead of one).
Me.ItemHeight *= 2
End Sub
Protected Overrides Sub OnDrawItem(e As DrawItemEventArgs)
' Call the base class.
MyBase.OnDrawItem(e)
' Fill the background.
e.DrawBackground()
' Extract the Record object corresponding to the combobox item to be drawn.
If (e.Index >= 0) Then
Dim record As Record = DirectCast(Me.Items(e.Index), Record)
' Format the item's caption string.
Dim caption As String = String.Format("ID: {0}{1}Name: {2}", record.UniqueID.ToString(), Environment.NewLine, record.Name)
' And then draw that string, left-aligned and vertically centered.
TextRenderer.DrawText(e.Graphics, caption, e.Font, e.Bounds, e.ForeColor, TextFormatFlags.Left Or TextFormatFlags.VerticalCenter)
End If
' Finally, draw the focus rectangle.
e.DrawFocusRectangle()
End Sub
End Class
I created a class named MultiLineComboBox, followed the instruction exactly, and it says "Type 'Record' is not defined." I have been searching for answers on the type "record" or DirectCast (e.g. https://learn.microsoft.com/en-us/dotnet/visual-basic/language-reference/operators/directcast-operator), but none of them has helped me so far.
My reputation is currently <50 so I cannot leave a comment on the answer of that thread either. Could you all please help me with this?
(added tag visual-studio-2019 and .net-4.7.2 in case VS or .NET version is the issue)
Read the whole answer. The Record class is declared there; you need it, too, and you want to change the code to match the fields for your combobox.

VB.NET Listbox item color [duplicate]

So I'm trying to make a listbox with 2 buttons.
Listbox is supposed to display files from a specific folder (I get back to this)
And the two buttons are supposed to be called "Set.." (As in set directory)
and Update (As the list will be refreshed (Something I do every time the Windows Form Runs.
So as of now, when I start my application, and go to the form with the listbox, the listbox is empty. When pressing "Update", the List box picks up files from an address located on my Harddrive (So this is a static address located in my code).
It also finds 7 different extensions (Filetypes), and lists all of them correctly.
My problem is as follows, I want the set Button to open a File Dialog for the user on First-Time Runtime, so the user himself can choose what folder the program "Indexes or Searches" if you will. And then when he runs the application again, and finds the listbox, he can only press Update, and the listbox shows the content of the folder he choose last time.
The Set - button doesn't do anything in my code right now.
Second up, I want each filetype to be labeled or colored with a specific color.
Like; .txt should be blue, .jpg is red, ect..
Running Visual Studio 2013 if that helps.
Also, when checking my code, if you have any suggestions too, how I can improve the code, make it easier, shorter, and just to change things to avoid duplicate codes, please let me know.
Here is from the Design in VS2013
Code:
Private Sub Form_Load(sender As Object, e As EventArgs) Handles Me.Load
FolderBrowserDialog1.SelectedPath = "xxx\xxx\xxx\xxx"
System.IO.Directory.GetCurrentDirectory()
Private Sub updateButtonGame_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles updateButtonGame.Click
If FolderBrowserDialog1.SelectedPath = "xxx\xxx\xxx\xxx" Then
ListFiles(FolderBrowserDialog1.SelectedPath)
End If
End Sub
Private Sub ListFiles(ByVal folderPath As String)
filesListBox.Items.Clear()
Dim fi = From f In New IO.DirectoryInfo(FolderBrowserDialog1.SelectedPath).GetFiles().Cast(Of IO.FileInfo)() _
Where f.Extension = ".z64" OrElse f.Extension = ".nds" OrElse f.Extension = ".BIN" OrElse f.Extension = ".smc" OrElse f.Extension = ".ISO" OrElse f.Extension = ".nes" OrElse f.Extension = ".gb"
Order By f.Extension
Select f
For Each fileInfo As System.IO.FileInfo In fi
filesListBox.Items.Add(fileInfo.Name)
Next
End Sub
Another thing, this is more optional..
My list is completely black, so I choose to have the "Items" in the Listbox turn Light gray.
I played around with something called e.Graphics in hope to achieve Coloring a specific filetype, and it turned ALL items either Black, Red, or whatever I put it to.
But after removing the code, all Items turns into the same color as the Background color of the Listbox. So I can no longer see the elements actually being there, other than the Scroll-bar popping up on the side (Since its many Items in the folder I picked)
Also, I am not that good with coding/visual studio yet, as I started around 1 week ago to date.
Started with VB 2010 and then went to VS2013 to see if I managed to fix some issues, also related to List Box.
If I explained rather poorly, let me know and I'll update with better info.
Project was also first created in VB 2010, and then "Migrated" or opened in VS 2013.
A much, much better way to do this is with a ListView and an ImageList with some standard images for Text, Image, PDF etc in the list, then just set the image key for each item when you add them to the list.
Alternatively, you could emulate the same thing in a listbox (using OwnerDrawFixed) to draw a specified image to indicate the file type. A really good way to implement this is as an ExtenderProvider using code similar to that below as a starting point. As an EP, you can link any cbo or listbox to an image list to provide image cues very much like the ListView works:
The reason you do not see your colored item idiom very often is that whatever colors you pick will not look right on all systems. The more colors, the more likely and more often they wont have enough contrast, be readable etc with the user's color scheme. You also dont need a "Legend" to explain what the colors mean - an image is self explanatory. That said, the DrawItem code would be something like this:
NB: Listbox control is set to OwnerDrawFixed, ItemHeight = 16
Private Sub lb_DrawItem(sender As Object,
e As DrawItemEventArgs) Handles lb.DrawItem
Dim TXT As Color = Color.Black
Dim JPG As Color = Color.Green
Dim PDF As Color = Color.Blue
Dim EXE As Color = Color.Gray
Dim SEL As Color = SystemColors.HighlightText
Dim thisColor As Color = Color.Orange
Dim ndx As Integer = e.Index
' isolate ext ans text to draw
Dim text As String = lb.Items(ndx).ToString()
Dim ext As String = System.IO.Path.GetExtension(text).ToLowerInvariant
' dont do anything if no item being drawn
If ndx = -1 Then Exit Sub
' default
e.DrawBackground()
' color selector
Select Case ext
Case ".jpg"
thisColor = JPG
Case ".txt"
thisColor = TXT
Case ".exe"
thisColor = EXE
Case ".pdf"
thisColor = PDF
End Select
' override color to use default when selected
If (e.State And DrawItemState.Selected) = DrawItemState.Selected Then
thisColor = SEL
End If
' render the text
TextRenderer.DrawText(e.Graphics, text, lb.Font, e.Bounds,
thisColor, TextFormatFlags.Left)
' default
e.DrawFocusRectangle()
End Sub
Result:
Works on My SystemTM

Add clickable buttons to a custom DataGridViewCell control

I made a custom DataGridViewColumn control together with its DataGridViewCell controls.
The idea is to dynamically create the contents of the cell, which consists of a series of clickable function buttons, upon databinding. The number and kinds of buttons depend on the data value passed.
For this, I override the Paint method of the DataGridViewCell and check the formattedValue on its contents and draw buttons accordingly. However, these buttons are "dead" and not clickable, so the question is how to make them clickable, i.e. how do I add a handler for the click event?
Do I have to override the cell's OnClick method and then try to pinpoint which button exactly is clicked? Is this even possible? Are there better ways?
This is what I've got so far:
Protected Overrides Sub Paint(graphics As Graphics, clipBounds As Rectangle, cellBounds As Rectangle, rowIndex As Integer, cellState As DataGridViewElementStates, value As Object, formattedValue As Object, errorText As String, cellStyle As DataGridViewCellStyle, advancedBorderStyle As DataGridViewAdvancedBorderStyle, paintParts As DataGridViewPaintParts)
MyBase.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts)
Dim cellBackground As New SolidBrush(cellStyle.BackColor)
graphics.FillRectangle(cellBackground, cellBounds)
cellBackground.Dispose()
PaintBorder(graphics, clipBounds, cellBounds, cellStyle, advancedBorderStyle)
Dim sValue As String = formattedValue.ToString()
If (sValue.Contains("ViewAsPDF")) Then
Dim buttonArea As Rectangle = cellBounds
Dim buttonAdjustment As Rectangle = Me.BorderWidths(advancedBorderStyle)
buttonArea.X += buttonAdjustment.X
buttonArea.Y += buttonAdjustment.Y
buttonArea.Height -= buttonAdjustment.Height
buttonArea.Width -= buttonAdjustment.Width
buttonArea.Width = buttonArea.Width / 4
ButtonRenderer.DrawButton(graphics, buttonArea, PushButtonState.Default)
TextRenderer.DrawText(graphics, "PDF", Me.DataGridView.Font, buttonArea, SystemColors.ControlText)
End If
'etcetera
End Sub
I think you may have wandered down the wrong road. Based on the code provided, you are simply drawing the cells to look like they contain buttons. Since they are not actually objects, they are incapable of raising events.
I don't understand ButtonRenderer, if you can't create actual Buttons with it
The ButtonRender does not create a new button object, it is meant to be used by Button objects for drawing. Often a subclassed a button, will not use it because it employs the existing theme and style which is may be what a you wants to do differently (even the DataGridViewButtonCell does not use it -- at least not directly).
From the code provided, it seems to work out each button on the fly each time rather than drawing from some collection or definition. What if the "action" list needs to vary based on the row (e.g. different actions for a DOC, XLS or Image row)? Doing so, would seem to take a great deal of code.
Your current course may not be impossible, but it is not trivial either. You might be able to create a collection of virtual buttons (basically the Rect from when it was drawn) and render them as you have done. Then in the cell-click event, translate/adjust the X position to see which rectangle contains thisPt.X to determine which related action to take.
There are "issues" still such as what happens when the user resizes the column? What about when the button list varies by some other cell value (DOC vs XLS vs IMG vs PDF)? This would require a collection of button sets...and a fair amount of code.
This is not to say it cant be done, but it seems like a great deal of code would be required to make it even a little flexible.
Are there better ways?
I think so.
A simpler, existing solution might be to use the existing DataGridViewComboBoxColumn to store "Actions" or "Activities". It seems a bit less cluttered and more user friendly:
It takes only a small amount of code to provide a different list for each animal:
' dogs like to go for walks
Private ActsCan() As String = {"Feed", "Pet", "Bathe", "Brush", "Take for Walk"}
' no walks or baths for cats
Private ActsFel() As String = {"Feed", "Pet", "Baby-Talk To", "Brush"}
' never bathe a Mugwai, comb rather than brush
Private ActsMug() As String = {"Feed", "Pet", "Baby-Talk To", "Comb"}
Private ActsGrem() As String = {"Hide From", "Strangle"}
...
Private Sub dgv_RowEnter(sender As Object,
e As DataGridViewCellEventArgs) Handles dgv.RowEnter
Dim dgvCBO As DataGridViewComboBoxCell
dgvCBO = CType(dgv.Rows(e.RowIndex).Cells("ColActs"), DataGridViewComboBoxCell)
dgvCBO.Items.Clear()
Select Case dgv.Rows(e.RowIndex).Cells("colSpecies").Value.ToString
Case "Canine"
dgvCBO.Items.AddRange(ActsCan)
Case "Feline"
dgvCBO.Items.AddRange(ActsFel)
Case "Mugwai"
dgvCBO.Items.AddRange(ActsMug)
Case "Gremlin"
dgvCBO.Items.AddRange(ActsGrem)
End Select
End Sub
A class to encapsulate most of that might be nice for unbound DGVs. It could be optimized not to rebuild the list when the trigger value for thisRow is the same as the last.
What about this approach. Only implementing the ui.

Changing background color of each cell in Data Grid

After I figured out how to change the different cell's border colors using the RGB values to generate a random color, I now want to change the background color of each cell as well. This is for DataGridView. Below is my relevant code that allowed me to change cell border colors and now somewhere in that code lies a way to change background color of each cell but I am not familiar with this code since it is from a freeware. Does anyone know what I must change in this code to affect the background color of each cell?
Here is my code:
http://pastebin.com/WNBReUys
The solution printing a background color is similar to the pen solution except you need to use a brush, usually a SolidBrush:
Dim brushColor as New SolidBrush(someColor)
e.Graphics.FillRectangle(brushColor ,_
New Rectangle(ColumnLeft(ColPage, ColAt), _
tmpTop, _
ColumnWidth(ColPage, ColAt), _
CellHeight))
Note that since you are drawing text and other graphics on this rectangle, you probably want to paint the background color first, before all the other graphics. (Otherwise, you will end up with only a solid colored rectangle with no text.)
I used the following code to change DataGrid BackColor.
Usually, you assign an array, table or dataset as DataSource of your DataGrid. So, I looped in my DataTable which is my data source, then look for the index of the line I want to change.
Private Sub DataGridForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
dgr1.DataSource = TimeDifftbl
dgr1.PreferredColumnWidth = 250
Dim cellText As String
Dim dr As DataRow
For n As Integer = 0 To TimeDifftbl.Rows.Count - 1
dr = TimeDifftbl.Rows(n)
cellText = dr.Item(2)
If cellText = "Tot. RunTime" Then
dgr1.CurrentRowIndex = n
dgr1.Select(n)
dgr1.SelectionBackColor = BackColor.LightGray
End If
Next
End Sub

Is there some kind of display control in .NET that can handle color codes?

It seems the only options available to do multi-color on a string is either a bunch of label controls cleverly grouped together or to use a RichTextBox and play with the font properties as text is added to the control.
What I am looking for instead is some kind of control that can render some style of control codes out as color. Consider bash codes:
NORMAL='\e[0m'
GREEN='\e[0;32m'
BLUE='\e[0;34m'
echo -e "This text is ${GREEN}green${NORMAL} and this text is ${BLUE}blue${NORMAL}"
In the above, the words 'green' and 'blue' will be colorized with their respective colors. I was wondering if there was a control with some kind of feature like this, or will I have to code something myself?
Note, I only have the Express copy of VB 2010, and I would very much like to avoid third-party controls.
Are you specifically looking for something that understands ANSI control codes, or just something that accepts markup? If you just want something that accepts markup, you can use the RichTextBox.Rtf property to set all the control codes and text with a single string.
See http://msdn.microsoft.com/en-us/library/aa140277(v=office.10).aspx for the RTF specifications.
I would recommend programmatically generating a sample document, then reading the Rtf property and using the resulting RTF code as a template for what you should generate. For reference, here's a simple RTF document that has two color of text (plus the default) in Consolas (which fallback to Courier New):
{\rtf1\deff0{\fonttbl{\f0\fmodern\fcharset0 Consolas {\*\falt Courier New};}}
{\colortbl ;\red255\green0\blue0;\red0\green176\blue80;}
\cf1 Hello\cf0 , \cf2 world\cf0 .
}
There are a couple of other options. first you can paint text using the graphics object and DrawString method using any color font and style you want. This however can be a pain. The easiest way is to use a web browser control and use plain old html.
If you don't want to use RTF I wrote this little sample which will allow you to use RGB codes this is not complete solution as you would have to figure out a way to delmit the control chars. If you wanted to test it create a form and drop a button and a rich text box on it.
Imports System.Drawing
Imports System.Text.RegularExpressions
Public Class Form1
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Dim str As String = "This text is {#00FF00}green{#000000} and this text is {#0000FF}blue{#000000}"
PrintToRtf(str, RichTextBox1)
End Sub
Private Shared Sub PrintToRtf(Str As String, RTB As RichTextBox)
Dim mc As MatchCollection = Regex.Matches(Str, "\{\#(?<Red>[0-9A-Fa-f]{2})(?<Green>[0-9A-Fa-f]{2})(?<Blue>[0-9A-Fa-f]{2})\}")
Dim lp As Int32 = 0
For Each mtc As Match In mc
Dim subStr As String = Str.Substring(lp, mtc.Index - lp)
Dim R, G, B As Byte
R = Integer.Parse(mtc.Groups("Red").Value, Globalization.NumberStyles.AllowHexSpecifier)
G = Integer.Parse(mtc.Groups("Green").Value, Globalization.NumberStyles.AllowHexSpecifier)
B = Integer.Parse(mtc.Groups("Blue").Value, Globalization.NumberStyles.AllowHexSpecifier)
Dim clr As Color = Color.FromArgb(255, R, G, B)
RTB.SelectedText = subStr
RTB.SelectionColor = clr
lp = mtc.Index + mtc.Length
RTB.Select(RTB.TextLength, 0)
Next
End Sub
End Class