DVLUP
January 2, 2020

Custom TypingStarted and TypingEnded Events

Posted on January 2, 2020  •  2 minutes  • 300 words

You know that little indicator in a chat that shows if someone is currently typing? I am working on a new post (coming soon, link will be here) that uses SignalR to communicate who is currently typing in a chat room along with the messages themselves.

To determine who is typing, I use a timer and the TextChanged event. The timer logic itself is straightforward, in the TextChanged event starts a timer.

This code is a bit tedious to implement over and over again, so why not just build it into the control itself and invoke a custom TypingStarted and TypingEnded event? Enjoy!

public class TimedEntry : Entry, IDisposable
{
    private readonly System.Timers.Timer timer;

    public TimedChatEntry()
    {
        TextChanged += TimedChatEntry\_TextChanged;

        timer = new System.Timers.Timer(1000);
        timer.Elapsed += timer\_Elapsed;
    }

    public event EventHandler<EventArgs> TypingStarted;

    public event EventHandler<EventArgs> TypingEnded;

    private void timer\_Elapsed(object sender, System.Timers.ElapsedEventArgs args)
    {
        if (timer == null)
            return;

        timer?.Stop();
        Device.BeginInvokeOnMainThread(() => TypingEnded?.Invoke(this, new EventArgs()));
    }

    private void TimedChatEntry\_TextChanged(object sender, TextChangedEventArgs e)
    {
        if (timer == null)
            return;

        if (!timer.Enabled)
        {
            timer?.Start();
            Device.BeginInvokeOnMainThread(() => TypingStarted?.Invoke(this, new EventArgs()));
        }
        else
        {
            timer.Stop();
            timer.Start();
        }
    }

    public void Dispose()
    {
        if (timer != null)
        {
            timer.Elapsed -= timer\_Elapsed;
        }
        timer?.Dispose();
    }
}

Here’s an example that uses a SignalR service:

<TimedEntry TypingStarted="TimedChatEntry\_OnTypingStarted"
            TypingEnded="TimedChatEntry\_OnTypingEnded"/>

private async void TimedChatEntry_OnTypingStarted(object sender, EventArgs e) { if (service != null) await service.SendTyperAsync(me.Name, true); }

private async void TimedChatEntry_OnTypingEnded(object sender, EventArgs e) { if (service != null) await service.SendTyperAsync(me.Name, false); }


You can see the entire thing in action, including the SignalR Hub project, here on GitHub: [SignalR Chat Room Demo](https://github.com/LanceMcCarthy/CustomXamarinDemos/tree/master/SignalRChatDemo).

Follow me on your preferred social network =>