Skip to content

Commit c783d4c

Browse files
Add Clear and selected text access functions. (#3312)
* Add Clear and selected text access functions. Tidy the sample page * Update Microsoft.Toolkit.Uwp.SampleApp/SamplePages/TokenizingTextBox/TokenizingTextBoxCode.bind * fix cr comment to allow a cancelled 'remove'request. add a UT to check for it * Fix issue with Clear not resetting the filter correctly * fix release build checks * address PR comments * PR Comment fix Co-authored-by: Michael Hawker MSFT (XAML Llama) <[email protected]>
1 parent 6b10e46 commit c783d4c

File tree

8 files changed

+241
-80
lines changed

8 files changed

+241
-80
lines changed

Microsoft.Toolkit.Uwp.SampleApp/SamplePages/TokenizingTextBox/TokenizingTextBoxCode.bind

Lines changed: 85 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,22 @@ private void TextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventAr
1515
private void TokenItemCreating(object sender, TokenItemAddingEventArgs e)
1616
{
1717
// Take the user's text and convert it to our data type (if we have a matching one).
18-
e.Item = this._samples.FirstOrDefault((item) => item.Text.Contains(e.TokenText, System.StringComparison.CurrentCultureIgnoreCase)) ??
19-
// Otherwise, create a new version of our data type
20-
new SampleDataType()
21-
{
22-
Text = e.TokenText,
23-
Icon = Symbol.OutlineStar
24-
};
18+
e.Item = _samples.FirstOrDefault((item) => item.Text.Contains(e.TokenText, System.StringComparison.CurrentCultureIgnoreCase));
19+
20+
// Otherwise, create a new version of our data type
21+
if (e.Item == null)
22+
{
23+
e.Item = new SampleDataType()
24+
{
25+
Text = e.TokenText,
26+
Icon = Symbol.OutlineStar
27+
};
28+
}
2529
}
2630

2731
private void TokenItemAdded(TokenizingTextBox sender, object data)
2832
{
33+
// TODO: Add InApp Notification?
2934
if (data is SampleDataType sample)
3035
{
3136
Debug.WriteLine("Added Token: " + sample.Text);
@@ -103,16 +108,83 @@ private void EmailTokenItemRemoved(TokenizingTextBox sender, object args)
103108

104109
private void EmailList_ItemClick(object sender, ItemClickEventArgs e)
105110
{
106-
if (e.ClickedItem != null)
111+
if (e.ClickedItem != null && e.ClickedItem is SampleEmailDataType email)
107112
{
108-
_ttbEmail.Items.Add(e.ClickedItem);
109-
_ttbEmail.Text = string.Empty;
113+
_ttbEmail.Text = string.Empty; // Clear current text
114+
115+
_ttbEmail.AddTokenItem(email); // Insert new token with picked item to current text location
116+
110117
_acvEmail.RefreshFilter();
118+
119+
_ttbEmail.Focus(FocusState.Programmatic); // Give focus back to type another filter
111120
}
112121
}
113122

114-
private void ClearButtonClick(object sender, RoutedEventArgs e)
123+
private async void ClearButtonClick(object sender, RoutedEventArgs e)
115124
{
116-
_ttbEmail.Items.Clear();
125+
await _ttbEmail.Clear();
117126
_acvEmail.RefreshFilter();
118-
}
127+
128+
await _ttb.Clear();
129+
}
130+
131+
private async void ShowEmailSelectedClick(object sender, RoutedEventArgs e)
132+
{
133+
// Grab the list of items and identify which ones are free text, which ones are tokens
134+
string message = string.Empty;
135+
136+
foreach (var item in _ttbEmail.Items)
137+
{
138+
if (!string.IsNullOrEmpty(message))
139+
{
140+
message += "\r\n";
141+
}
142+
143+
message += item is ITokenStringContainer ? "Unrslvd: " : "Token : ";
144+
var textVal = item.ToString();
145+
146+
message += string.IsNullOrEmpty(textVal) ? "<empty>" : textVal;
147+
}
148+
149+
MessageDialog md = new MessageDialog(message, "Item List with type");
150+
await md.ShowAsync();
151+
}
152+
153+
private async void ShowSelectedTextClick(object sender, RoutedEventArgs e)
154+
{
155+
// Grab the list of items and identify which ones are free text, which ones are tokens
156+
string message = _ttbEmail.SelectedTokenText;
157+
158+
if (_ttbEmail.SelectedItems.Count == 0)
159+
{
160+
message = "<Nothing Selected>";
161+
}
162+
163+
MessageDialog md = new MessageDialog(message, "Selected Tokens as Text");
164+
await md.ShowAsync();
165+
}
166+
167+
// Move to Email Suggest ListView list when we keydown from the TTB
168+
private void EmailPreviewKeyDown(object sender, KeyRoutedEventArgs e)
169+
{
170+
if (e.Key == Windows.System.VirtualKey.Down && _ttbEmailSuggestions != null)
171+
{
172+
e.Handled = true;
173+
174+
_ttbEmailSuggestions.SelectedIndex = 0;
175+
176+
_ttbEmailSuggestions.Focus(FocusState.Programmatic);
177+
}
178+
}
179+
180+
private void EmailList_PreviewKeyDown(object sender, KeyRoutedEventArgs e)
181+
{
182+
if (e.Key == Windows.System.VirtualKey.Up &&
183+
_ttbEmailSuggestions != null && _ttbEmail != null &&
184+
_ttbEmailSuggestions.SelectedIndex == 0)
185+
{
186+
e.Handled = true;
187+
188+
_ttbEmail.Focus(FocusState.Programmatic); // Give focus back to type another filter
189+
}
190+
}

Microsoft.Toolkit.Uwp.SampleApp/SamplePages/TokenizingTextBox/TokenizingTextBoxPage.xaml.cs

Lines changed: 24 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,6 @@ public sealed partial class TokenizingTextBoxPage : Page, IXamlRenderListener
8282
private TokenizingTextBox _ttb;
8383
private TokenizingTextBox _ttbEmail;
8484
private ListView _ttbEmailSuggestions;
85-
private Button _ttbEmailClear;
86-
private Button _ttbEmailShowItems;
8785

8886
private AdvancedCollectionView _acv;
8987
private AdvancedCollectionView _acvEmail;
@@ -101,6 +99,11 @@ public TokenizingTextBoxPage()
10199
_acvEmail.SortDescriptions.Add(new SortDescription(nameof(SampleEmailDataType.DisplayName), SortDirection.Ascending));
102100

103101
Loaded += (sender, e) => { this.OnXamlRendered(this); };
102+
103+
// Add the buttons
104+
SampleController.Current.RegisterNewCommand("Clear Tokens", ClearButtonClick);
105+
SampleController.Current.RegisterNewCommand("Show Email Items", ShowEmailSelectedClick);
106+
SampleController.Current.RegisterNewCommand("Show Email Selection", ShowSelectedTextClick);
104107
}
105108

106109
public void OnXamlRendered(FrameworkElement control)
@@ -169,28 +172,6 @@ public void OnXamlRendered(FrameworkElement control)
169172

170173
_ttbEmailSuggestions.ItemsSource = _acvEmail;
171174
}
172-
173-
if (_ttbEmailClear != null)
174-
{
175-
_ttbEmailClear.Click -= ClearButtonClick;
176-
}
177-
178-
if (control.FindChildByName("ClearButton") is Button btn)
179-
{
180-
_ttbEmailClear = btn;
181-
_ttbEmailClear.Click += ClearButtonClick;
182-
}
183-
184-
if (_ttbEmailShowItems != null)
185-
{
186-
_ttbEmailShowItems.Click -= ShowButtonClick;
187-
}
188-
189-
if (control.FindChildByName("ShowSelectedEmails") is Button showBtn)
190-
{
191-
_ttbEmailShowItems = showBtn;
192-
_ttbEmailShowItems.Click += ShowButtonClick;
193-
}
194175
}
195176

