|
Hi
Thnx it works 4 me as well in VS2005 thnx
|
|
|
|
|
Like many who use The Code Project we've spent countless hours building custom controls to meet our needs. Unfortunately, it's hard to justify spending thousands of hours on a custom control unless you intend to market them.
We've just released a beta of List Controls for .NET WinForms which includes the most advanced list box and combo box controls ever built for any platform.
Sounds too good to be true? Please, confirm this statement for yourself. A beta of List Controls is available for download from our website, including a comprehensive demo and tutorial.
http://www.it-partners.com/products/list_controls_win_forms/list_controls.asp[^]
Many features, too many to list here!
Brett Werner
it-partners.com
|
|
|
|
|
I want to use color in combo box and arow and background color of combo box.
plz help me how can i change it through CSS classes.
Ajay
Advance Scripter
|
|
|
|
|
Hi Ajay,
Unfortunately to my knowledge, you can only use css style with web control and not winform control. I would think to implement support for css will involve a lot of work.
I dont use css much and I would welcome pointers from others.
Fadrian
|
|
|
|
|
Hi,
I've slightly changed your control for my purpose and add colored border
onto it, problem is however with inner listbox. I think I will propably have to subclass it and redirect WM_NCPAINT to fake WndProc function, when I'll draw border of listbox in appropriate color. Do you plan to add this behaviour to your control? If you have it already, please let me know, I would like to save some time in writing it.
Thanks
Martin
martinhoge@seznam.cz
|
|
|
|
|
Martin,
I haven't done anything on that area yet. If you have done something it will be nice if you can share your work here.
Thanks,
Fadrian
|
|
|
|
|
There is a problem when i change RightToLeft property to Yes
|
|
|
|
|
Booky,
Thanks for pointing that out. It is something that I haven't looked at before
Well, I did a quick hack just then and it works for me. Below is the snipplet of the code that will do the job. Replace the original PaintFlatDropDown function with the revised code below.
private static bool DrawRightToLeft(Control ctrl)
{
if (ctrl.RightToLeft == RightToLeft.Yes ||
(ctrl.RightToLeft == RightToLeft.Inherit && ctrl.Parent.RightToLeft == RightToLeft.Yes))
{
return true;
}
return false;
}
public static void PaintFlatDropDown(Control ctrl, Graphics g)
{
Rectangle rect = new Rectangle(ctrl.Width-DropDownButtonWidth, 0, DropDownButtonWidth, ctrl.Height);
if (DrawRightToLeft(ctrl))
rect = new Rectangle(1, 0, DropDownButtonWidth, ctrl.Height);
ControlPaint.DrawComboButton(g, rect, ButtonState.Flat);
}
Hope that help.
Fadrian
|
|
|
|
|
flickering !!
If there are so much combobox in the same form, flickering is increaseing. Because Windows drawing the normal combobox before our painting.
Serdar YILMAZ
Senior Developer
|
|
|
|
|
Adding following code will not make flickering any more!!
protected override void OnPaint(PaintEventArgs e)
{
// base.OnPaint (e);
}
switch (m.Msg)
{
...
case WM_ERASEBKGND:
//indicate msg has been processed
m.Result = (IntPtr) 1;
break;
...
Thanks,
ChangYoung
jucyblue@gmail.com
jucyblue@gmail.com
|
|
|
|
|
Has no change ...
Serdar YILMAZ
Senior Developer
|
|
|
|
|
Thanks for the post and suggestion. I really don't have much idea on how to fix that, as my control is drawing on top of existing control to leverage all the existing functionality. If someone has a solution to this I will be please to know.
Fadrian
|
|
|
|
|
I changed Draw Mode of this control.
Now, there are NO flicker.
And I added ImageList properties.
public syComboBox()
{
...
...
base.SetStyle(ControlStyles.ResizeRedraw, true);
this.DrawMode = DrawMode.OwnerDrawVariable;
}
...
...
protected virtual void Draw(bool fillContent)
{
Graphics graphics1 = Graphics.FromHwnd(base.Handle);
// Drawing Border
... drawing border procedures
... if (this.isMouseOver | this.Focused) then draw HOT else draw NORMAL
// Drawing Button
ButtonState bs = (DroppedDown) ? ButtonState.Pushed : ButtonState.Normal;
... drawing combobox button procedures
if (fillContent)
{
Rectangle rectangle1 = (1, 1, this.Width-SystemInformation.HorizontalScrollBarArrowWidth-2, this.Height-2);
Color color1 = this.BackColor;
if (!base.Enabled)
{
color1 = SystemColors.Control;
}
SolidBrush brush1 = new SolidBrush(color1);
graphics1.FillRectangle(brush1, 1, 1, rectangle1.Width, 2); // top
graphics1.FillRectangle(brush1, 1, rectangle1.Bottom - 2, rectangle1.Width, 2); // bottom
graphics1.FillRectangle(brush1, 1, 1, 2, rectangle1.Height); // left
graphics1.FillRectangle(brush1, rectangle1.Right - 2, 1, 2, rectangle1.Height); // right
}
}
...
protected override void OnMouseLeave(EventArgs e)
{
base.OnMouseLeave(e);
this.isMouseOver = false;
this.Draw(false);
}
protected override void OnMouseEnter(EventArgs e)
{
base.OnMouseEnter(e);
this.isMouseOver = true;
this.Draw(false);
}
protected override void OnLostFocus(System.EventArgs e)
{
base.OnLostFocus(e);
this.Draw(false);
}
protected override void OnGotFocus(System.EventArgs e)
{
base.OnLostFocus(e);
this.Draw(false);
}
protected override void WndProc(ref Message msg)
{
if (msg.Msg == 15)
{
base.DefWndProc(ref msg);
this.Draw(true);
}
else
{
base.WndProc(ref msg);
}
}
-----------------
Serdar YILMAZ
Senior Developer
|
|
|
|
|
please, can you post the modified source ?
|
|
|
|
|
Great control, small, simple, and yet does all it's supposed to do. Well, most of it anyway, that's where I want to ask you some questions.
1.First is that I implemented a mouseenter/mouseleave event to highlight the border with different color depending on whether the mouse is hovering above the control or not. However if I repeatedly move my mouse in and out of control at least three-four times a second I notice a lot of flickering at the drop down button. My guess is that when you do a WM_PAINT event you let the default wndproc to take over and then paint the custom border and dropdown button which causes the flickering. Is there any way to redraw this manually without base class? I tried it, but I'm very new at this whole GDI and window messages thing, so, not surprisingly I failed.
2.This is also related to mouseenter/mouseleave thing. You said that your combobox did not work with simple style. What did you mean by that, what exactly did not work? Because for some reason, and I don't know why I have problems when the style is set to dropdown instead of dropdownlist. The issue I have is that when I set the style to dropdown, sometimes, when I move the mouse quickly in or out of the control mouseenter/mouseleave events do not fire. So the border of the control does not change, it's really annoying. I tried catching wm_mouseleave message in the wndproc, but it seems it never gets sent. Any idea what's causing it?
I also posted a question about your datetimepicker control. Can you take a look at it too?
Thanks.
|
|
|
|
|
Thanks for your input.
I haven't looked at the control for a while, so it is a slow start for me as well. These are my answers to your questions:
1. Instead of doing the drawing in mouseenter and mouseleave, I suggest that you just set a bool flag in those function such as m_bMouseEntered = true in the mouseenter even tna m_bMouseEntered = false in the mouseleave event. Change the implementation of PaintFlatControlBorder so that it first test for if (m_bMouseEntered) then call ControlPaint.DrawBorder(g, rect, MyColor, ButtonBorderStyle.Solid);
2. ComboBox has 3 style, simple style looks like a normal List control. you can set that property and have a look at your winform for the difference. I don't think the dropdownlist and dropdown style would be different in dealing with those events.
|
|
|
|
|
first and foremost, good job!
second, I noticed that in WndProc you have:
IntPtr hDC = GetWindowDC(this.Handle);
Graphics gdc = Graphics.FromHdc(hDC);
however, only messages WM_NC_PAINT and WM_PAINT make use of them, while for any other message they're not used at all, therefore, my advice to you would be to limit their scope to just the observed messages. In any case I know you're cleaning up:
ReleaseDC(m.HWnd, hDC);
gdc.Dispose();
however, why create and dispose of resources, in this case, relatively expensive resources, that will not be used.
good luck
|
|
|
|
|
Thanks. I agree with your point. The code was structured that way was partially caused by my laziness and also trying to make the code as easy to read as possible. I did plan to build up a library of these controls, but I have stopped for a while due to some change in circumstances. Keep your suggestions coming and will benefit me and others
|
|
|
|
|
I have a Sony Vaio with 1900x1200 resolution.
This FlatCombobox works great, except there is an odd artifact:
Ther is a wide 3D gap showing between the Textbox portion of the control and the arrow part of the control.
Any ideas on this? I tried it as a C# dll and also with the VB.Net code snippet. They both do the same thing.
Elizabeth Gee
Information Architect - .Net Developer
http://www.nwtd.com
|
|
|
|
|
Liz,
Geez.. that is a very wide screen that you have! I haven't got the environment to try, but did you try my suggested code in other thread:
====================================================
When it come to adjusting for drawing, I tempt to use the graphic resolution, so say "g" is the Graphics object, I would do something like this:
int iWidth = (int) ((g.DpiX/96.0f) * DROPDOWNWIDTH);
I use 96 there because that is the pixel size for standard font display. I also make it a float so that we keep the precision when performing the math.
====================================================
See if that works for you.
Fadrian
|
|
|
|
|
Fadrian,
I am new to CodeProject.com and am excited to hear from you. Yes I did add this dropdownwidth code snippet from ont of the threads as well as the resize snippet.
I also added the OnResize snippet
Everything compiles well.
I think it may be the videocard on the Sony Vaio stretches things, as I am having troubles with the rest of my form where relative co-ordinates are working out better than absolute co-ordinates. This is interesting, and may become more of an issue for software developers as the panoramic screen resolutions become more common over time.
Elizabeth Gee
Information Architect - .Net Developer
http://www.nwtd.com
|
|
|
|
|
BTW,
I went to the Form level properties and set the AutoScale to False. This did not change the Bug on the control where there is a 3D wide artifact between the textbox and the arrow.
Elizabeth Gee
Information Architect - .Net Developer
http://www.nwtd.com
|
|
|
|
|
Liz,
AutoScale can be nasty and I constantly run into problem with it.
Can you capture the screen of the 3D wide artifact problem and send to my email a/c? Once I see the exact prob, I may be able to make other suggestion.
Fadrian
|
|
|
|
|
Here is a link to a screenshot of your Flat Combo on my Sony Vaio at 16oox1200 resolution:
http://www32.brinkster.com/icontoo/Temp/FlatComboOnSonyVaio.html
Also, here is your code with the two modifications made by others, which I compiled down to a C# DLL as depicted in the screenshot:
using System;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Runtime.InteropServices;
namespace DrawFlat
{
[ToolboxBitmap(typeof(System.Windows.Forms.ComboBox))]
public class FlatComboBox: ComboBox
{
public const int WM_ERASEBKGND = 0x14;
public const int WM_PAINT = 0xF;
public const int WM_NC_PAINT = 0x85;
public const int WM_PRINTCLIENT = 0x318;
[DllImport("user32.dll", EntryPoint="SendMessageA")]
public static extern int SendMessage (IntPtr hwnd, int wMsg, IntPtr wParam, object lParam);
[DllImport("user32")]
public static extern IntPtr GetWindowDC (IntPtr hWnd );
[DllImport("user32")]
public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC );
public FlatComboBox()
: base()
{
this.SetStyle(ControlStyles.DoubleBuffer, true);
}
protected override void OnSelectedValueChanged(EventArgs e)
{
base.OnSelectedValueChanged (e);
this.Invalidate();
}
protected override void WndProc(ref Message m)
{
if (this.DropDownStyle == ComboBoxStyle.Simple)
{
base.WndProc(ref m);
return;
}
IntPtr hDC = GetWindowDC(this.Handle);
Graphics gdc = Graphics.FromHdc(hDC);
switch (m.Msg)
{
case WM_NC_PAINT:
SendMessage(this.Handle, WM_ERASEBKGND, hDC, 0);
SendPrintClientMsg(); // send to draw client area
PaintFlatControlBorder(this, gdc);
m.Result = (IntPtr) 1; // indicate msg has been processed
break;
case WM_PAINT:
base.WndProc(ref m);
// flatten the border area again
Pen p = new Pen((this.Enabled? BackColor:SystemColors.Control), 2);
gdc.DrawRectangle(p, new Rectangle(2, 2, this.Width-3, this.Height-3));
PaintFlatDropDown(this, gdc);
PaintFlatControlBorder(this, gdc);
break;
default:
base.WndProc(ref m);
break;
}
ReleaseDC(m.HWnd, hDC);
gdc.Dispose();
}
private void SendPrintClientMsg()
{
// We send this message for the control to redraw the client area
Graphics gClient = this.CreateGraphics();
IntPtr ptrClientDC = gClient.GetHdc();
SendMessage(this.Handle, WM_PRINTCLIENT, ptrClientDC, 0);
gClient.ReleaseHdc(ptrClientDC);
gClient.Dispose();
}
private void PaintFlatControlBorder(Control ctrl, Graphics g)
{
Rectangle rect = new Rectangle(0, 0, ctrl.Width, ctrl.Height);
if (ctrl.Focused == false || ctrl.Enabled == false )
ControlPaint.DrawBorder(g, rect, SystemColors.ControlDark, ButtonBorderStyle.Solid);
else
ControlPaint.DrawBorder(g, rect, Color.Black, ButtonBorderStyle.Solid);
}
public static void PaintFlatDropDown(Control ctrl, Graphics g)
{
const int DROPDOWNWIDTH = 18;
int iWidth = (int) ((g.DpiX/96.0f) * DROPDOWNWIDTH);
//Rectangle rect = new Rectangle(ctrl.Width-DROPDOWNWIDTH, 0, DROPDOWNWIDTH, ctrl.Height);
Rectangle rect = new Rectangle(ctrl.Width-iWidth, 0, iWidth, ctrl.Height);
ControlPaint.DrawComboButton(g, rect, ButtonState.Flat);
}
protected override void OnLostFocus(System.EventArgs e)
{
base.OnLostFocus(e);
this.Invalidate();
}
protected override void OnGotFocus(System.EventArgs e)
{
base.OnGotFocus(e);
this.Invalidate();
}
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
this.Invalidate();
}
}
}
Elizabeth Gee
Information Architect - .Net Developer
http://www.nwtd.com
|
|
|
|
|
Liz,
Looks like the width of the dropdown combo is 1 pixel out. I would just change the DROPDOWNWIDTH to 19. It doesn't really matter in normal screen display for the dropdown combo to be 1 pixel wider. Perhaps 19 would be a better size to be used as it will cover the standard 17 pixel width combo and total of 2 3D pixels outer border for the left and right.
Fadrian
|
|
|
|
|