Skip to content

Commit 2233ac6

Browse files
Merge pull request #4786 from michael-hawker/llama/tokenizingtextbox-fix4749
Fix Text initialization and updating for TokenizingTextBox
2 parents 5d90149 + cd1afd0 commit 2233ac6

File tree

11 files changed

+376
-82
lines changed

11 files changed

+376
-82
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,10 @@ private static void TextPropertyChanged(DependencyObject d, DependencyPropertyCh
109109
if (d is TokenizingTextBox ttb && ttb._currentTextEdit != null)
110110
{
111111
ttb._currentTextEdit.Text = e.NewValue as string;
112+
113+
// Notify inner container of text change, see issue #4749
114+
var item = ttb.ContainerFromItem(ttb._currentTextEdit) as TokenizingTextBoxItem;
115+
item?.UpdateText(ttb._currentTextEdit.Text);
112116
}
113117
}
114118

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,8 @@ private void ItemsSource_PropertyChanged(DependencyObject sender, DependencyProp
8989
}
9090
}
9191

92-
_currentTextEdit = _lastTextEdit = new PretokenStringContainer(true);
92+
// Add our text box at the end of items and set its default value to our initial text, fix for #4749
93+
_currentTextEdit = _lastTextEdit = new PretokenStringContainer(true) { Text = Text };
9394
_innerItemsSource.Insert(_innerItemsSource.Count, _currentTextEdit);
9495
ItemsSource = _innerItemsSource;
9596
}

Microsoft.Toolkit.Uwp.UI.Controls.Input/TokenizingTextBox/TokenizingTextBoxItem.AutoSuggestBox.cs

Lines changed: 55 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33
// See the LICENSE file in the project root for more information.
44

5+
using System.Collections.Generic;
56
using Windows.Foundation;
67
using Windows.System;
78
using Windows.UI;
@@ -100,29 +101,36 @@ private void OnApplyTemplateAutoSuggestBox(AutoSuggestBox auto)
100101
_autoSuggestBox.LostFocus += AutoSuggestBox_LostFocus;
101102

102103
// Setup a binding to the QueryIcon of the Parent if we're the last box.
103-
if (Content is ITokenStringContainer str && str.IsLast)
104+
if (Content is ITokenStringContainer str)
104105
{
105-
// Workaround for https://github.com/microsoft/microsoft-ui-xaml/issues/2568
106-
if (Owner.QueryIcon is FontIconSource fis &&
107-
fis.ReadLocalValue(FontIconSource.FontSizeProperty) == DependencyProperty.UnsetValue)
108-
{
109-
// This can be expensive, could we optimize?
110-
// Also, this is changing the FontSize on the IconSource (which could be shared?)
111-
fis.FontSize = Owner.TryFindResource("TokenizingTextBoxIconFontSize") as double? ?? 16;
112-
}
106+
// We need to set our initial text in all cases.
107+
_autoSuggestBox.Text = str.Text;
113108

114-
var iconBinding = new Binding()
109+
// We only set/bind some properties on the last textbox to mimic the autosuggestbox look
110+
if (str.IsLast)
115111
{
116-
Source = Owner,
117-
Path = new PropertyPath(nameof(Owner.QueryIcon)),
118-
RelativeSource = new RelativeSource() { Mode = RelativeSourceMode.TemplatedParent }
119-
};
112+
// Workaround for https://github.com/microsoft/microsoft-ui-xaml/issues/2568
113+
if (Owner.QueryIcon is FontIconSource fis &&
114+
fis.ReadLocalValue(FontIconSource.FontSizeProperty) == DependencyProperty.UnsetValue)
115+
{
116+
// This can be expensive, could we optimize?
117+
// Also, this is changing the FontSize on the IconSource (which could be shared?)
118+
fis.FontSize = Owner.TryFindResource("TokenizingTextBoxIconFontSize") as double? ?? 16;
119+
}
120120

121-
var iconSourceElement = new IconSourceElement();
121+
var iconBinding = new Binding()
122+
{
123+
Source = Owner,
124+
Path = new PropertyPath(nameof(Owner.QueryIcon)),
125+
RelativeSource = new RelativeSource() { Mode = RelativeSourceMode.TemplatedParent }
126+
};
127+
128+
var iconSourceElement = new IconSourceElement();
122129

123-
iconSourceElement.SetBinding(IconSourceElement.IconSourceProperty, iconBinding);
130+
iconSourceElement.SetBinding(IconSourceElement.IconSourceProperty, iconBinding);
124131

125-
_autoSuggestBox.QueryIcon = iconSourceElement;
132+
_autoSuggestBox.QueryIcon = iconSourceElement;
133+
}
126134
}
127135
}
128136
}
@@ -156,11 +164,35 @@ private void AutoSuggestBox_SuggestionChosen(AutoSuggestBox sender, AutoSuggestB
156164
Owner.RaiseSuggestionChosen(sender, args);
157165
}
158166