196177
private async void EmailTokenItemClick(object sender, ItemClickEventArgs e)
@@ -316,14 +297,15 @@ private void EmailList_ItemClick(object sender, ItemClickEventArgs e)
316297
}
317298
}
318299

319-
private void ClearButtonClick(object sender, RoutedEventArgs e)
300+
private async void ClearButtonClick(object sender, RoutedEventArgs e)
320301
{
321-
_selectedEmails.Clear();
322-
302+
await _ttbEmail.ClearAsync();
323303
_acvEmail.RefreshFilter();
304+
305+
await _ttb.ClearAsync();
324306
}
325307

326-
private async void ShowButtonClick(object sender, RoutedEventArgs e)
308+
private async void ShowEmailSelectedClick(object sender, RoutedEventArgs e)
327309
{
328310
// Grab the list of items and identify which ones are free text, which ones are tokens
329311
string message = string.Empty;
@@ -345,6 +327,20 @@ private async void ShowButtonClick(object sender, RoutedEventArgs e)
345327
await md.ShowAsync();
346328
}
347329

330+
private async void ShowSelectedTextClick(object sender, RoutedEventArgs e)
331+
{
332+
// Grab the list of items and identify which ones are free text, which ones are tokens
333+
string message = _ttbEmail.SelectedTokenText;
334+
335+
if (_ttbEmail.SelectedItems.Count == 0)
336+
{
337+
message = "<Nothing Selected>";
338+
}
339+
340+
MessageDialog md = new MessageDialog(message, "Selected Tokens as Text");
341+
await md.ShowAsync();
342+
}
343+
348344
// Move to Email Suggest ListView list when we keydown from the TTB
349345
private void EmailPreviewKeyDown(object sender, KeyRoutedEventArgs e)
350346
{

Microsoft.Toolkit.Uwp.SampleApp/SamplePages/TokenizingTextBox/TokenizingTextBoxXaml.bind

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,6 @@
7878
</ListView.ItemTemplate>
7979
</ListView>
8080
</Border>
81-
82-
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
83-
<Button x:Name="ClearButton" Content="Clear All Tokens"/>
84-
<Button x:Name="ShowSelectedEmails" Content="Show Selected Emails" Margin="10,0,0,0"/>
85-
</StackPanel>
8681
</StackPanel>
8782
</Grid>
8883
</Page>

Microsoft.Toolkit.Uwp.UI.Controls/TokenizingTextBox/TokenizingTextBox.Properties.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,5 +292,16 @@ public bool TabNavigateBackOnArrow
292292
get => (bool)GetValue(TabNavigateBackOnArrowProperty);
293293
set => SetValue(TabNavigateBackOnArrowProperty, value);
294294
}
295+
296+
/// <summary>
297+
/// Gets the complete text value of any selection in the control. The result is the same text as would be copied to the clipboard.
298+
/// </summary>
299+
public string SelectedTokenText
300+
{
301+
get
302+
{
303+
return PrepareSelectionForClipboard();
304+
}
305+
}
295306
}
296307
}

