Событие TextBox.Enter () запускает событие Textbox.Leave () вместе с ним в WinForm - PullRequest
0 голосов
/ 02 апреля 2020

Я делаю регистрационную форму, используя WinForms C#. Я сделал 2 частные функции для вызова Enter() и Leave() событий в различных TexBox.Enter() и TexBox.Leave() событиях.

private void EnterBox(TextBox Box, string Text, PictureBox PicBox, Bitmap Pic, Label WarningLabel)
{
    if ((Box.Text == Text) && (Box.TextAlign == HorizontalAlignment.Center))
    {
        Box.Clear();

        if (Box == PassBox)
            Box.UseSystemPasswordChar = true;
        Box.TextAlign = HorizontalAlignment.Left;
    }
    PicBox.BackgroundImage = Pic;
    WarningLabel.ForeColor = Color.FromArgb(34, 36, 49);
    Box.ForeColor = Color.FromArgb(78, 184, 206);
}

private void LeaveBox(TextBox Box, string Text, PictureBox PicBox, Bitmap Pic, Label WarningLabel)
{
    if (Box.Text == "")
    {
        if (Box == PassBox)
            Box.UseSystemPasswordChar = false;

        WarningLabel.ForeColor = Color.Red;
        Box.Text = Text;
        Box.TextAlign = HorizontalAlignment.Center;
        Box.ForeColor = Color.Gray;
    }
    else
    {
        if (!Regex.IsMatch(Box.Text, (string)Box.Tag))
            WarningLabel.ForeColor = Color.Red;
        Box.ForeColor = Color.White;
    }
    PicBox.BackgroundImage = Pic;
    Box.Select(0, 0);                     // Move the Cursor to Start.
}

Кажется, что работает хорошо с другими TextBox, но это не работает в порядке с PassBox.

private void PassBox_Enter(object sender, EventArgs e)
{
    EnterBox(PassBox, "Password", PasswordPic, Properties.Resources.password__2_, PasswordWarningLabel);
}

private void PassBox_Leave(object sender, EventArgs e)
{
    LeaveBox(PassBox, "Password", PasswordPic, Properties.Resources.password, PasswordWarningLabel);
}

Отладка с помощью VS-Studio-2019 показывает Когда я ввожу EnterBox() из PassBox_Enter() после завершения

if ((Box.Text == Text) && (Box.TextAlign == HorizontalAlignment.Center))
    {
        Box.Clear();

        if (Box == PassBox)
            Box.UseSystemPasswordChar = true;
        Box.TextAlign = HorizontalAlignment.Left;
    }

, он вводит PassBox_Leave() и выполнить его, затем снова он входит в PassBox_Enter() и снова выполнить функцию.

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

Ответы [ 2 ]

1 голос
/ 02 апреля 2020

Как сказали @Hans Passant и @ MarkusAnd , изменение UseSystemPasswordChar вызывает событие PassBox_Leave() каждый раз. Я удалил if (Box == PassBox) Box.UseSystemPasswordChar = true; и if (Box == PassBox) Box.UseSystemPasswordChar = false; из LeaveBox() и EnterBox() и обновил PassBox_Enter() и PassBox_Leave() следующим образом

private void PassBox_Enter(object sender, EventArgs e)
{
 if (PassBox.TextAlign == HorizontalAlignment.Center)
    PassBox.UseSystemPasswordChar = true;
 EnterBox(PassBox, "Password", PasswordPic, Properties.Resources.password__2_, PasswordWarningLabel);
}

и

private void PassBox_Leave(object sender, EventArgs e)
{
 if (PassBox.Text == "")
     PassBox.UseSystemPasswordChar = false;
 LeaveBox(PassBox, "Password", PasswordPic, Properties.Resources.password, PasswordWarningLabel);
}

Это будет по-прежнему вызвать PassBox_Leave(), но это будет работать.

1 голос
/ 02 апреля 2020

Я думаю, что проблема в строке

if (Box == PassBox)
            Box.UseSystemPasswordChar = true;

в методе EnterBox. Когда вы звоните Box.UseSystemPasswordChar = true;, вы устанавливаете TextBox в ограниченный режим (как вы можете прочитать в разделе здесь ). Когда TextBox переведен в ограниченный режим, он теряет фокус, и событие PassBox_Leave генерируется. Это причина, по которой отладка ведет себя так, как вы описали.

Если вы хотите убедиться, что событие PassBox_Entered завершено до того, как будет сделан любой вызов PassBox_Leave, вам нужно убедиться, что ни одна строка кода в EnterBox не переключает фокус с TextBox. В настоящее время это делается по линии Box.UseSystemPasswordChar = true; в EnterBox.

Однако это способы обойти эту проблему, например, с помощью логических флагов. Это решение не может быть оптимальным, но должно работать.

Поскольку PassBox_Leave может вызываться либо Box.UseSystemPasswordChar = true; (где вы не хотите, чтобы что-либо в LeaveBox было выполнено), либо когда пользователь покидает TextBox (где вы хотите, чтобы LeaveBox выполнить) вы можете использовать логический флаг в своем классе и установить его на true до выполнения строки Box.UseSystemPasswordChar = true; в EnterBox. Затем в первых строках LeaveBox вы проверяете, является ли логический флаг true и возвращаете ли вы его, следовательно, ничего в LeaveBox не будет выполнено (однако PassBox_Leave все равно будет вызываться, поэтому это может быть оптимальное решение).

Public Class YourClass {
    private bool falseCall; //Add this boolean flag as an attribute to your class

    public YourClass() {
       falseCall = false; //Set the inital value to false in the constructor of your class;
    }

    private void EnterBox(TextBox Box, string Text, PictureBox PicBox, Bitmap Pic, Label WarningLabel)
    {

       if ((Box.Text == Text) && (Box.TextAlign == HorizontalAlignment.Center))
       {
           Box.Clear();

           if (Box == PassBox) {
              falseCall = true; //Set the flag to true before the call to LeaveBox is executed
              Box.UseSystemPasswordChar = true;
           }
           Box.TextAlign = HorizontalAlignment.Left;
       }
    //-------Rest of method-----------
    }


    private void LeaveBox(TextBox Box, string Text, PictureBox PicBox, Bitmap Pic, Label WarningLabel)
    {
        if(falseCall) { 
            falseCall = false; //Reset the boolean flag 
            return; 
        }
        //--------Rest of method-----------
    }
}

Таким образом, в основном программа все равно будет вводить LeaveBox при выполнении Box.UseSystemPasswordChar = true;, но она быстро вернется, поскольку флаг был установлен в true. Когда пользователь покидает TextBox, флаг будет ложным, и LeaveBox будет выполняться, как предполагалось.

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