Как закрыть форму после нажатия клавиши ESC, но только если никакой элемент управления не обработал ее? - PullRequest
1 голос
/ 30 декабря 2010

У меня есть форма, которая закрывается при нажатии клавиши ESC, благодаря KeyPreview, ProcessKeyEventArgs, ProcessCmdKey или как угодно.Но у меня есть элемент управления в этой форме, который делает очень важные вещи, когда нажимается ESC (он скрывается), и форма не должна закрываться, когда это происходит.

Элемент управления использует событие KeyDown и устанавливаетSuppressKeyPress признак true, но это происходит после вышеупомянутого предварительного просмотра ключа формы, таким образом, не имеет никакого эффекта.

Есть какой-то вид KeyPostview?

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

Редактировать: ESC управления обработкой - это текстовое поле, встроенное в ListView служанки.Текстовое поле появляется, когда пользователь щелкает ячейку, чтобы включить редакцию.Чтобы проверить новый текст, было бы неплохо ввести ENTER (это уже работает, поскольку фокусируется на чем-то еще).Чтобы отменить издание, ESC кажется наиболее естественным.

Ответы [ 4 ]

1 голос
/ 30 декабря 2010

Вы соревнуетесь в Big Time за клавишу Escape.Вместе с клавишей Enter это очень важный ключ в стандартном пользовательском интерфейсе Windows.Просто нажмите кнопку на форме и установите свойство формы CancelButton на другую кнопку, которая будет сосать нажатие на эту кнопку.

Чтобы конкурировать с этим, вы должны создать элемент управления, который сообщает Winforms, что вы действительно думаетеключ Escape больше важен.Это требует переопределения свойства IsInputKey.Как это:

using System;
using System.Windows.Forms;

class MyTexBox : TextBox {
    protected override bool IsInputKey(Keys keyData) {
        if (keyData == Keys.Escape) return true;
        return base.IsInputKey(keyData);
    }
    protected override void OnKeyDown(KeyEventArgs e) {
        if (e.KeyData == Keys.Escape) {
            this.Text = "";   // for example
            e.SuppressKeyPress = true;
            return;
        }
        base.OnKeyDown(e);
    }
}
1 голос
/ 30 декабря 2010

ОК - это работает:

class CustomTB : TextBox
{
    public CustomTB()
        : base()
    {
        CustomTB.SuppressEscape = false;
    }

    public static bool SuppressEscape { get; set; }

    protected override void OnKeyDown(KeyEventArgs e)
    {
        CustomTB.SuppressEscape = (e.KeyCode == Keys.Escape);
        base.OnKeyUp(e);
    }
}

В вашей форме:

    public Form1()
    {
        InitializeComponent();
        this.KeyPreview = true;
    }

    private void Form1_KeyUp(object sender, KeyEventArgs e)
    {
        if (e.KeyCode == Keys.Escape && !CustomTB.SuppressEscape)
        {
            this.Close();
        }
        CustomTB.SuppressEscape = false;
    }
0 голосов
/ 30 декабря 2010

Основная проблема заключается в том, что метод Dispose формы вызывается при вызове Close, поэтому форма закрывается, и с этим ничего не поделаешь.

Я бы обошел это, если бы UserControl реализовал интерфейс маркера, скажем ISuppressEsc. Затем обработчик формы KeyUp может найти фокусированный в данный момент элемент управления и отменить закрытие, если фокусированный элемент управления реализует ISuppressEsc. Помните, что вам придется проделать дополнительную работу, чтобы нашел фокусированный элемент управления , если это может быть вложенный элемент управления.

public interface ISuppressEsc
{
    // marker interface, no declarations
}

public partial class UserControl1 : UserControl, ISuppressEsc
{
    public UserControl1()
    {
        InitializeComponent();
    }

    private void textBox1_KeyUp(object sender, KeyEventArgs e)
    {
        if (e.KeyCode == Keys.Escape)
        {
            textBox1.Text = DateTime.Now.ToLongTimeString();
        }
    }
}

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

    private void Form1_KeyUp(object sender, KeyEventArgs e)
    {
        var activeCtl = ActiveControl;
        if (!(activeCtl is ISuppressEsc) && e.KeyCode == Keys.Escape)
        {
            Close();
        }
    }
}
0 голосов
/ 30 декабря 2010

Можете ли вы проверить, какой элемент управления имеет фокус в первую очередь?Если в вашей форме есть только один элемент управления, который имеет отношение к клавише escape, проверьте, находится ли этот элемент управления в фокусе, прежде чем закрывать форму.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...