Microsoft.Toolkit.Uwp.UI.Controls/TokenizingTextBox/TokenizingTextBox.Selection.cs

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ private async void TokenizingTextBoxItem_ClearAllAction(TokenizingTextBoxItem se
236236

237237
private async void TokenizingTextBoxItem_ClearClicked(TokenizingTextBoxItem sender, RoutedEventArgs args)
238238
{
239-
await RemoveToken(sender);
239+
await RemoveTokenAsync(sender);
240240
}
241241

242242
/// <summary>
@@ -275,7 +275,7 @@ internal async Task RemoveAllSelectedTokens()
275275
if (tempStr.Length == 0)
276276
{
277277
// Need to be careful not to remove the last item in the list
278-
await RemoveToken(container);
278+
await RemoveTokenAsync(container);
279279
}
280280
else
281281
{
@@ -285,7 +285,7 @@ internal async Task RemoveAllSelectedTokens()
285285
else
286286
{
287287
// if the item is a token just remove it.
288-
await RemoveToken(container);
288+
await RemoveTokenAsync(container);
289289
}
290290
}
291291
}
@@ -296,6 +296,17 @@ private void CopySelectedToClipboard()
296296
DataPackage dataPackage = new DataPackage();
297297
dataPackage.RequestedOperation = DataPackageOperation.Copy;
298298

299+
var tokenString = PrepareSelectionForClipboard();
300+
301+
if (!string.IsNullOrEmpty(tokenString))
302+
{
303+
dataPackage.SetText(tokenString);
304+
Clipboard.SetContent(dataPackage);
305+
}
306+
}
307+
308+
private string PrepareSelectionForClipboard()
309+
{
299310
string tokenString = string.Empty;
300311
bool addSeparator = false;
301312

@@ -325,11 +336,7 @@ private void CopySelectedToClipboard()
325336
}
326337
}
327338

328-
if (!string.IsNullOrEmpty(tokenString))
329-
{
330-
dataPackage.SetText(tokenString);
331-
Clipboard.SetContent(dataPackage);
332-
}
339+
return tokenString;
333340
}
334341
}
335342
}

0 commit comments

Comments
 (0)