граница текстового поля c # изменяется при отключении по сравнению с другими отключенными текстовыми полями

#c# #textbox #focus #border

#c# #текстовое поле #фокус #граница

Вопрос:

У меня действительно странная проблема. У меня есть несколько текстовых полей для имени пользователя / паролей и флажок рядом с каждой группой пользователей / пропусков. Когда пользователь нажимает на флажок, и если он его установил, текстовое поле имени пользователя и пароля рядом с ним становится включенным, а фокус устанавливается на текстовое поле имени пользователя. Если пользователь снял флажок, текстовые поля рядом с ним становятся отключенными. Однако граница одного текстового поля остается отличной от других отключенных текстовых полей.

См.:

http://img545.imageshack.us/img545/1944/textbox.png

Я подумал, что это проблема с фокусом, поэтому я изменил код — когда пользователь снимает флажок, он сначала фокусируется на каком-то другом элементе формы, а затем отключает его, но все равно делает то же самое. Есть идеи о том, что может вызвать проблему?

Комментарии:

1. Вы проверили, что свойства всех ваших флажков одинаковы и что у одного из них нет другого стиля или чего-то в этом роде?

2. Возможно, я не очень хорошо объяснил — это происходит со всеми текстовыми полями — на том, которое было сфокусировано до отключения (также все были сделаны с одинаковыми свойствами — единственным исключением являются текстовые поля для передачи, у которых есть символ пароля). Когда я отключаю автофокусировку на текстовом поле пользователя, и пользователь не нажимает, чтобы сфокусироваться / ввести его, флажок не изменяет границу, когда он отключен. Вот почему я подумал, что это проблема фокуса. Но затем я добавил тестовое текстовое поле tbTest и выполнил tbTest. Focus(); а затем отключение 2 текстовых полей, но все равно получил тот же результат.

3. Ах, я понимаю, что вы имеете в виду сейчас, да, я неправильно истолковал это, поскольку один конкретный флажок вызывал проблемы. : (

Ответ №1:

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

Я создал форму с: 4 текстовыми полями с именами txtBox1, txtBox2, txtBox3 и txtBox4, 4 флажками с именами chkBox1, chkBox2, chkBox3 и chkBox4

Установите для свойства Enabled каждого текстового поля значение False (я сделал это во время разработки)

     private void Form1_Load(object sender, EventArgs e) {
        chkBox1.CheckedChanged  = chkBox_CheckedChanged;
        chkBox2.CheckedChanged  = chkBox_CheckedChanged;
        chkBox3.CheckedChanged  = chkBox_CheckedChanged;
        chkBox4.CheckedChanged  = chkBox_CheckedChanged;
    }

    private void chkBox_CheckedChanged(object sender, EventArgs e) {
        var chkBox = ((CheckBox)sender);
        var controlSet = chkBox.Name.Substring(6,1);
        var txtName = "txtBox"   controlSet;

        foreach (var txtBox in Controls.Cast<object>().Where(ctl => ((Control)ctl).Name == txtName).Select(ctl => ((TextBox)ctl))) {
            if (chkBox.Checked) {
                txtBox.Enabled = true;
                txtBox.Focus();
            }
            else {
                //The checkbox stole the focuse when it was clicked, so no need to change.
                txtBox.Enabled = false;
            }
        }
    }
  

Теперь, если вы выполните этот код, вы можете установить флажки, чтобы включить текстовое поле с тем же префиксом имени (1, 2, 3 или 4). Это также устанавливает фокус на текстовое поле. Теперь, если вы отключите текстовое поле с фокусом, оно отображается иначе, чем другие отключенные текстовые поля.

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

Обновить

Итак, я нашел хак, который, похоже, работает. Если вы установите для стиля границы текстового поля значение «Нет» перед отключением, а затем сбросите его после этого, эффект нечетного контура не произойдет.

     var borderStyle = txtBox.BorderStyle;
    txtBox.BorderStyle = BorderStyle.None;
    txtBox.Enabled = false;
    txtBox.BorderStyle = borderStyle;
  

Комментарии:

1. Я думаю, я обнаружил, что если вы поместите MessageBox. Показать («что-то») в строке комментария, после нажатия ok код отключения будет выполнен, и текстовое поле будет таким, каким оно должно быть.

2. Да, я думаю, что это законная ошибка. Как я уже сказал, я пытался обновить / перерисовать элемент управления безрезультатно. Я сомневаюсь, что вы хотите открыть окно сообщения, чтобы исправить отображение элемента управления. Надеюсь, вы что-нибудь придумаете. Я еще немного поиграю с этим сегодня днем.

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

4. Думаю, я что-то понял. Если вы сделаете это. Обновить () для формы после того, как флажок снят, другие текстовые поля обновляются, а границы становятся нормальными, но последнее сфокусированное поле — нет. Это можно решить, запустив таймер или выполнив это с задержкой, но задержка зависит от скорости системы. Есть ли способ узнать, когда текстовое поле было перерисовано, поэтому нет необходимости наследовать класс текстового поля и переопределять метод рисования?

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