CommunityToolkit / Windows

Collection of controls for WinUI 2, WinUI 3, and Uno Platform developers. Simplifies and demonstrates common developer tasks building experiences for Windows with .NET.
https://aka.ms/windowstoolkitdocs
Other
590 stars 74 forks source link

[Feature] TokenizingTextBox - Make TokenItemAdding event to be invoked even if the adding object is not a string to allow pre-check and cancellation #529

Open kaismic opened 1 month ago

kaismic commented 1 month ago

Describe the problem

Currently, TokenizingTextBox does not fire TokenItemAdding event when the data parameter in AddTokenAsync(object data) is not a string.

So when the user selects the already added item from SuggestedItemsSource, only QuerySubmitted event is invoked and I cannot prevent the duplicate item adding.

Thus, allowing TokenItemAdding to be invoked even if the data parameter is not a string would allow me to prevent duplicate items adding by checking the adding object and cancelling the event.

Describe the solution

Modify AddTokenAsync(object data)

        if (TokenItemAdding != null)
        {
            TokenItemAddingEventArgs tiaea;
            if (data is string str)
            {
                tiaea = new TokenItemAddingEventArgs(str);
            }
            else
            {
                tiaea = new TokenItemAddingEventArgs(null) { Item = data };
            }
            await TokenItemAdding.InvokeAsync(this, tiaea);
            ...
        }

Alternatives

  1. Create new TokenizingTextBoxQuerySubmittedEventArgs class and either remove sealed from AutoSuggestBoxQuerySubmittedEventArgs and derive from it like this:

    public class TokenizingTextBoxQuerySubmittedEventArgs : AutoSuggestBoxQuerySubmittedEventArgs
    {
        public bool Cancel { get; set; }
    }

    Or just create a similar class with additional Cancel property:

    public class TokenizingTextBoxQuerySubmittedEventArgs
        {
        public object ChosenSuggestion { get; }
        public string QueryText { get; }
        public bool Cancel { get; set; } = false;
    }
  2. Create a new TokenizingTextBoxQuerySubmitted event in TokenizingTextBox.Events.cs

public event TypedEventHandler<AutoSuggestBox, TokenizingTextBoxQuerySubmittedEventArgs> TokenizingTextBoxQuerySubmitted;
  1. Modify RaiseQuerySubmitted
    internal void RaiseQuerySubmitted(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs 
 args, TokenizingTextBoxQuerySubmittedEventArgs args)
    {
        TokenizingTextBoxQuerySubmitted?.Invoke(sender, ttbArgs);
        QuerySubmitted?.Invoke(sender, args);
    }
  1. Modify AutoSuggestBox_QuerySubmitted
    private async void AutoSuggestBox_QuerySubmitted(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs args)
    {
        var ttbArgs = new TokenizingTextBoxQuerySubmittedEventArgs()
        {
            ChosenSuggestion = args.ChosenSuggestion,
            QueryText = args.QueryText
        };
        Owner.RaiseQuerySubmitted(sender, args, ttbArgs);
        if (ttbArgs.Cancel)
        {
            return;
        }
        object? chosenItem = null;
        ....
    }

Additional info

No response

Help us help you

None