Почему 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;