DroppedDown

  • Thread starter Chandra Kotha via DotNetMonster.com
  • Start date
C

Chandra Kotha via DotNetMonster.com

Hello Sir,

This is Chandra and Working as Software Engineer. I got a really weird
problem with ComboBoxes.

I have set the ComboBox DroppedDown Property to true.

Now the actual problem is When the ComboBox DroppedDown is Shown I have to
actually click twice to get out of the form or need to click twice to do
anything.

For Example in My Form If I have 2 Controls One is ComboBox and Another
Button Which Clicked Just Closes the Form. Then I set ComboBox DroppedDown
= true.So When the ComboBox DroppedDown = true to click on Close Button I
need to click twice to initate click event on the button.

Plz Help me on how to do it once when ComboBox DroppedDown = true.If
Combobox DroppedDown = true I need to click twicw to click X on the Form as
Well. Is this a Bug of ComboBox. I am using .NET 1.1

I am under tremendous pressure from client to perform this action.

Thanks very much

Chandra
 
E

Eric Cadwell

Why do you set the DroppedDown property to true? I'm surprised that's not a
readonly property.

-Eric
 
G

Guest

Thats what the customer wants.

Or May be is there any way of Knowing the height of the Combobox DropDown so
that i willl dismiss dropdown after an interval of say 100 ms

Thanks
 
E

Eric Cadwell

If it's dropped down, it's standard behavior that the first click outside
the drop down will close the drop down. That window is a modal dialog that
has capture of the mouse. It will not release capture until the window is
closed. That's how the dropdown knows when to close.

You might be able to override combobox and reissue the windows message to
prevent the second click. Look at SendMessage API with P/Invoke.

-Eric
 
G

Guest

Thanks Eric For your reply. But to be frank i don't know how to do it
specifed by you.
May be i want to attack it in a different way.

I want to drop down a combobox when the mouse enters and collapse it
when the mouse leaves.I did find the MouseMove event could be used to
do the drop down and it is dropping down fine in the mousemove event
for combobox.

Code Snippet:

private void cboCypher_MouseMove(object sender,
System.Windows.Forms.MouseEventArgs e)
{
Point ptCursor = Cursor.Position;

ptCursor = PointToClient(ptCursor);

if( cboCypher.Bounds.Contains(ptCursor) )>
{

//mouse over Cypher Combo
this.cboCypher.DroppedDown=true;

}

else

{

//mouse not over Cypher Combo
this.cboCypher.DroppedDown=false;

}
}

But I can not get it to collapse the combobox no matter what event I
use. I tried MouseLeave and Leave events.

I tried it even with Timer Event but the problem is when the mouse cursor is
in the droppeddown portion of the combobox droppeddown is closing.

How can I find out if the mouse cursor is still in the dropdown portion of
the combobox.

I tried it with (# of visible items * 13) + 2.

But it doesn't work sir.

Plz Help me to solve this problem sir as it is really really high priority.

Thanks very much for your time sir.
Is there any way we could implement this sir???

Thanks

Chandra.
 
E

Eric Cadwell

MouseLeave will never fire. You are right in trying to calculate if the
mouse has left the bounds of the drop down within the MouseMove. With your
code as a basis, I will try to help solve your problem.

-Eric
 
E

Eric Cadwell

This works may need some tweaks...
ignore when user clicks dropdown button when already shown
add a little buffer to bounds so it doesn't close by accident

Three classes:
AutoCombo - derived combobox that opens on MouseMove and closes when user
moves mouse outside of dropdown.
Win32 - API imports and constants.
MoveListener - listens for WM_MOUSEMOVE on the drop down window handle
wndproc and fires event to close the dropdown when cursor moves outside
bounds of the window.


using System;

using System.Diagnostics;

using System.Drawing;

using System.Runtime.InteropServices;

using System.Windows.Forms;

namespace OriginControls

{

public class AutoCombo : ComboBox

{

private IntPtr hWndDropDown = IntPtr.Zero;

private MoveListener lstnr = null;

protected override void OnMouseMove(MouseEventArgs e)

{

base.OnMouseMove(e);

this.DroppedDown = true;

}


protected override void WndProc(ref System.Windows.Forms.Message m)

{

base.WndProc(ref m);

switch (m.Msg)

{

case (Win32.WM_CTLCOLORLISTBOX):

hWndDropDown = m.LParam;


if (Win32.IsWindow(hWndDropDown))

{

Debug.WriteLine("hWnd DD: " + hWndDropDown);

lstnr = new MoveListener(this, hWndDropDown);

lstnr.AssignHandle(hWndDropDown);

lstnr.Leave += new EventHandler(lstnr_Leave);

}

break;

}

}

private void lstnr_Leave(object sender, EventArgs e)

{

if (lstnr != null)

{

lstnr.Leave -= new EventHandler(lstnr_Leave);

this.DroppedDown = false;

lstnr = null;

}

}

}


public class Win32

{

[DllImport("user32")]

public static extern bool IsWindow (IntPtr hwnd );

[StructLayout(LayoutKind.Sequential)]

public struct RECT

{

public int left;

public int top;

public int right;

public int bottom;

}

[DllImport("user32")]

public static extern bool GetWindowRect(IntPtr hwnd, ref RECT lpRect);

public const int WM_CTLCOLORLISTBOX = 0x134;

public const int WM_MOUSEMOVE = 0x0200;

}

public class MoveListener : NativeWindow

{

EventHandler leaveHandler;


ComboBox source = null;

IntPtr hWnd = IntPtr.Zero;

Rectangle bounds = Rectangle.Empty;

public MoveListener(ComboBox Source, IntPtr hWndDropDown)

{

source = Source;

hWnd = hWndDropDown;

Win32.RECT dropDownRect = new Win32.RECT();

Win32.GetWindowRect(hWnd, ref dropDownRect);

bounds = new Rectangle(dropDownRect.left, dropDownRect.top,
dropDownRect.right - dropDownRect.left, dropDownRect.bottom -
(dropDownRect.top));

bounds.Offset(0, -(source.Height / 2));

bounds.Inflate(0, source.Height / 2);

}

private void Rebound()

{

Win32.RECT dropDownRect = new Win32.RECT();

Win32.GetWindowRect(source.Handle, ref dropDownRect);

Rectangle newBounds = new Rectangle(dropDownRect.left, dropDownRect.top,
dropDownRect.right - dropDownRect.left, dropDownRect.bottom -
(dropDownRect.top));


bounds = new Rectangle(newBounds.Location, bounds.Size);

}

protected override void WndProc(ref System.Windows.Forms.Message m)

{

base.WndProc(ref m);

switch (m.Msg)

{

case (Win32.WM_MOUSEMOVE):

Rebound();

if (!bounds.Contains(Cursor.Position))

OnLeave(EventArgs.Empty);

break;

}

}

protected void OnLeave(EventArgs e)

{

if (leaveHandler != null)

leaveHandler(this, e);

}

public event EventHandler Leave

{

add { leaveHandler += value; }

remove { leaveHandler -= value; }

}

}

}


HTH;
Eric Cadwell
http://www.origincontrols.com
 

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