Почему ComboBox скрывает курсор при установке DroppedDown?

Позвольте создать приложение WinForms (у меня Visual Studio 2008 работает в Windows Vista, но похоже, что описанная ситуация происходит почти везде от Win98 до Vista, от собственного или управляемого кода).

Напишите такой код:

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;
        }
    }
}

Затем запустите приложение. Поместите курсор мыши на форму и больше не касайтесь мыши. Начните вводить что-то в TextBox - курсор скроется из-за него. Когда вы нажимаете клавишу "Enter" - выбросы событий и ComboBox будут сброшены. Но теперь курсор не появится, даже если вы его переместите! И появляется только тогда, когда вы нажимаете где-то.

Там Я нашел обсуждение этой проблемы. Но нет хорошего решения...

Любые мысли?:)

Ответ 1

Мне удалось решить проблему следующим образом:

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

Если вы попали по этой проблеме, как и я, я рекомендую проголосовать за связанный отчет об ошибке Microsoft. Может быть, когда-нибудь они это исправит!

Ответ 2

Для начала это очень неясный набор обстоятельств, которые я не могу себе представить как полезное действие интерфейса.

Казалось бы, это ошибка, из-за которой программный выпадающий список начинает редактирование в текстовом поле, которое является частью выпадающего элемента управления, что позволяет эффективно скрывать курсор. Чтобы сломать его...

Я подозреваю, что каждый скрыть сохраняет состояние курсора и восстанавливает его при выходе.

Текстовое поле сохранит фактическое состояние курсора и скрыло его.

В раскрывающемся списке скрытое состояние сохраняется, а курсор - скрытым. Когда вы перемещаете курсор, он, вероятно, восстанавливает его, но в скрытом состоянии он сохраняется, поэтому курсор остается скрытым.

Щелчок на форме, кажется, заставляет reset этой ситуации, не уверен, почему на этом, но что мой 2 достоинства.

Ответ 3

Фактически я смог решить эту проблему следующим образом:

#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
}

Но это не то решение, которое я хочу:( Это скорее костыль, но не решение.

Ответ 4

Я получил эту проблему в приложении Delphi. Как было предложено здесь Я просто добавил SendMessage(ComboBox1.Handle, WM_SETCURSOR, 0, 0) после любого события DropDown, и он сработал.

Ответ 5

Это странный набор обстоятельств, когда поле со списком является типом DropDownList, и вы вызываете метод DroppedDown в поле со списком внутри кода либо в то время, когда оно имеет фокус, либо нет.

Курсор исчезнет, ​​как бы за формой. Если вы нажмете форму, возвращаемую курсором, но поле со списком закрывается, поэтому не будет хорошего результата.

Я могу подтвердить, что этот код исправляет проблему, не закрывая список списков сокетов.

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