Обработка копии буфера обмена в UserControl - PullRequest
2 голосов
/ 25 мая 2010

У меня сложный UserControl (сетка, элементы управления для редактирования сетки и т. Д.), И я хочу обрабатывать сочетания клавиш CTRL + C, однако я не хочу отключать встроенные функции с помощью элементов управления для редактирования (текстовые поля, выпадающие списки и т. Д.) ..). Если CTRL + C не обрабатывается другими внутренними элементами управления, я хочу обработать его самостоятельно (скопировать целые строки из сетки и т. Д.).

Я попытался переопределить метод WndProc в UserControl и проверить наличие WM_COPY и WM_COPYDATA, но он не работает. Он работает только для конечного целевого элемента управления (например, TextBox).

Ответы [ 3 ]

5 голосов
/ 25 мая 2010

Вы можете сделать это, переопределив ProcessCmdKey (). Проверьте, имеет ли текстовое поле фокус. Например:

    protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
        if (keyData == (Keys.Control | Keys.C)) {
            var box = this.ActiveControl as TextBoxBase;
            if (box == null) {
                // Do your stuff
                MessageBox.Show("Copy!");
                return true;
            }
        }
        return base.ProcessCmdKey(ref msg, keyData);
    }
0 голосов
/ 25 мая 2010

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

Автоматическое распространение событий по иерархии элементов управления встроено в WPF и называется Routed Events . Однако эта функция недоступна в Windows Forms, поэтому вам придется реализовать собственное решение.

Взгляните на этот ТАК вопрос , чтобы получить вдохновение.

Связанные ресурсы:

0 голосов
/ 25 мая 2010

Я не пробовал это, и я думаю, что это тяжело, зависит от всех дочерних элементов управления, которые находятся в вашем UserControl.Но обычно нажатие клавиши дается фактическому контролю, который имеет фокус.Если он не обрабатывает это нажатие клавиши (установка e.Handled = true), он будет пузыриться до своего родителя, а если он не обрабатывает его, он будет идти дальше, пока не достигнет формы и, наконец, лимба.

Так что, если ваши дочерние элементы управления написаны правильно, и они не могут обрабатывать данное нажатие клавиши (например, Control + C ), должно быть легко добавить обработчик в ваш UserControl кKeyDown событие и делайте все, что вам нравится.

Обновление

После прочтения ваших комментариев я все же думаю, что путь, показанный Энрико и мной, должен быть правильным,Поэтому я думаю, что проблема заключается в том, что если один из ваших сторонних элементов управления имеет фокус, он не может обработать ярлык копирования, но он устанавливает e.Handled = true, что приводит к отсутствию дополнительной информации родительских элементов управления о ярлыке.

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

Альтернативно существует другой хакерский способ:
В вашей форме вы можетеустановите KeyPreview в true и перехватите входящий ключ.Теперь вы можете проверить, является ли в ActiveControl что-то, что правильно обрабатывает ярлык (может быть, проверка на Dictionary<Type, bool> или HashSet<Type> lackingControls), и просто выйти из функции или сделать то, что вы хотите, и установитьe.Handled = true самостоятельно.

Обновление 2

Небольшой фрагмент, чтобы проиллюстрировать, что я имел в виду:

this.KeyPreview = true;

HashSet<Type> scrappyControls = new HashSet<Type>();
//ToDo: Add all controls that say it handles Ctrl-C
//      but doesn't it the right way.
scrappyControls.Add(typeof(TextBox));

this.KeyDown += (sender, e) =>
{
    if (e.KeyData == (Keys.Control | Keys.C))
    {
        if (scrappyControls.Contains(this.ActiveControl.GetType()))
        {
            //ToDo: Do copy to clipboard on yourself
            e.Handled = true;
        }
    }
};

Недостаток этой функции в том, что она должна бытьпомещается в вашу форму, а не в самописанный UserControl.Но таким образом вы будете проинформированы, когда TextBox имеет фокус и внутри него нажата Control + C .

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