C# 检查用户是否在文本框中写入文本

C# 检查用户是否在文本框中写入文本,c#,winforms,textbox,C#,Winforms,Textbox,我正在用C#编写一个聊天程序,我需要一个函数来检查文本框中的文本是否已更改。它可以通过TextChanged事件完成,但我只需要在开始编写时检查它 private void messageText_TextChanged(object sender, TextChangedEventArgs e) { chatApp.WriteChatLine(userName + "is typping..."); } 此代码会在每次更改文本时写入聊天信息。当用户第一次开始向文本框中写入文本时,如何

我正在用C#编写一个聊天程序,我需要一个函数来检查文本框中的文本是否已更改。它可以通过TextChanged事件完成,但我只需要在开始编写时检查它

private void messageText_TextChanged(object sender, TextChangedEventArgs e)
{
    chatApp.WriteChatLine(userName + "is typping...");
}

此代码会在每次更改文本时写入聊天信息。当用户第一次开始向文本框中写入文本时,如何对其进行限制?如果这是一个愚蠢的问题,我很抱歉,但我无法让它工作。谢谢你的帮助

您可以取消订阅事件处理程序:

private void messageText_TextChanged(object sender, TextChangedEventArgs e)
{
    chatApp.WriteChatLine(userName + "is typping...");
    messageText.TextChanged -= messageText_TextChanged;
}
此事件处理程序将执行一次,然后从处理程序列表中删除。因此,文本的进一步更改不会触发事件(如果没有其他订阅者),或者不会执行此特定处理程序

更新:正如@karim所指出的,您可能需要在消息发送、用户停止键入或用户删除所有内容后自动重置此消息。可以使用计时器组件完成(将其间隔设置为您希望在用户停止键入后显示键入消息的值)

通过创建处理状态更新和计时器启动/停止的属性,可以简化此代码:

private void messageText_TextChanged(object sender, TextChangedEventArgs e)
{
    IsUserTyping = true;
}

private void timer_Tick(object sender, EventArgs e)
{
    IsUserTyping = false;
}

private void buttonSend_Click(object sender, EventArgs e)
{
    // send message
    IsUserTyping = false;
}

private bool IsUserTyping 
{
    get { return timer.Enabled; }
    set {
        if (value)
        {
            if (!IsUserTyping)
                chatApp.WriteChatLine(userName + "is typping...");

            timer.Stop();
            timer.Start();
        }
        else
        {
            timer.Stop();
            chatApp.WriteChatLine("");
        }
    }        
}

您可以使用sentinel变量来检测更改是否已经触发过一次,如下所示:

bool textboxChanged = false;

private void messageText_TextChanged(object sender, TextChangedEventArgs e)
{
    if(!textboxChanged) //if not changed
    {
        chatApp.WriteChatLine(userName + "is typping...");
    }
}

因此,事件仍然会被触发,但在您更改sentinel变量之前,它不会做任何事情。这有一个额外的值,允许您在以后需要时重置sentinel变量,而不必担心重新订阅事件。

最简单的版本是

bool wasUserTyping = false;
private void messageText_KeyUp(object sender, KeyEventArgs e){
     wasUserTyping = true;
}

private void messageText_TextChanged(object sender, TextChangedEventArgs e){
    if(wasUserTyping){
          //Yaaay!! User did type
    }
}

文本长度正好为1个字符时?不需要额外的代码。您是否考虑过在第一次之后删除事件处理程序?例如:
messageText.TextChanged-=messageText\u TextChanged当用户最终发送消息时,当他删除所有插入的文本然后再次开始键入时,他将需要更多的额外代码来再次附加处理程序…几秒钟后,我还将使用计时器重新订阅事件。如果不是,代码将只在键入的第一个字符处有效,而不用于进一步的聊天信息。@AdrianoRepetti发送按钮单击事件处理程序:
messageText.TextChanged+=messageText\u TextChanged
@karim同意,计时器是一个很好的解决方案(Skype使用这种方法)非常感谢!最后,我让它在“简化”变体中工作。这对我理解这些“过程”有很大帮助
bool wasUserTyping = false;
private void messageText_KeyUp(object sender, KeyEventArgs e){
     wasUserTyping = true;
}

private void messageText_TextChanged(object sender, TextChangedEventArgs e){
    if(wasUserTyping){
          //Yaaay!! User did type
    }
}