159-
private void AutoSuggestBox_TextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args)
167+
// Called to update text by link:TokenizingTextBox.Properties.cs:TextPropertyChanged
168+
internal void UpdateText(string text)
160169
{
161-
var t = sender.Text.Trim();
170+
if (_autoSuggestBox != null)
171+
{
172+
_autoSuggestBox.Text = text;
173+
}
174+
else
175+
{
176+
void WaitForLoad(object s, RoutedEventArgs eargs)
177+
{
178+
if (_autoSuggestTextBox != null)
179+
{
180+
_autoSuggestTextBox.Text = text;
181+
}
162182

163-
Owner.Text = sender.Text; // Update parent text property
183+
AutoSuggestTextBoxLoaded -= WaitForLoad;
184+
}
185+
186+
AutoSuggestTextBoxLoaded += WaitForLoad;
187+
}
188+
}
189+
190+
private void AutoSuggestBox_TextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args)
191+
{
192+
if (!EqualityComparer<string>.Default.Equals(sender.Text, Owner.Text))
193+
{
194+
Owner.Text = sender.Text; // Update parent text property, if different
195+
}
164196

165197
// Override our programmatic manipulation as we're redirecting input for the user
166198
if (UseCharacterAsUser)
@@ -172,6 +204,8 @@ private void AutoSuggestBox_TextChanged(AutoSuggestBox sender, AutoSuggestBoxTex
172204

173205
Owner.RaiseTextChanged(sender, args);
174206

207+
var t = sender.Text?.Trim() ?? string.Empty;
208+
175209
// Look for Token Delimiters to create new tokens when text changes.
176210
if (!string.IsNullOrEmpty(Owner.TokenDelimiter) && t.Contains(Owner.TokenDelimiter))
177211
{
@@ -195,7 +229,7 @@ private void AutoSuggestBox_TextChanged(AutoSuggestBox sender, AutoSuggestBoxTex
195229
}
196230
else
197231
{
198-
sender.Text = tokens[tokens.Length - 1];
232+
sender.Text = tokens[tokens.Length - 1].Trim();
199233
}
200234
}
201235
}

Microsoft.Toolkit.Uwp.UI.Controls.Input/TokenizingTextBox/TokenizingTextBoxItem.AutoSuggestBox.xaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,6 @@
314314
ItemsSource="{Binding Path=Owner.SuggestedItemsSource, RelativeSource={RelativeSource Mode=TemplatedParent}}"
315315
PlaceholderText="{Binding Path=Owner.PlaceholderText, RelativeSource={RelativeSource Mode=TemplatedParent}}"
316316
Style="{StaticResource SystemAutoSuggestBoxStyle}"
317-
Text="{Binding Text, Mode=TwoWay}"
318317
TextBoxStyle="{StaticResource TokenizingTextBoxTextBoxStyle}"/>
319318
</ControlTemplate>
320319
</Setter.Value>

UITests/UITests.Tests.MSTest/UITests.Tests.MSTest.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
<PackageReference Include="Microsoft.Toolkit" Version="7.1.2" />
1717
<PackageReference Include="MSTest.TestAdapter" Version="2.1.2" />
1818
<PackageReference Include="MSTest.TestFramework" Version="2.1.2" />
19-
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
19+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
2020
<!-- Microsoft.UI.Xaml MSTest Extension -->
2121
<PackageReference Include="MUXTestInfra.MSTest" Version="0.0.4" />
2222
<!-- System packages -->

UnitTests/UnitTests.Notifications.NetCore/UnitTests.Notifications.NetCore.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
<ItemGroup>
1212
<PackageReference Include="MSTest.TestAdapter" Version="2.1.2" />
1313
<PackageReference Include="MSTest.TestFramework" Version="2.1.2" />
14-
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
14+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
1515
</ItemGroup>
1616

1717
<Import Project="..\UnitTests.Notifications.Shared\UnitTests.Notifications.Shared.projitems" Label="Shared" />

UnitTests/UnitTests.Notifications.UWP/UnitTests.Notifications.UWP.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@
122122
<PackageReference Include="MSTest.TestFramework">
123123
<Version>2.1.2</Version>
124124
</PackageReference>
125-
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
125+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
126126
<PackageReference Include="System.ValueTuple">
127127
<Version>4.5.0</Version>
128128
</PackageReference>

0 commit comments

Comments
 (0)