Hello,
I'm extending the .NET ComboBox control in several ways. One way is that
when the user types something into the textbox portion, I try to jump to a
matching item in the dropdown (which I expand). If the substring entered by
the user exactly matches the display text of an item, then I select that item
using the SelectedIndex property. If the text typed by the user doesn't
match any item in the list of dropdown items, then I select the item (again
with SelectedIndex) that 'closest' matches the text typed by the user. (The
list of items is sorted).
All of the above is working as I'd like. The one thing I'd like to do is to
change the way a selected item in the dropdown appears if it is selected to
indicate it is the 'closest' or 'near' match, but doesn't actually match what
the user typed in the textbox.
My preferred way to indicate a "near" match would be to change the
background colour of the selected item such that it is the same as the rest
of the dropdown background colour (white by default), and only leave a small
coloured border around the selected item. For example, the selectedItem
would not display with a blue background colour; it would be white, with just
a thin black or blue (or whatever the default selection background colour is)
border around the text of the selected item.
If I can't do the border idea, then as a second best choice, it would be
okay to change the background colour of the selected item to something other
than the system selected background colour. For example, if the normal
selected background colour is blue, then in the case of a "near" match, I
might change the background colour to red.
My question is how to achieve this. I'm guessing I might be able to call my
background colour changing logic from an override of WndProc and look at the
WM_CTLCOLORLISTBOX message. Is that right? I don't know how:
1) determine the default background colour of a selected item and either
2) draw the selected item such that the selectedItem background colour is
transparent/same as dropdown background, and also draw a border around the
selected item OR
3) simply change the background colour of the selected item
Any help is appreciated. Thank you!
Notre
Linda Liu [MSFT] - 18 Dec 2006 08:56 GMT
Hi Notre,
I have spent several hours researching on this problem, but unfortunately,
I haven't found a workaround to change the back color of the selected item
in a ComboBox control.
In my opinion, I suggest that you change the back color of a specified item
(or draw a colored border around the text of the item), which is a more
common usage.
To change the back color of a specified item or draw a colored border for
the specified item in a ComboBox control, set the DrawMode property of the
ComboBox to OwnerDrawFixed and then handle the DrawItem event or override
the OnDrawItem method.
The following is a sample of deriving a new control from ComboBox and
drawing colored borders around the specified items.
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
class MyComboBox:ComboBox
{
public MyComboBox()
{
this.DrawMode = DrawMode.OwnerDrawFixed;
}
private List<int> specialItems = new List<int>();
public List<int> SpecialItems
{
get { return specialItems; }
}
protected override void OnDrawItem(DrawItemEventArgs e)
{
DrawItemEventArgs newe = null;
Rectangle rect = new Rectangle();
rect.X = e.Bounds.X;
rect.Y = e.Bounds.Y;
rect.Width = e.Bounds.Width - 1;
rect.Height = e.Bounds.Height - 1;
if (this.specialItems.Contains(e.Index))
{
newe = new DrawItemEventArgs(e.Graphics, e.Font, rect,
e.Index, e.State);
}
else
{
newe = e;
}
newe.DrawBackground();
newe.Graphics.DrawString(this.Items[newe.Index].ToString(),
newe.Font, new SolidBrush(newe.ForeColor), newe.Bounds);
if (this.specialItems.Contains(e.Index))
{
newe.Graphics.DrawRectangle(Pens.Blue, newe.Bounds);
}
base.OnDrawItem(e);
}
}
Then in the DropDown event handler of the derived ComboBox control, add the
indexes of the specified items into the SpecialItems property of the
derived ComboBox.
Hope this helps.
If you have any concerns, please feel free to let me know.
Sincerely,
Linda Liu
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.
Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.