private async Task OnRowMouseDownAsync(MouseEventArgs args, TItem item)
        {
            if (SelectionMode != TableSelectionMode.None)
            {
                var key = KeyField !(item)?.ToString();
                if (key != null)
                {
                    var alreadySelected = Selection.Contains(key);

                    // begin edit mode?
                    if (AllowEdit && !IsEditing && Selection.Count == 1 && alreadySelected && !args.CtrlKey && args.Button == 0)
                    {
                        _editTimer?.Change(500, Timeout.Infinite);
                    }
                    else
                    {
                        if (SelectionMode == TableSelectionMode.Single)
                        {
                            if (!alreadySelected)
                            {
                                Selection.Clear();
                                Selection.Add(key);
                                await SelectionChanged.InvokeAsync(null).ConfigureAwait(true);
                            }
                        }
                        else if (SelectionMode == TableSelectionMode.Multiple)
                        {
                            if (args.ShiftKey && Selection.Count > 0)                             // range selection (from last selected to row clicked on)
                            {
                                Selection.RemoveRange(0, Selection.Count - 1);
                                var idxFrom = ItemsToDisplay.FindIndex(x => KeyField !(x)?.ToString() == Selection[0]);
                                var idxTo   = ItemsToDisplay.FindIndex(x => KeyField !(x)?.ToString() == key);
                                if (idxFrom > -1 && idxTo > -1)
                                {
                                    Selection.Clear();
                                    Selection.AddRange(ItemsToDisplay
                                                       .GetRange(Math.Min(idxFrom, idxTo), (Math.Max(idxFrom, idxTo) - Math.Min(idxFrom, idxTo)) + 1)
                                                       .Select(x => KeyField !(x).ToString()));
                                    await SelectionChanged.InvokeAsync(null).ConfigureAwait(true);
                                }
                            }
                            else if (args.CtrlKey)                             // toggle selection
                            {
                                if (alreadySelected)
                                {
                                    Selection.Remove(key);
                                }
                                else
                                {
                                    Selection.Add(key);
                                }
                                await SelectionChanged.InvokeAsync(null).ConfigureAwait(true);
                            }
                            else if (!alreadySelected)                             // single selection
                            {
                                Selection.Clear();
                                Selection.Add(key);
                                await SelectionChanged.InvokeAsync(null).ConfigureAwait(true);
                            }
                        }
                    }
                }
            }
        }