views:

706

answers:

5

Let's create WinForms Application (I have Visual Studio 2008 running on Windows Vista, but it seems that described situation takes place almost everywhere from Win98 to Vista, on native or managed code).

Write such code:

using System;
using System.Drawing;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public class Form1 : Form
    {
        private readonly Button button1 = new Button();
        private readonly ComboBox comboBox1 = new ComboBox();
        private readonly TextBox textBox1 = new TextBox();

        public Form1() {
            SuspendLayout();
            textBox1.Location = new Point(21, 51);
            button1.Location = new Point(146, 49);
            button1.Text = "button1";
            button1.Click += button1_Click;
            comboBox1.Items.AddRange(new[] {"1", "2", "3", "4", "5", "6"});
            comboBox1.Location = new Point(21, 93);
            AcceptButton = button1;
            Controls.AddRange(new Control[] {textBox1, comboBox1, button1});
            Text = "Form1";
            ResumeLayout(false);
            PerformLayout();
        }

        private void button1_Click(object sender, EventArgs e) {
            comboBox1.DroppedDown = true;
        }
    }
}

Then, run app. Place mouse cursor on the form and don't touch mouse anymore. Start to type something in TextBox - cursor will hide because of it. When you press Enter key - event throws and ComboBox will be dropped down. But now cursor won't appear even if you move it! And appears only when you click somewhere.

There I've found discussion of this problem. But there's no good solution...

Any thoughts? :)

+1  A: 

For a start, it's a very obscure set of circumstances that I can't imagine being a useful interface action.

It would seem to be a bug that causes the programmatic dropdown to start editing in the text box that forms part of the dropdown control so effectively double hiding the cursor. To break it down...

I'd suspect that each hide stores the state of the cursor and restores it on exit.

The text box has stored the actual cursor state and hidden it.

The dropdown causes the hidden state to be stored and the cursor set to hidden. When you move the cursor it probably does restore it but to the hidden state it saved so the cursor remains hidden.

A click on the form seems to force a reset of that situation, not sure why on that but that's my 2 penneth worth.

Lazarus
Yep, my thought was similar. But how can I resolve such situation?I have business app where TextBox is filled with search string, Button is "Search" and ComboBox is filled with search results. And described scenario is absolutely real - users suffer from it right now! :)I'm trying now to simulate mouse click on down arrow button instead of setting DropedDown, but it doesn't seem as good solution for me :(
Ivan Danilov
If the search fills the combo, what about using the keypress event from the combo to progressively search and fill the dropdown a la a lot of AJAXified web search boxes? i.e. eliminate the textbox and button and provide a more seamless output, you could limit the search return list to 50 items to avoid a dropdown with 1000s of values or only search when you have 3 or more characters. Lots of ways to improve the user experience. Otherwise, perhaps a listbox would be a better solution?
Lazarus
+1  A: 

In fact I was able to resolve this issue in this way:

#region Dirty methods :)
#pragma warning disable 169
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern void mouse_event(long dwFlags, long dx, long dy, long cButtons, long dwExtraInfo);

private const int MOUSEEVENTF_ABSOLUTE = 0x8000;
private const int MOUSEEVENTF_MOVE = 0x1;
private const int MOUSEEVENTF_LEFTDOWN = 0x02;
private const int MOUSEEVENTF_LEFTUP = 0x04;
private const int MOUSEEVENTF_RIGHTDOWN = 0x08;
private const int MOUSEEVENTF_RIGHTUP = 0x10;
#pragma warning restore 169
#endregion

private void button1_Click(object sender, EventArgs e) {
   Point oldCursorPos = Cursor.Position; // save pos
   Point a = comboBox1.Parent.PointToScreen(comboBox1.Location);
   a.X += comboBox1.Width - 3;
   a.Y += comboBox1.Height - 3;
   Cursor.Position = a;
   // simuate click on drop down button
   mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
   Cursor.Position = oldCursorPos; // restore pos
}

But it is not the solution I want :( It is rather a crutch but not a solution.

Ivan Danilov
+2  A: 

I was able to work around the problem like this:

comboBox1.DroppedDown = true;
Cursor.Current = Cursors.Default;

If you get hit by this issue as I did, I recommend voting up the related Microsoft bug report. Maybe someday they'll fix it!

Daniel Stutzbach
It is very simple, thanks :)
Ivan Danilov
A: 

thank you very much, it is long, I'm looking for this solution

arffak abdallah
A: 

Thanks Daniel Stutzbach for providing the solution

Rupak Basack