CommunityToolkit / CommunityToolkit/Windows

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

Open
#529 0 comments 1 reaction 0 assignees View on GitHub
components::controls::tokenizingtextbox feature request :mailbox_with_mail:
Dominant language
C#
Stars
1.1k
Forks
166
PR merge metrics
No merged PRs in 30d

Description

### Describe the problem

Currently, [`TokenizingTextBox`](https://github.com/CommunityToolkit/Windows/blob/main/components/TokenizingTextBox/src/TokenizingTextBox.cs) does not fire [`TokenItemAdding`](https://github.com/CommunityToolkit/Windows/blob/5fd59df3d2e65cc2d38e62386b73a692105e2f30/components/TokenizingTextBox/src/TokenizingTextBox.Events.cs#L30) event when the `data` parameter in [`AddTokenAsync(object data)`](https://github.com/CommunityToolkit/Windows/blob/5fd59df3d2e65cc2d38e62386b73a692105e2f30/components/TokenizingTextBox/src/TokenizingTextBox.cs#L494) 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)`](https://github.com/CommunityToolkit/Windows/blob/5fd59df3d2e65cc2d38e62386b73a692105e2f30/components/TokenizingTextBox/src/TokenizingTextBox.cs#L494)
```
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`](https://github.com/CommunityToolkit/Windows/blob/5fd59df3d2e65cc2d38e62386b73a692105e2f30/components/TokenizingTextBox/src/TokenizingTextBox.Events.cs)

```
public event TypedEventHandler TokenizingTextBoxQuerySubmitted;
```

3. Modify [`RaiseQuerySubmitted`](https://github.com/kaismic/Windows/blob/ee32a0a854f108afaabb9bbc07b58f665ef95161/components/TokenizingTextBox/src/TokenizingTextBox.cs#L243C1-L246C6)

```
internal void RaiseQuerySubmitted(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs
args, TokenizingTextBoxQuerySubmittedEventArgs args)
{
TokenizingTextBoxQuerySubmitted?.Invoke(sender, ttbArgs);
QuerySubmitted?.Invoke(sender, args);
}
```

4. Modify [`AutoSuggestBox_QuerySubmitted`](https://github.com/kaismic/Windows/blob/5fd59df3d2e65cc2d38e62386b73a692105e2f30/components/TokenizingTextBox/src/TokenizingTextBoxItem.AutoSuggestBox.cs#L138)
```
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

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.