Inherit ComboBox / Windows Vista

N

Nathan Laff

Why when I inherit a ComboBox and make no code changes, when I set the new
control DropDownStyle to dropDownList it appears different than the standard
ComboBox control on Vista?

In Windows Vista when this mode is set, the control is all one color
indicating that you can't type in it and looks really slick. How do i
reproduce this behavior?
 
T

Tom Porterfield

Nathan said:
Why when I inherit a ComboBox and make no code changes, when I set the
new control DropDownStyle to dropDownList it appears different than the
standard ComboBox control on Vista?

In Windows Vista when this mode is set, the control is all one color
indicating that you can't type in it and looks really slick. How do i
reproduce this behavior?

Are you overriding or modifying any behavior. Just tried it here with
my own combobox inheriting from System.Windows.Forms.ComboBox and the
display renders exactly the same as a System.Windows.Forms.ComboBox when
the DropDownStyle is set to DropDownList.
 
N

Nathan Laff

Are you overriding or modifying any behavior. Just tried it here with my
own combobox inheriting from System.Windows.Forms.ComboBox and the display
renders exactly the same as a System.Windows.Forms.ComboBox when the
DropDownStyle is set to DropDownList.

Ok, here is what happened, I forgot to override OnPaint and pass in
base.OnPaint.

So that fixed the problem of a blank control not working. However I am doing
DrawMode of OwnerDrawFixed.
Basically it's drawing images next to my comboBox items. Any idea how to
maintain the look that it should, while drawing these images?
 
N

nx-2000

Basically it's drawing images next to mycomboBoxitems. Any idea how to
maintain the look that it should, while drawing these images?

I'm having the same issue with Vista, here's the quick code I posted
trying to get help(maybe someone in this group has some better
suggestions).

public class ColoredComboBox : ComboBox
{


public ColoredComboBox()
{
this.DrawMode = DrawMode.OwnerDrawFixed;
this.DrawItem += new
DrawItemEventHandler(ColoredComboBox_DrawItem);
}
void ColoredComboBox_DrawItem(object sender, DrawItemEventArgs e)
{
e.DrawBackground();
// don't even care about text, my icon, or anything else at this
point, just want the background to work.
}
}
 
N

nx-2000

If you want to do this you have to handle WM_PAINT and paint the thing
yourself using DrawThemeBackground.
Here's the long explanation of it:
http://www.eggheadcafe.com/software/aspnet/29400336/re-dropdown-list-...

Sure would be nice if the shell developers provided some code as an
example of how to work around the situation they put us in. Maybe
then they'd understand and release a patch rather than the hack that
by their own admission may not work on future releases of windows.

The combobox seems to always get the shaft, the project I'm upgrading
was from .NET v1.x and I'm cutting out all the hacks that where put in
place to allow windows 95 style auto-complete to now find that I get
to put in another series of hacks until v3.5 or whenever.
 
N

nx-2000

Here's what I put together over the last few hours of trial and error
and a bunch of searching. I originally was using DrawThemeBackground
and so forth but eventually dumped it and used the easier
VisualStyleRender's(which are just wrappers, I know, but at least they
are included). Its got a lot of specific stuff to the app I'm using
but should at least give someone a lot of cut-n-paste if they find
this topic in the future.


