New method to add token to RichSuggestBox
Describe the bug
As mentioned on Discord, I would really love a new method on RichSuggestBox that allows the programmatic insertion of a new token.
The use-case for this is something like a toolbar that offers ways to insert tokens. Currently you need to type the prefix, and then use the provided suggestions.
I think it is quite a common case that you want to offer suggestions outside of the provided popup. In the sample people get suggested to at-mention when the user types @. But imagine if I want to have a custom menu that enables the user to at-mention the last couple of people they interacted with. This new method would make that quite easy to implement.
Steps to reproduce
Currently I create the token in a manual way that relies a bit too much on the inner workings of RichSuggestBox:
private void AddToken(string displayText, object? tokenData)
{
var guid = Guid.NewGuid();
if (mySuggestBox.TextDocument is not null)
{
mySuggestBox.AddTokens([new(guid, $"({displayText})") { Item = tokenData }]);
mySuggestBox.TextDocument.Selection.SetText(Microsoft.UI.Text.TextSetOptions.Unhide, $"\u200B({displayText})\u200B");
mySuggestBox.TextDocument.Selection.Link = $"\"{guid}\"";
// I move the focus, but probably not needed in the toolkit:
mySuggestBox.Focus(FocusState.Programmatic);
mySuggestBox.TextDocument.Selection.MoveStart(Microsoft.UI.Text.TextRangeUnit.Story, 1);
// note: the new Token is not available in `Tokens` here yet, some processing occurs.
// It seems like the private method `ValidateTokensInDocument()` should be called here.
}
}
Expected behavior
The new method should add a token, allow me to set the displayed text and the associated data. The token should be inserted at the current text selection/position (In my experience the current position is at the end of the document if the user hasn't interacted with the content)
Screenshots
See the discord for a video of my current use-case
Code Platform
- [ ] UWP
- [x] WinAppSDK / WinUI 3
- [ ] Web Assembly (WASM)
- [ ] Android
- [ ] iOS
- [ ] MacOS
- [ ] Linux / GTK
Windows Build Number
- [ ] Windows 10 1809 (Build 17763)
- [ ] Windows 10 1903 (Build 18362)
- [ ] Windows 10 1909 (Build 18363)
- [ ] Windows 10 2004 (Build 19041)
- [ ] Windows 10 20H2 (Build 19042)
- [ ] Windows 10 21H1 (Build 19043)
- [ ] Windows 10 21H2 (Build 19044)
- [ ] Windows 10 22H2 (Build 19045)
- [x] Windows 11 21H2 (Build 22000)
- [ ] Other (specify)
Other Windows Build number
No response
App minimum and target SDK version
- [ ] Windows 10, version 1809 (Build 17763)
- [ ] Windows 10, version 1903 (Build 18362)
- [ ] Windows 10, version 1909 (Build 18363)
- [ ] Windows 10, version 2004 (Build 19041)
- [x] Windows 10, version 2104 (Build 20348)
- [x] Windows 11, version 22H2 (Build 22000)
- [ ] Other (specify)
Other SDK version
No response
Visual Studio Version
2022
Visual Studio Build Number
latest (17.14.9)
Device form factor
Desktop
Additional context
I find the tokenized richtextbox a very cool and powerful control, the use-case in the samples centered on suggestions are just the tip of the ice berg. I did not really look into this yet, but I believe a token must currently start with a punctuation character. But wouldn't it be neat if you could use an emoji? Imagine a paperclip with a document name to reference an attachment. 📎MyReport.pdf
Help us help you
No, I'm unable to contribute a solution.
The signature for this should be like:
public void InsertToken(ITextRange range, RichSuggestToken token)
It should do similar steps to the committing of a suggestion here:
https://github.com/CommunityToolkit/Windows/blob/5bc705f2f563549914327a04a61c4322b8fc7fef/components/RichSuggestBox/src/RichSuggestBox.Suggestion.cs#L77-L136
Not sure if that'd mean it'd have to be async, not as familiar with the inner workings here myself.
SelectionChanging has the location information of the selection as well, though not SelectionChanged (which is exposed by the control), seems like a platform issue to investigate too.
https://learn.microsoft.com/en-us/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.controls.richeditboxselectionchangingeventargs?view=windows-app-sdk-1.7
Yeah, looks like SelectionChanged is defined: https://github.com/microsoft/microsoft-ui-xaml/blob/adae19431771d29b4c94d7a2bfd889e7d8c0fa4c/src/dxaml/xcp/tools/XCPTypesAutoGen/Modules/Controls/RichEditBox.cs#L290 - but I never see it raised searching in the https://github.com/microsoft/microsoft-ui-xaml/blob/adae19431771d29b4c94d7a2bfd889e7d8c0fa4c/src/dxaml/xcp/dxaml/lib/RichEditBox_Partial.cpp implementation.
Someone would need to do a quick repro and raise an issue, but seems like an oversight to not have the same information passed after selection made?
However folks can just grab an ITextRange from the selection of the document itself: https://learn.microsoft.com/en-us/windows/windows-app-sdk/api/winrt/microsoft.ui.text.richedittextdocument.selection?view=windows-app-sdk-1.7 (which is either whatever the user has highlighted, or should be the cursor position if no selection from my understanding)