On a ZedGraph pane, it is possible to set a CurveItem as "selected".
zedGraphControl.GraphPane.CurveList[0].IsSelected = true;
zedGraphControl.Refresh();
This will change its color to Color.Gray as far as I can see.
Is it possible to change this selected-state color?
I don't know of such a property but you can accomplish this by manually overriding the MouseClick event of the ZedGraphControl and set the color of the "selected" CurveItem, something like:
private void zedGraphControl1_MouseClick(object sender, MouseEventArgs e)
{
foreach (var curve in zedGraphControl1.GraphPane.CurveList)
{
curve.Color = Color.Black;
}
CurveItem nearestItem;
int nearestPoint;
zedGraphControl1.GraphPane.FindNearestPoint(e.Location, out nearestItem, out nearestPoint);
if (nearestItem != null)
{
nearestItem.Color = Color.Red;
}
zedGraphControl1.Refresh();
}
UPDATE: Looking at the source code of http://www.opensourcejavaphp.net/csharp/zedgraph/Line.cs.html and http://www.opensourcejavaphp.net/csharp/zedgraph/Selection.cs.html it seems that Line.DrawCurve is using static property Selection.Line. Without modifying source it would be hard to change this behaviour.
Part of Line.cs:
public void DrawCurve( Graphics g, GraphPane pane, CurveItem curve, float scaleFactor )
{
Line source = this;
if ( curve.IsSelected )
source = Selection.Line;
Selection.cs:
/// The <see cref="Line" /> type to be used for drawing "selected"
/// <see cref="LineItem" /> and <see cref="StickItem" /> types
/// </summary>
public static Line Line = new Line( Color.Gray );
The selected line is a static property, but NOT read-only. One can change the format by resetting the Selection.Line property:
public Form1()
{
InitializeComponent();
ZedGraph.Selection.Line.Width = 3;
ZedGraph.Selection.Line.Color = Color.Red;
...
}
After resetting the selection line, all selected lines will draw as specified.
Related
I'm remaking a program, everything was going good but now i ran into a problem. The program i'm rewriting is wpf and i'm working in winforms, the program has a listbox that i cant recreate that easy :(
Here is a picture of the ListBox with a selected item: Selected Item
As you can see selected items turn blue and the border of it another blue, when you stop focusing on the form it will turn white: White item
And items where you hover on will turn blue to but a bit lighter:
Hover Item
Thanks for your help!
btw im using .NET Framework 4.8
You can create your own listbox deriving from the original one. Once the new list is compiled for the first time, it will appear in the toolbox, so that you can drag and drop it onto your forms. Or you can change the type of existing listboxes to ListBoxEx in the Form.designer.cs manually.
public class ListBoxEx : ListBox
{
public ListBoxEx()
{
DrawMode = DrawMode.OwnerDrawFixed;
DoubleBuffered = true; // Eliminates flicker (optional).
}
private int _hotTrackedIndex = -1;
private int HotTrackedIndex
{
get => _hotTrackedIndex;
set {
if (value != _hotTrackedIndex) {
if (_hotTrackedIndex >= 0 && _hotTrackedIndex < Items.Count) {
Invalidate(GetItemRectangle(_hotTrackedIndex));
}
_hotTrackedIndex = value;
if (_hotTrackedIndex >= 0) {
Invalidate(GetItemRectangle(_hotTrackedIndex));
}
}
}
}
protected override void OnDrawItem(DrawItemEventArgs e)
{
var borderRect = e.Bounds;
borderRect.Width--;
borderRect.Height--;
if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) {
if (Focused) {
e.Graphics.FillRectangle(Brushes.Teal, e.Bounds);
e.Graphics.DrawRectangle(Pens.LightSkyBlue, borderRect);
} else {
e.Graphics.FillRectangle(Brushes.DimGray, e.Bounds);
e.Graphics.DrawRectangle(Pens.White, borderRect);
}
} else if (e.Index == HotTrackedIndex) {
e.Graphics.FillRectangle(Brushes.DarkSlateGray, e.Bounds);
e.Graphics.DrawRectangle(Pens.DarkCyan, borderRect);
} else {
e.DrawBackground();
}
if (Items[e.Index] != null) {
e.Graphics.DrawString(Items[e.Index].ToString(), e.Font, Brushes.White, 6, e.Bounds.Top, StringFormat.GenericTypographic);
}
}
protected override void OnMouseLeave(EventArgs e)
{
HotTrackedIndex = -1;
base.OnMouseLeave(e);
}
protected override void OnMouseMove(MouseEventArgs e)
{
HotTrackedIndex = IndexFromPoint(e.Location);
base.OnMouseMove(e);
}
protected override void OnGotFocus(EventArgs e)
{
if (SelectedIndex >= 0) {
RefreshItem(SelectedIndex);
}
base.OnGotFocus(e);
}
protected override void OnLostFocus(EventArgs e)
{
if (SelectedIndex >= 0) {
RefreshItem(SelectedIndex);
}
base.OnLostFocus(e);
}
}
We change the appearance of the listbox by overriding OnDrawItem. in the constructor, we set DrawMode = DrawMode.OwnerDrawFixed; to enable owner drawing.
We must consider selected items and hot tracked items, i.e., items the mouse moves over. If the item to be drawn is the selected one, we further differentiate between the cases where the listbox has the focus or not.
FillRectangle draws the background. DrawRectangle draws the border. Note that the border rectangle must be smaller by one pixel than the e.Bounds rectangle, otherwise the right and bottom borders will not be drawn.
If the current item is not selected, we test to see whether it is hot tracked. If it is, we draw in different colors. Otherwise we draw the default background with e.DrawBackground();.
Then we draw the text over the background with DrawString.
For all this to work, we also must invalidate regions of the listbox where the colors are changing. We detect changes in hot tracking in OnMouseMove and OnMouseLeave. There we set the HotTrackedIndex. This is a property which triggers drawing when necessary.
In OnGotFocus and OnLostFocus we refresh the selected item to change its color depending on the focused state.
My colors do not match your images, but you can easily tweak them. If you need to create Brushes and Pens in non-standard colors, then either create them as static and read-only or then don't forget to dispose them.
private static readonly Brush HotTrackBrush = new SolidBrush(new Color(123, 45, 67));
private static readonly Pen HotTrackPen = new Pen(new Color(234, 56, 78));
An improved version of this listbox could expose the different selection and hot tracking colors as properties, so that you could easily change them in the properties window. (Properties automatically appear there.)
I have implemented Metro Framework in my Windows Form Application. I want to change the style color to custom color. (As shown in the screenshot) How do I do this?
I know this is an old question but it might help others looking for answers in the future.
If you are using the nuget Metro Framework package for C# in Visual Studio then you need to set the "UseCustomBackColor" of the object to true:
metroTile_YourTile.UseCustomBackColor = true;
and then change the back color in the designer to "Custom" and pick the color, or set it programmatically:
metroTile_YourTile.UseCustomBackColor = Color.FromArgb(100,100,100);
This is true for a multitude of objects in the package, including buttons, dropdowns, etc. I hope that is helpful.
Short answer: You can't.
A workaround would be to override the OnPaint method of the MetroForm and draw it yourself. For example:
protected override void OnPaint(PaintEventArgs e) {
base.OnPaint(e);
// custom draw the top border
using (Brush b = new SolidBrush(Color.White))
{
int borderWidth = 5; // MetroFramework source code
e.Graphics.FillRectangle(b, 0, 0, Width, borderWidth);
}
}
Long answer: I am using MetroModernUI from Nuget. And wanted to remove the top border.
Reading the source-code of the Framework, I found the method responsible for the draw of the top border, which is similar to the code above.
The method responsible for get the color for draw is MetroPaint.GetStyleBrush(Style), where Style is the Enum MetroColorStyle. It is a switch-case:
public static SolidBrush GetStyleBrush(MetroColorStyle style)
{
switch (style)
{
case MetroColorStyle.Black:
return MetroBrushes.Black;
case MetroColorStyle.White:
return MetroBrushes.White;
.
.
.
}
}
Basically you are limited to choose one of the colors available. (or fork the code and live the freedom!)
Reference: MetroModernUI (Github)
I realise this is an old question but this was driving me mad and I couldn't find answers anywhere. I did, however, figure it out so thought I'd share... As long as you don't mind editing the source code a little, there is a way to add custom colors.
1. Start with the MetroColors Class. Right at the bottom there is some code relating to a Custom option. Replace it with the following:
public static Color customColor = new Color();
public static Color Custom
{
get
{
return customColor;
}
}
2. Next, move onto the MetroPaint Class. Near the bottom, expand the Helper Methods region and add a case for Custom to GetStyleColor,
public static Color GetStyleColor(MetroColorStyle style)
{
switch (style)
{
case MetroColorStyle.Custom:
return MetroColors.Custom;
}
GetStyleBrushand
public static SolidBrush GetStyleBrush(MetroColorStyle style)
{
switch (style)
{
case MetroColorStyle.Custom:
return MetroBrushes.Custom;
}
GetStylePen. (Make sure to leave the defaults at the end)
public static Pen GetStylePen(MetroColorStyle style)
{
switch (style)
{
case MetroColorStyle.Custom:
return MetroPens.Custom;
}
}
3. Make sure that the MetroPens
public static Pen Custom
{
get
{
return GetSavePen("Custom", MetroColors.Yellow);
}
}
and MetroBrusheshave the Custom options at the end of them (I don't remember if they were already there or not)
public static SolidBrush Custom
{
get
{
return GetSaveBrush("Custom", MetroColors.Custom);
}
}
4. Save your changes and build it, then replace the MetroFramwork.dll in your project with the newly edited one.
5. I'll assume you already have a comboBox hooked up to the StyleManager. Add "Custom" to the end of the comboBox items (its index should be 15 as long as you haven't excluded any of the other colors) and add a colorDialog to the form.
6. Add a SelectedIndexChanged event handler to the comboBox and then add the following:
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (comboBox1.SelectedIndex == 15)
{
Color c = new Color();
if (colorDialog1.ShowDialog() == DialogResult.OK)
{
c = colorDialog1.Color;
}
MetroColors.customColor = c;
metroStyleManager1.Style = MetroColorStyle.Custom;
}
else
{
metroStyleManager1.Style = (MetroFramework.MetroColorStyle)Convert.ToInt32(comboBox1.SelectedIndex);
}
Refresh();
}
Now when you select Custom from the combBox, the colorDialog will appear and you can choose any color you want. If you just wanted to change to a fixed custom color that you don't want to be changed, you can just specify the RGB and apply it on FormLoad instead:
private void Form1_Load(object sender, EventArgs e)
{
MetroColors.customColor = Color.FromArgb(0, 0, 0);
metroStyleManager1.Style = MetroColorStyle.Custom;
}
You can repeat these steps as many times as you want to add new colors (Custom1, Custom2 etc.). Just remember to add these to the list in the MetroColorStyle.cs as well.
Try to use:
this.Style={color};
You can use:
this.Style = MetroFramework.MetroColorStyle.<color>;
Possible colors:
Default
Black
White
Silver
Blue
Green
Lime
Teal
Orange
Brown
Pink
Magenta
Purple
Red
Yellow
So for example:
this.Style = MetroFramework.MetroColorStyle.Red;
You can use this on any MetroFramework control:
metroProgressBar1.Style = MetroFramework.MetroColorStyle.Blue;
You can also switch between light and dark theme:
this.Theme = MetroFramework.MetroThemeStyle.Light;
//or
this.Theme = MetroFramework.MetroThemeStyle.Dark;
As already stated before, a custom color is not possible. However, you can use the already defined colors. (See #SomeCoder's answer)
If you want to make a ComboBox to change the theme/style you don't have to make a big switch statement with all the themes/styles, you can simply do this:
private void ColorComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
try
{
Enum.TryParse(colorComboBox.Text, out MetroColorStyle color);
this.Style = color;
}
catch (ArgumentException)
{
this.Style = MetroColorStyle.Default;
}
Refresh();
}
I am not sure if this will work, but try to use
this.BackColor = (your colour)
Also please let me know if this is working or not.
When I add item(s) to the ListView in any other than LargeIcon view mode, the ListView stops showing the images from LargeImageList when it is switched back to LargeIcon. This situation lasts until new item is added to the ListView in the LargeIcon mode.
So the following sequence illustrates the problem:
create ListView, add column, set View to Details
create ImageList, set ImageSize, assign it to ListView.LargeImageList
create new ListViewItem, set its ImageKey
create new image, add it to the ImageList with given key
add the ListViewItem to the ListView
switch the ListView mode to LargeIcon
no images are shown
repeat steps #3 - #6, now in the LargeIcon mode
all images are shown as expected
What is the point I am still missing?
I have tried following:
Invalidate the ListView
Re-assign the LargeImageList before/after adding the item (even through null)
The test code for those who like it more than words:
public partial class Form1 : Form
{
int counter = 0;
ImageList iList = new ImageList();
private string GetNewKey()
{
return counter++.ToString();
}
private Image GetNewImage(Size size)
{
var bmp = new Bitmap(size.Width, size.Height);
using (var gra = Graphics.FromImage(bmp))
{
var rnd = new Random();
var lines = rnd.Next(1000);
for (int l = 0; l < lines; ++l)
{
var pen = new Pen(Color.FromArgb(rnd.Next(256), rnd.Next(256), rnd.Next(256)));
var p1 = new Point(rnd.Next(size.Width), rnd.Next(size.Height));
var p2 = new Point(rnd.Next(size.Width), rnd.Next(size.Height));
gra.DrawLine(pen, p1, p2);
}
}
return bmp;
}
public Form1()
{
InitializeComponent();
iList.ImageSize = new Size(100, 100);
listView.LargeImageList = iList;
listView.Columns.Add("name");
}
private void buttonAdd_Click(object sender, EventArgs e)
{
var key = GetNewKey();
var lvi = new ListViewItem()
{
Name = key,
Text = "blabla",
ImageKey = key,
};
iList.Images.Add(key, GetNewImage(new Size(100, 100)));
listView.Items.Add(lvi);
}
private void buttonClear_Click(object sender, EventArgs e)
{
listView.Items.Clear();
}
private void buttonLarge_Click(object sender, EventArgs e)
{
listView.View = View.LargeIcon;
}
private void buttonDetails_Click(object sender, EventArgs e)
{
listView.View = View.Details;
}
}
EDIT:
For anyone who would suffer the same problem. After some experiments, there is at least stupid poor man's workaround:
Modify the ImageList, the ListView somehow detects its change and reloads the images for LargeIcon mode. The questions are how it detects the change and why does it ignore the ImageList after mode change...
private void FixIt()
{
// Trigger a reload of the ListView.LargeImageList
if (listView.View == View.LargeIcon)
{
var key = "Dummy image to be deleted right after its insertion...";
iList.Images.Add(key, new Bitmap(1, 1));
iList.Images.RemoveByKey(key);
}
}
EDIT #2:
I have also discovered some other funny features the ListView and associated components have. You might want to check them in answers of question 4097912 and question 23059678
To solve your problem
You could avoid this by useing ImageIndex instead of ImageKey to connect your ListView with the ImageList. So in your buttonAdd_Click event use:
var lvi = new ListViewItem()
{
Name = key,
Text = "blabla",
//ImageKey = key,
//Use ImageIndex and don't set both
ImageIndex= Convert.ToInt32(key) //you could just use count++
};
The reason behind this problem:
The reason behind this is not clear to me, but I assume this may be a bug that when changing from Details to LargeIcon, it only checks ImageIndex in default and if you set ImageKey the ImageIndex will be set to -1. Or may be this is by design, I don't know (see ImageKey section below), since you don't have a SmallImageList, so when changing to LargeIcon view, ImageIndex is null or -1 and the ImageKey is ignored.
About ListViewItem.ImageIndex Property
The ImageKey and ImageIndex properties are mutually exclusive, meaning if one is set, the other is ignored. Furthermore, if you set the ImageKey property, the ImageIndex property is automatically set to -1. Alternatively, if you set the ImageIndex property, the ImageKey is automatically set to an empty string ("").
About ListViewItem.ImageKey Property
If you are using multiple image lists, for small and large icon view, with a ListView control, you should place small and large versions of the image at the same index location in their respective image lists. When switching between views, the index location of the image in one list is used to locate the image in the other list, regardless of the key value specified.
And this can somehow be verified:
using your existing code (use ImageKey)
set ImageIndex for any Item in your listView within the buttonLarge_Click event handler will show you that item's image.
set ImageKey for any Item within the buttonLarge_Click event handler will not show that itme's image.
e.g.:
private void buttonLarge_Click(object sender, EventArgs e)
{
listView.View = View.LargeIcon;
//Set ImageIndex of Item 0 you could see its Icon.
listView.Items[0].ImageIndex= 0 ;
//set ImageKey will change nothing
//listView.Items[0].ImageKey= "0" ;
}
I have a ComboBox on a form, and its default height is 21. How do I change it?
ComboBox auto-sizes to fit the font. Turning that off is not an option. If you want it bigger then give it a bigger font.
Set the DrawMode to OwnerDrawVariable. However customization of the ComboBox leads to other issues. See this link for a tutorial on how to do this completely:
http://www.csharphelp.com/2006/09/listbox-control-in-c/
OwnerDrawVariable sample code here:
https://msdn.microsoft.com/en-us/library/system.windows.forms.combobox.drawitem%28v=vs.110%29.aspx
Once that's done, you need to set the ItemHeight property of the combobox to set the effective height of the combobox.
Just as another option, if you'd like to increase the height of the ComboBox without increasing the font size or having to worry about drawing everything yourself, you can use a simple Win32 API call to increase the height like this:
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace Win32ComboBoxHeightExample
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
[DllImport("user32.dll")]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, Int32 wParam, Int32 lParam);
private const Int32 CB_SETITEMHEIGHT = 0x153;
private void SetComboBoxHeight(IntPtr comboBoxHandle, Int32 comboBoxDesiredHeight)
{
SendMessage(comboBoxHandle, CB_SETITEMHEIGHT, -1, comboBoxDesiredHeight);
}
private void button1_Click(object sender, EventArgs e)
{
SetComboBoxHeight(comboBox1.Handle, 150);
comboBox1.Refresh();
}
}
}
Result:
To do this, you need to set the DrawMode to OwnerDrawVariable or OwnerDrawFixed and manually draw your items. This can be done with a pretty simple class.
This example will allow you to use the ItemHeight property of the ComboBox regardless of font size. I threw in an bonus property TextAlign which will also allow you to center the items.
One thing worth mentioning is, you must set DropDownStyle to DropDownList for the selected item to respect our customizations.
// The standard combo box height is determined by the font. This means, if you want a large text box, you must use a large font.
// In our class, ItemHeight will now determine the height of the combobox with no respect to the combobox font.
// TextAlign can be used to align the text in the ComboBox
class UKComboBox : ComboBox
{
private StringAlignment _textAlign = StringAlignment.Center;
[Description("String Alignment")]
[Category("CustomFonts")]
[DefaultValue(typeof(StringAlignment))]
public StringAlignment TextAlign
{
get { return _textAlign; }
set
{
_textAlign = value;
}
}
private int _textYOffset = 0;
[Description("When using a non-centered TextAlign, you may want to use TextYOffset to manually center the Item text.")]
[Category("CustomFonts")]
[DefaultValue(typeof(int))]
public int TextYOffset
{
get { return _textYOffset; }
set
{
_textYOffset = value;
}
}
public UKComboBox()
{
// Set OwnerDrawVariable to indicate we will manually draw all elements.
this.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawVariable;
// DropDownList style required for selected item to respect our DrawItem customizations.
this.DropDownStyle = ComboBoxStyle.DropDownList;
// Hook into our DrawItem & MeasureItem events
this.DrawItem +=
new DrawItemEventHandler(ComboBox_DrawItem);
this.MeasureItem +=
new MeasureItemEventHandler(ComboBox_MeasureItem);
}
// Allow Combo Box to center aligned and manually draw our items
private void ComboBox_DrawItem(object sender, DrawItemEventArgs e)
{
// Draw the background
e.DrawBackground();
// Draw the items
if (e.Index >= 0)
{
// Set the string format to our desired format (Center, Near, Far)
StringFormat sf = new StringFormat();
sf.LineAlignment = _textAlign;
sf.Alignment = _textAlign;
// Set the brush the same as our ForeColour
Brush brush = new SolidBrush(this.ForeColor);
// If this item is selected, draw the highlight
if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
brush = SystemBrushes.HighlightText;
// Draw our string including our offset.
e.Graphics.DrawString(this.Items[e.Index].ToString(), this.Font, brush,
new RectangleF(e.Bounds.X, e.Bounds.Y + _textYOffset, e.Bounds.Width, e.Bounds.Height), sf);
}
}
// If you set the Draw property to DrawMode.OwnerDrawVariable,
// you must handle the MeasureItem event. This event handler
// will set the height and width of each item before it is drawn.
private void ComboBox_MeasureItem(object sender,System.Windows.Forms.MeasureItemEventArgs e)
{
// Custom heights per item index can be done here.
}
}
Now we have full control over our font and height of the ComboBox separately. We no longer need to make a large font to size our ComboBox.
If you are wanting to adjust to the number of items in the ComboBox you can change the value of the DropDownHeight as follows, given a List of items. I'm using 24 here as a "per item amount"; this is by no means fixed.
comboBox1.DropDownHeight = SomeList.Count * 24;
ComboBox has a property 'DropDownHeight' which can be changed either via the properties window of the combobox or programmatically. i.e.
public partial class EventTestForm : Form
{
public EventTestForm()
{
InitializeComponent();
cmbOwners.DropDownHeight = 100;
}
In code, a.Height should work. In the designer, go into the properties and look in Size->Height.
Alternatively, you can change the Font Size and the combo box will grow bigger to accomodate it, but I don't think that's what you want.
I want to change the color of the items that are chedked in the CheckedListBox in C# WindowsForms.
Can any one help me to solve this problem!
This should get you started. I've subclassed a CheckedListBox and overridden the drawing event. The result is all checked items in the list are drawn with a red background.
From playing around with this, if you want the area behind the checkbox to be a different colour as well, use e.Graphics.FillRectangle before calling base.OnDrawItem.
class ColouredCheckedListBox : CheckedListBox
{
protected override void OnDrawItem(DrawItemEventArgs e)
{
DrawItemEventArgs e2 =
new DrawItemEventArgs
(
e.Graphics,
e.Font,
new Rectangle(e.Bounds.Location, e.Bounds.Size),
e.Index,
e.State,
e.ForeColor,
this.CheckedIndices.Contains(e.Index) ? Color.Red : SystemColors.Window
);
base.OnDrawItem(e2);
}
}
Thanks Jon that got me on the right path as I had the same desire: to have the item's text color be different for each of the 3 states of the checkbox.
I came up with this subclass of the CheckedListBox. It changes the items text, not the background color. It lets the 3 colors be set by the user at design time or in code of course.
It also fixes a problem I had where I got an error when viewing the control in the designer. I also had to overcome a problem I think would have happened in your solution where if the item is selected the base.OnDrawItem method obliterates the color choices set in the overridden OnDrawItem method. I did this at the expense of the selected item no longer having a colored background by removing the part of e.State that says it is selected so that in the base.OnDrawItem it is not made to be a selected item look and feel. This is ok though I think since the user will see the focus rectangle still which indicates which is selected.
Hopefully this may be useful to others. I didn't find much for a cohesive solution (even just a complete OnDrawItem method) when looking on the net.
using System;
using System.Windows.Forms;
using System.Drawing;
namespace MyNameSpace
{
/// <summary>
/// This is a CheckedListBox that allows the item's text color to be different for each of the 3 states of the corresponding checkbox's value.
/// Like the base CheckedListBox control, you must handle setting of the indeterminate checkbox state yourself.
/// Note also that this control doesn't allow highlighting of the selected item since that obscures the item's special text color which has the special meaning. But
/// the selected item is still known to the user by the focus rectangle it will have surrounding it, like usual.
/// </summary>
class ColorCodedCheckedListBox : CheckedListBox
{
public Color UncheckedColor { get; set; }
public Color CheckedColor { get; set; }
public Color IndeterminateColor { get; set; }
/// <summary>
/// Parameterless Constructor
/// </summary>
public ColorCodedCheckedListBox()
{
UncheckedColor = Color.Green;
CheckedColor = Color.Red;
IndeterminateColor = Color.Orange;
}
/// <summary>
/// Constructor that allows setting of item colors when checkbox has one of 3 states.
/// </summary>
/// <param name="uncheckedColor">The text color of the items that are unchecked.</param>
/// <param name="checkedColor">The text color of the items that are checked.</param>
/// <param name="indeterminateColor">The text color of the items that are indeterminate.</param>
public ColorCodedCheckedListBox(Color uncheckedColor, Color checkedColor, Color indeterminateColor)
{
UncheckedColor = uncheckedColor;
CheckedColor = checkedColor;
IndeterminateColor = indeterminateColor;
}
/// <summary>
/// Overriden draw method that doesn't allow highlighting of the selected item since that obscures the item's text color which has desired meaning. But the
/// selected item is still known to the user by the focus rectangle being displayed.
/// </summary>
/// <param name="e"></param>
protected override void OnDrawItem(DrawItemEventArgs e)
{
if (this.DesignMode)
{
base.OnDrawItem(e);
}
else
{
Color textColor = this.GetItemCheckState(e.Index) == CheckState.Unchecked ? UncheckedColor : (this.GetItemCheckState(e.Index) == CheckState.Checked ? CheckedColor : IndeterminateColor);
DrawItemEventArgs e2 = new DrawItemEventArgs
(e.Graphics,
e.Font,
new Rectangle(e.Bounds.Location, e.Bounds.Size),
e.Index,
(e.State & DrawItemState.Focus) == DrawItemState.Focus ? DrawItemState.Focus : DrawItemState.None, /* Remove 'selected' state so that the base.OnDrawItem doesn't obliterate the work we are doing here. */
textColor,
this.BackColor);
base.OnDrawItem(e2);
}
}
}
}