public class ColoredComboBox : ComboBox
{
#region Private Members
private bool IsVista;
private ComboBoxState cb_State = ComboBoxState.Normal;
#endregion
#region Public Members
private Image ListaImg1 = null;
public Image ImageData1
{
set
{
ListaImg1 = value;
if (value != null)
{
if (this.DrawMode !=
System.Windows.Forms.DrawMode.OwnerDrawFixed)
{
this.DrawMode =
System.Windows.Forms.DrawMode.OwnerDrawFixed;
if (this.DropDownStyle !=
ComboBoxStyle.DropDownList)
this.DropDownStyle =
ComboBoxStyle.DropDownList;
}
}
}
get { return (ListaImg1); }
}
private Image ListaImg2 = null;
public Image ImageData2
{
set
{
ListaImg2 = value;
if (value != null)
{
if (this.DrawMode !=
System.Windows.Forms.DrawMode.OwnerDrawFixed)
{
this.DrawMode =
System.Windows.Forms.DrawMode.OwnerDrawFixed;
if (this.DropDownStyle !=
ComboBoxStyle.DropDownList)
this.DropDownStyle =
ComboBoxStyle.DropDownList;
}
}
}
get { return (ListaImg2); }
}
#endregion
#region Constructor
public ColoredComboBox()
{
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.UserPaint, true);
IsVista = ((Environment.OSVersion.Version >= new
Version("6.0.0")) && (Environment.OSVersion.Platform ==
PlatformID.Win32NT));
this.DropDownStyle = ComboBoxStyle.DropDownList;
this.FlatStyle = FlatStyle.System;
this.DrawMode =
System.Windows.Forms.DrawMode.OwnerDrawFixed;
this.DrawItem += new
DrawItemEventHandler(ColoredComboBox_DrawItem);
}
#endregion
#region DrawIcon
private Rectangle DrawIcon(Graphics g,Rectangle r, object
iconData1, object iconData2)
{
Rectangle newBounds = r;
if (iconData2 != null && iconData1 != null)
{
int x = r.X;
int w = this.Height - 4;
newBounds.X += w;
newBounds.Width -= w;
if (iconData2.ToString() == "True" && ImageData2 !=
null) // draw icon
{
w -= 4;
g.DrawImage(ImageData2, r.X + 1, r.Y + 1, w, w);
}
else if (iconData1.ToString() == "True" && ImageData1 !
= null) // draw icon
{
w -= 4;
g.DrawImage(ImageData1, r.X + 1, r.Y + 1, w, w);
}
}
return (newBounds);
}
#endregion
#region DrawItem
protected void ColoredComboBox_DrawItem(object sender,
DrawItemEventArgs e)
{
e.DrawBackground();
DrawItemText(e.Graphics, e.Bounds, e.Index);
e.DrawFocusRectangle();
}
private void DrawItemText(Graphics g,Rectangle r,int Index)
{
if (Index == -1 || Items.Count == 0)
return;
Color c = ForeColor;
Descriptor d = new Descriptor(Items[Index].ToString(),
Items[Index].ToString(), null, null, null);
try
{
d = (Descriptor)Items[Index];
if (d.Data3 != null)
c = (Color)d.Data3;
}
catch { }
SolidBrush b = new SolidBrush(c);
g.DrawString(d.Name, this.Font, b, DrawIcon(g,r, d.Data1,
d.Data2));
b.Dispose();
}
private void DrawArrow(Graphics g, Rectangle rect)
{
Point p1 = new Point(rect.X + 3, rect.Y + rect.Height / 2
- 2);
Point p2 = new Point(rect.X + rect.Width - 3, rect.Y +
rect.Height / 2 - 2);
Point p3 = new Point(rect.X + rect.Width / 2, rect.Y +
rect.Height / 2 + 2);
g.FillPolygon(new
SolidBrush(System.Drawing.SystemColors.ControlText), new Point[]{p1,
p2, p3});
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);

if (Enabled == false)
cb_State=ComboBoxState.Disabled;
Rectangle r = e.ClipRectangle;
if (IsVista)
{
PushButtonState pb_State = PushButtonState.Normal;
if (cb_State == ComboBoxState.Disabled)
pb_State = PushButtonState.Disabled;
else if (cb_State == ComboBoxState.Hot)
pb_State = PushButtonState.Hot;
else if (cb_State == ComboBoxState.Pressed)
pb_State = PushButtonState.Pressed;
ButtonRenderer.DrawButton(e.Graphics, r,pb_State);
r = new Rectangle(r.Right -
System.Windows.Forms.SystemInformation.VerticalScrollBarWidth+2,
e.ClipRectangle.Top,
System.Windows.Forms.SystemInformation.VerticalScrollBarWidth-4,
e.ClipRectangle.Height);
DrawArrow(e.Graphics, r);
}
else
{
ComboBoxRenderer.DrawTextBox(e.Graphics, r, cb_State);
r = e.ClipRectangle;
r = new Rectangle(r.Right -
System.Windows.Forms.SystemInformation.VerticalScrollBarWidth,
e.ClipRectangle.Top,
System.Windows.Forms.SystemInformation.VerticalScrollBarWidth,
e.ClipRectangle.Height);
ComboBoxRenderer.DrawDropDownButton(e.Graphics, r,
cb_State);
}
r = e.ClipRectangle;
r.Inflate(0, -2);
r.Offset(0, 1);
DrawItemText(e.Graphics,r,SelectedIndex);
}
#endregion
#region Mouse Movement
// Draw the smaller pressed button image.
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
cb_State = ComboBoxState.Pressed;
Invalidate();
}

// Draw the button in the hot state.
protected override void OnMouseEnter(EventArgs e)
{
base.OnMouseEnter(e);
cb_State = ComboBoxState.Hot;
Invalidate();
}

// Draw the button in the unpressed state.
protected override void OnMouseLeave(EventArgs e)
{
base.OnMouseLeave(e);
cb_State = ComboBoxState.Normal;
Invalidate();
}

// Draw the button hot if the mouse is released on the
button.
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
OnMouseEnter(e);
}

// Detect when the cursor leaves the button area while
// it is pressed.
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);

// Detect when the left mouse button is down and
// the cursor has left the pressed button area.
if ((e.Button & MouseButtons.Left) == MouseButtons.Left &&
!ClientRectangle.Contains(e.Location) &&
cb_State == ComboBoxState.Pressed)
{
OnMouseLeave(e);
}
}

#endregion
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top