如何使用keybord焦点创建非活动下拉列表 [英] How to create a non active dropdown with keybord focus

查看:68
本文介绍了如何使用keybord焦点创建非活动下拉列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个下拉控件,该控件应该处于非活动状态并具有键盘输入焦点。所以我创建了一个控件如下。



I want to create a dropdown control which should be inactive and have keyboard input focus. So I created a control as below.

public class DropDownEdit : UserControl
{
    [DllImport("user32.dll")]
    public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

    private const int WS_EX_TOOLWINDOW = 0x00000080;
    private const int WS_EX_TOPMOST = 0x00000008;
    private const int WS_EX_NOACTIVATE = 0x08000000;
    private const int WS_CHILD = 0x40000000;
    private const int WS_POPUP = unchecked((int)0x80000000);

    private TextBox text = new TextBox();

    public DropDownEdit()
    {
        this.BackColor = Color.FromArgb(44, 68, 107);
        this.Controls.Add(text);
        this.Margin = Padding.Empty;
        this.Padding = new Padding(0);
        text.Multiline = true;
        text.ScrollBars = ScrollBars.Both;
        text.Size = new Size(this.Width, this.Height);
    }

    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams createParams = base.CreateParams;
            createParams.Style &= ~WS_CHILD;
            createParams.Style |= WS_POPUP;

            createParams.ExStyle |= WS_EX_TOOLWINDOW;
            createParams.ExStyle |= WS_EX_TOPMOST;
            createParams.ExStyle |= WS_EX_NOACTIVATE;
            return createParams;
        }
    }

    public void ShowWindow(Point point)
    {
        text.Focus();
        this.Capture = true;
        SetParent(this.Handle, IntPtr.Zero); 
        this.Location = point;
        Show();
    }

    protected override void OnMouseCaptureChanged(EventArgs e)
    {
        base.OnMouseCaptureChanged(e);
        this.Hide();
    }
}





当我显示上面的下拉窗口时,





And when I am displaying the above dropdown window as below,

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        Point point = this.PointToScreen(button1.Location);
        DropDownEdit window = new DropDownEdit();
        window.ShowWindow(new Point(point.X, point.Y + 20));
    }
}





Form1 有一个显示 DropDownEdit 时闪烁。我认为 DropDownEdit 被激活, Form1 失去激活。如何在 Form1 中避免这种闪烁?

注意: - 我需要输入焦点 TextBox 在下拉控件中。



The Form1 has a flickering while displaying DropDownEdit. I think DropDownEdit get activated and Form1 loses its activation. How can I avoid this flickering in Form1?
NB:- I need input focus on TextBox in the dropdown control.

推荐答案

听听它的声音是非主动下拉键盘焦点。什么不活动可以有键盘焦点?为什么?它可能做什么?它似乎没有任何意义。



你遇到的另一个问题是使用P / Invoke。您不需要P / Invoke来设置父级。父母是通过作业设定的

Just listen how it sounds "non-active drop down with keyboard focus". How anything inactive could have keyboard focus? Why? what it could possibly do? It does not seem to make any sense.

Another problem you have is using P/Invoke. You don't need P/Invoke to set a parent. A parent is set by assignment
myControl.Parent = someOtherControl;



或使用


or using

someOtherControl.Controls.Add(myControl);



P / Invoke不是绝对必需的,它使用起来很糟糕;它会破坏你代码的平台兼容性。



-SA


我找到了解决方案。



显示我的下拉窗口时,它将收到激活,Windows将停用主窗口。解决此问题的方法是向父级发送 WM_NCACTIVATE 消息,以更新其可视外观而不更改其激活状态。以下代码在 DropDownEdit 类中更新以解决我的问题。



I found a solution.

While displaying my dropdown window it will receive activation and Windows will deactivate the main window. The fix for this is to send a WM_NCACTIVATE message to the parent to update its visual appearance without changing its activation status. The below code is updated in DropDownEdit class to solve my issue.

private const int WM_NCACTIVATE = 0x86;

[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);

protected override void WndProc(ref Message m)
{
    // The popup needs to be activated for the user to interact with it,
    // but we want to keep the owner window's appearance the same.
    if ((m.Msg == WM_NCACTIVATE) && !_activating && (m.WParam != IntPtr.Zero))
    {
        // The popup is being activated, ensure parent keeps activated appearance
        _activating = true;
        SendMessage(this.Owner.Handle, WM_NCACTIVATE, (IntPtr) 1, IntPtr.Zero);
        _activating = false;
        // Call base.WndProc here if you want the appearance of the popup to change
    }
    else
    {
        base.WndProc(ref m);
    }
}


这篇关于如何使用keybord焦点创建非活动下拉列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