44
55using System ;
66using System . Collections . Generic ;
7+ using System . Collections . ObjectModel ;
78using System . Diagnostics ;
89using System . Linq ;
910using Microsoft . Toolkit . Uwp . UI ;
1213using Windows . UI . Popups ;
1314using Windows . UI . Xaml ;
1415using Windows . UI . Xaml . Controls ;
16+ using Windows . UI . Xaml . Input ;
1517
1618namespace Microsoft . Toolkit . Uwp . SampleApp . SamplePages
1719{
1820 public sealed partial class TokenizingTextBoxPage : Page , IXamlRenderListener
1921 {
22+ //// TODO: We should use images here.
2023 private readonly List < SampleEmailDataType > _emailSamples = new List < SampleEmailDataType > ( )
2124 {
2225 new SampleEmailDataType ( ) { FirstName = "Marcus" , FamilyName = "Perryman" , Icon = Symbol . Account } ,
@@ -46,6 +49,7 @@ public sealed partial class TokenizingTextBoxPage : Page, IXamlRenderListener
4649 new SampleEmailDataType ( ) { FirstName = "Irvin" , FamilyName = "Sayers" , Icon = Symbol . ZoomOut } ,
4750 } ;
4851
52+ // TODO: Setup ACV for this collection as well.
4953 private readonly List < SampleDataType > _samples = new List < SampleDataType > ( )
5054 {
5155 new SampleDataType ( ) { Text = "Account" , Icon = Symbol . Account } ,
@@ -80,8 +84,10 @@ public sealed partial class TokenizingTextBoxPage : Page, IXamlRenderListener
8084 private ListView _ttbEmailSuggestions ;
8185 private Button _ttbEmailClear ;
8286
83- private readonly AdvancedCollectionView _acv ;
84- private readonly AdvancedCollectionView _acvEmail ;
87+ private AdvancedCollectionView _acv ;
88+ private AdvancedCollectionView _acvEmail ;
89+
90+ private ObservableCollection < SampleEmailDataType > _selectedEmails ;
8591
8692 public TokenizingTextBoxPage ( )
8793 {
@@ -98,6 +104,8 @@ public TokenizingTextBoxPage()
98104
99105 public void OnXamlRendered ( FrameworkElement control )
100106 {
107+ _selectedEmails = new ObservableCollection < SampleEmailDataType > ( ) ;
108+
101109 if ( _ttb != null )
102110 {
103111 _ttb . TokenItemAdded -= TokenItemAdded ;
@@ -110,6 +118,8 @@ public void OnXamlRendered(FrameworkElement control)
110118 {
111119 _ttb = ttb ;
112120
121+ ////_ttb.ItemsSource = new ObservableCollection<SampleDataType>(); // TODO: This shouldn't be required, we should initialize in control constructor???
122+
113123 _ttb . TokenItemAdded += TokenItemAdded ;
114124 _ttb . TokenItemRemoving += TokenItemRemoved ;
115125 _ttb . TextChanged += TextChanged ;
@@ -128,31 +138,37 @@ public void OnXamlRendered(FrameworkElement control)
128138 _ttbEmail . TokenItemAdded -= EmailTokenItemAdded ;
129139 _ttbEmail . TokenItemRemoved -= EmailTokenItemRemoved ;
130140 _ttbEmail . TextChanged -= EmailTextChanged ;
141+ _ttbEmail . PreviewKeyDown -= EmailPreviewKeyDown ;
131142 }
132143
133144 if ( control . FindChildByName ( "TokenBoxEmail" ) is TokenizingTextBox ttbEmail )
134145 {
135146 _ttbEmail = ttbEmail ;
136147
137- _ttbEmail . ItemClick += EmailTokenItemClick ;
148+ _ttbEmail . ItemsSource = _selectedEmails ;
149+
150+ // _ttbEmail.ItemClick += EmailTokenItemClick;
138151 _ttbEmail . TokenItemAdding += EmailTokenItemAdding ;
139152 _ttbEmail . TokenItemAdded += EmailTokenItemAdded ;
140153 _ttbEmail . TokenItemRemoved += EmailTokenItemRemoved ;
141154 _ttbEmail . TextChanged += EmailTextChanged ;
155+ _ttbEmail . PreviewKeyDown += EmailPreviewKeyDown ;
142156
143157 _acvEmail . Filter = item => ! _ttbEmail . Items . Contains ( item ) && ( item as SampleEmailDataType ) . DisplayName . Contains ( _ttbEmail . Text , System . StringComparison . CurrentCultureIgnoreCase ) ;
144158 }
145159
146160 if ( _ttbEmailSuggestions != null )
147161 {
148162 _ttbEmailSuggestions . ItemClick -= EmailList_ItemClick ;
163+ _ttbEmailSuggestions . PreviewKeyDown -= EmailList_PreviewKeyDown ;
149164 }
150165
151166 if ( control . FindChildByName ( "EmailList" ) is ListView ttbList )
152167 {
153168 _ttbEmailSuggestions = ttbList ;
154169
155170 _ttbEmailSuggestions . ItemClick += EmailList_ItemClick ;
171+ _ttbEmailSuggestions . PreviewKeyDown += EmailList_PreviewKeyDown ;
156172
157173 _ttbEmailSuggestions . ItemsSource = _acvEmail ;
158174 }
@@ -187,17 +203,22 @@ private void TextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventAr
187203 private void TokenItemCreating ( object sender , TokenItemAddingEventArgs e )
188204 {
189205 // Take the user's text and convert it to our data type (if we have a matching one).
190- e . Item = this . _samples . FirstOrDefault ( ( item ) => item . Text . Contains ( e . TokenText , System . StringComparison . CurrentCultureIgnoreCase ) ) ??
191- // Otherwise, create a new version of our data type
192- new SampleDataType ( )
193- {
194- Text = e . TokenText ,
195- Icon = Symbol . OutlineStar
196- } ;
206+ e . Item = _samples . FirstOrDefault ( ( item ) => item . Text . Contains ( e . TokenText , System . StringComparison . CurrentCultureIgnoreCase ) ) ;
207+
208+ // Otherwise, create a new version of our data type
209+ if ( e . Item == null )
210+ {
211+ e . Item = new SampleDataType ( )
212+ {
213+ Text = e . TokenText ,
214+ Icon = Symbol . OutlineStar
215+ } ;
216+ }
197217 }
198218
199219 private void TokenItemAdded ( TokenizingTextBox sender , object data )
200220 {
221+ // TODO: Add InApp Notification?
201222 if ( data is SampleDataType sample )
202223 {
203224 Debug . WriteLine ( "Added Token: " + sample . Text ) ;
@@ -275,18 +296,49 @@ private void EmailTokenItemRemoved(TokenizingTextBox sender, object args)
275296
276297 private void EmailList_ItemClick ( object sender , ItemClickEventArgs e )
277298 {
278- if ( e . ClickedItem != null )
299+ // TODO: not sure how this is getting to be null, need to make simple repro and file platform issue?
300+ if ( e . ClickedItem != null && e . ClickedItem is SampleEmailDataType email )
279301 {
280- _ttbEmail . Items . Add ( e . ClickedItem ) ;
281- _ttbEmail . Text = string . Empty ;
302+ _ttbEmail . Text = string . Empty ; // Clear current text
303+
304+ _ttbEmail . AddTokenItem ( email ) ; // Insert new token with picked item to current text location
305+
282306 _acvEmail . RefreshFilter ( ) ;
307+
308+ _ttbEmail . Focus ( FocusState . Programmatic ) ; // Give focus back to type another filter
283309 }
284310 }
285311
286312 private void ClearButtonClick ( object sender , RoutedEventArgs e )
287313 {
288- _ttbEmail . Items . Clear ( ) ;
314+ _selectedEmails . Clear ( ) ;
315+
289316 _acvEmail . RefreshFilter ( ) ;
290317 }
318+
319+ // Move to Email Suggest ListView list when we keydown from the TTB
320+ private void EmailPreviewKeyDown ( object sender , KeyRoutedEventArgs e )
321+ {
322+ if ( e . Key == Windows . System . VirtualKey . Down && _ttbEmailSuggestions != null )
323+ {
324+ e . Handled = true ;
325+
326+ _ttbEmailSuggestions . SelectedIndex = 0 ;
327+
328+ _ttbEmailSuggestions . Focus ( FocusState . Programmatic ) ;
329+ }
330+ }
331+
332+ private void EmailList_PreviewKeyDown ( object sender , KeyRoutedEventArgs e )
333+ {
334+ if ( e . Key == Windows . System . VirtualKey . Up &&
335+ _ttbEmailSuggestions != null && _ttbEmail != null &&
336+ _ttbEmailSuggestions . SelectedIndex == 0 )
337+ {
338+ e . Handled = true ;
339+
340+ _ttbEmail . Focus ( FocusState . Programmatic ) ; // Give focus back to type another filter
341+ }
342+ }
291343 }
292344}
0 commit comments