Skip to content

Commit 6666ff3

Browse files
Merge pull request #51 from windows-toolkit/michael-hawker/update-tokenizing
Draft - Update TokenizingTextBox usage for PeoplePicker
2 parents a96dd84 + a8670cc commit 6666ff3

27 files changed

+154
-206
lines changed

Directory.Build.props

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@
5353
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
5454
</PropertyGroup>
5555
<ItemGroup>
56-
<PackageReference Include="Microsoft.SourceLink.Vsts.Git" Version="1.0.0-beta-62925-02" PrivateAssets="All"/>
57-
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0-beta-62925-02" PrivateAssets="All"/>
56+
<PackageReference Include="Microsoft.SourceLink.AzureRepos.Git" Version="1.0.0" PrivateAssets="All"/>
57+
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All"/>
5858
</ItemGroup>
5959
</When>
6060
</Choose>
@@ -63,7 +63,7 @@
6363
<When Condition="'$(IsTestProject)' != 'true' and '$(IsSampleProject)' != 'true' and '$(IsDesignProject)' != 'true' and '$(IsWpfProject)' != 'true'">
6464
<ItemGroup>
6565
<!--<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="15.3.83" PrivateAssets="all" />-->
66-
<PackageReference Include="StyleCop.Analyzers" Version="1.0.2" PrivateAssets="all" />
66+
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="all" />
6767

6868
<EmbeddedResource Include="**\*.rd.xml" />
6969
<Page Include="**\*.xaml" Exclude="**\bin\**\*.xaml;**\obj\**\*.xaml" SubType="Designer" Generator="MSBuild:Compile" />
@@ -83,7 +83,7 @@
8383
</PropertyGroup>
8484

8585
<ItemGroup>
86-
<PackageReference Include="Nerdbank.GitVersioning" Version=" 2.1.65" PrivateAssets="all" />
86+
<PackageReference Include="Nerdbank.GitVersioning" Version="3.1.91" PrivateAssets="all" />
8787
</ItemGroup>
8888

8989
<ItemGroup>

Microsoft.Toolkit.Graph.Controls/Controls/PeoplePicker/PeoplePicker.Properties.cs

Lines changed: 0 additions & 53 deletions
This file was deleted.

Microsoft.Toolkit.Graph.Controls/Controls/PeoplePicker/PeoplePicker.cs

Lines changed: 40 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
// See the LICENSE file in the project root for more information.
44

55
using System;
6+
using System.Collections;
7+
using System.Collections.ObjectModel;
68
using System.Linq;
79
using Microsoft.Graph;
810
using Microsoft.Toolkit.Graph.Extensions;
@@ -17,13 +19,8 @@ namespace Microsoft.Toolkit.Graph.Controls
1719
/// <summary>
1820
/// Control which allows user to search for a person or contact within Microsoft Graph. Built on top of <see cref="TokenizingTextBox"/>.
1921
/// </summary>
20-
[TemplatePart(Name = PeoplePickerTokenizingTextBoxName, Type = typeof(TokenizingTextBox))]
21-
public partial class PeoplePicker : Control
22+
public partial class PeoplePicker : TokenizingTextBox
2223
{
23-
private const string PeoplePickerTokenizingTextBoxName = "PART_TokenizingTextBox";
24-
25-
private TokenizingTextBox _tokenBox;
26-
2724
private DispatcherTimer _typeTimer = new DispatcherTimer();
2825

2926
/// <summary>
@@ -32,33 +29,14 @@ public partial class PeoplePicker : Control
3229
public PeoplePicker()
3330
{
3431
this.DefaultStyleKey = typeof(PeoplePicker);
35-
}
36-
37-
/// <inheritdoc/>
38-
protected override void OnApplyTemplate()
39-
{
40-
base.OnApplyTemplate();
41-
42-
if (_tokenBox != null)
43-
{
44-
_tokenBox.TextChanged -= TokenBox_TextChanged;
45-
_tokenBox.TokenItemAdded -= TokenBox_TokenItemAdded;
46-
_tokenBox.TokenItemCreating -= TokenBox_TokenItemCreating;
47-
_tokenBox.TokenItemRemoved -= TokenBox_TokenItemRemoved;
48-
}
4932

50-
_tokenBox = GetTemplateChild(PeoplePickerTokenizingTextBoxName) as TokenizingTextBox;
33+
SuggestedItemsSource = new ObservableCollection<Person>();
5134

52-
if (_tokenBox != null)
53-
{
54-
_tokenBox.TextChanged += TokenBox_TextChanged;
55-
_tokenBox.TokenItemAdded += TokenBox_TokenItemAdded;
56-
_tokenBox.TokenItemCreating += TokenBox_TokenItemCreating;
57-
_tokenBox.TokenItemRemoved += TokenBox_TokenItemRemoved;
58-
}
35+
TextChanged += TokenBox_TextChanged;
36+
TokenItemAdding += TokenBox_TokenItemTokenItemAdding;
5937
}
6038

61-
private async void TokenBox_TokenItemCreating(TokenizingTextBox sender, TokenItemCreatingEventArgs args)
39+
private async void TokenBox_TokenItemTokenItemAdding(TokenizingTextBox sender, TokenItemAddingEventArgs args)
6240
{
6341
using (args.GetDeferral())
6442
{
@@ -79,19 +57,6 @@ private async void TokenBox_TokenItemCreating(TokenizingTextBox sender, TokenIte
7957
}
8058
}
8159

82-
private void TokenBox_TokenItemAdded(TokenizingTextBox sender, TokenizingTextBoxItem args)
83-
{
84-
if (args?.Content is Person person)
85-
{
86-
PickedPeople.Add(person);
87-
}
88-
}
89-
90-
private void TokenBox_TokenItemRemoved(TokenizingTextBox sender, TokenItemRemovedEventArgs args)
91-
{
92-
PickedPeople.Remove(args.Item as Person);
93-
}
94-
9560
private void TokenBox_TextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args)
9661
{
9762
if (!args.CheckCurrent())
@@ -102,33 +67,49 @@ private void TokenBox_TextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChang
10267
if (args.Reason == AutoSuggestionBoxTextChangeReason.UserInput)
10368
{
10469
var text = sender.Text;
105-
_typeTimer.Debounce(
106-
async () =>
70+
var list = SuggestedItemsSource as IList;
71+
72+
if (list != null)
10773
{
108-
var graph = ProviderManager.Instance.GlobalProvider.Graph;
109-
if (graph != null)
74+
_typeTimer.Debounce(
75+
async () =>
11076
{
111-
// If empty, clear out
112-
if (string.IsNullOrWhiteSpace(text))
77+
var graph = ProviderManager.Instance.GlobalProvider.Graph;
78+
if (graph != null)
11379
{
114-
SuggestedPeople.Clear();
115-
}
116-
else
117-
{
118-
SuggestedPeople.Clear();
80+
// If empty, will clear out
81+
list.Clear();
11982

120-
foreach (var contact in (await graph.FindPersonAsync(text)).CurrentPage)
83+
if (!string.IsNullOrWhiteSpace(text))
12184
{
122-
if (!PickedPeople.Any(person => person.Id == contact.Id))
85+
foreach (var user in (await graph.FindUserAsync(text)).CurrentPage)
12386
{
124-
SuggestedPeople.Add(contact);
87+
// Exclude people in suggested list that we already have picked
88+
if (!Items.Any(person => (person as Person)?.Id == user.Id))
89+
{
90+
list.Add(user.ToPerson());
91+
}
92+
}
93+
94+
// Grab ids of current suggestions
95+
var ids = list.Cast<object>().Select(person => (person as Person).Id);
96+
97+
foreach (var contact in (await graph.FindPersonAsync(text)).CurrentPage)
98+
{
99+
// Exclude people in suggested list that we already have picked
100+
// Or already suggested
101+
if (!Items.Any(person => (person as Person)?.Id == contact.Id) &&
102+
!ids.Any(id => id == contact.Id))
103+
{
104+
list.Add(contact);
105+
}
125106
}
126107
}
127108
}
128-
}
129109

130-
// TODO: If we don't have Graph connection and just list of Person should we auto-filter here?
131-
}, TimeSpan.FromSeconds(0.3));
110+
// TODO: If we don't have Graph connection and just list of Person should we auto-filter here?
111+
}, TimeSpan.FromSeconds(0.3));
112+
}
132113
}
133114
}
134115
}

Microsoft.Toolkit.Graph.Controls/Controls/PeoplePicker/PeoplePicker.xaml

Lines changed: 26 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,36 +2,34 @@
22
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
33
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
44
xmlns:local="using:Microsoft.Toolkit.Graph.Controls"
5-
xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls">
5+
xmlns:ex="using:Microsoft.Toolkit.Uwp.UI.Extensions">
6+
<ResourceDictionary.MergedDictionaries>
7+
<ResourceDictionary Source="ms-appx:///Microsoft.Toolkit.Uwp.UI.Controls/TokenizingTextBox/TokenizingTextBox.xaml" />
8+
</ResourceDictionary.MergedDictionaries>
69

7-
<Style TargetType="local:PeoplePicker">
8-
<Setter Property="Template">
10+
<Style TargetType="local:PeoplePicker" BasedOn="{StaticResource DefaultPeoplePickerStyle}"/>
11+
12+
<Style x:Key="DefaultPeoplePickerStyle" TargetType="local:PeoplePicker" BasedOn="{StaticResource DefaultTokenizingTextBoxStyle}">
13+
<Setter Property="QueryIcon">
14+
<Setter.Value>
15+
<SymbolIconSource Symbol="Find"/>
16+
</Setter.Value>
17+
</Setter>
18+
<Setter Property="PlaceholderText" Value="Start typing a name"/>
19+
<Setter Property="TextMemberPath" Value="DisplayName"/>
20+
<Setter Property="TokenDelimiter" Value=","/>
21+
<Setter Property="SuggestedItemTemplate">
22+
<Setter.Value>
23+
<DataTemplate>
24+
<local:PersonView PersonDetails="{Binding}" ShowName="True" ShowEmail="True"/>
25+
</DataTemplate>
26+
</Setter.Value>
27+
</Setter>
28+
<Setter Property="TokenItemTemplate">
929
<Setter.Value>
10-
<ControlTemplate TargetType="local:PeoplePicker">
11-
<Border
12-
Background="{TemplateBinding Background}"
13-
BorderBrush="{TemplateBinding BorderBrush}"
14-
BorderThickness="{TemplateBinding BorderThickness}">
15-
<controls:TokenizingTextBox
16-
x:Name="PART_TokenizingTextBox"
17-
QueryIcon="Find"
18-
PlaceholderText="Start typing a name"
19-
TextMemberPath="DisplayName"
20-
TokenDelimiter=","
21-
SuggestedItemsSource="{TemplateBinding SuggestedPeople}">
22-
<controls:TokenizingTextBox.SuggestedItemTemplate>
23-
<DataTemplate>
24-
<local:PersonView PersonDetails="{Binding}" ShowName="True" ShowEmail="True"/>
25-
</DataTemplate>
26-
</controls:TokenizingTextBox.SuggestedItemTemplate>
27-
<controls:TokenizingTextBox.TokenItemTemplate>
28-
<DataTemplate>
29-
<local:PersonView PersonDetails="{Binding}" ShowName="True"/>
30-
</DataTemplate>
31-
</controls:TokenizingTextBox.TokenItemTemplate>
32-
</controls:TokenizingTextBox>
33-
</Border>
34-
</ControlTemplate>
30+
<DataTemplate>
31+
<local:PersonView PersonDetails="{Binding}" ShowName="True"/>
32+
</DataTemplate>
3533
</Setter.Value>
3634
</Setter>
3735
</Style>

Microsoft.Toolkit.Graph.Controls/Microsoft.Toolkit.Graph.Controls.csproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@
2424
</ItemGroup>
2525

2626
<ItemGroup>
27-
<PackageReference Include="Microsoft.Toolkit.Uwp.UI" Version="6.0.0-rc1.2" />
28-
<PackageReference Include="Microsoft.Toolkit.Uwp.UI.Controls" Version="6.0.0-rc1.2" />
27+
<PackageReference Include="Microsoft.Toolkit.Uwp.UI" Version="6.1.0-build.183" />
28+
<PackageReference Include="Microsoft.Toolkit.Uwp.UI.Controls" Version="6.1.0-build.183" />
2929
<ProjectReference Include="..\Microsoft.Toolkit.Graph\Microsoft.Toolkit.Graph.csproj" />
3030
</ItemGroup>
3131

@@ -34,8 +34,8 @@
3434
</ItemGroup>
3535

3636
<ItemGroup>
37-
<PackageReference Include="Microsoft.Graph.Beta" Version="0.8.0-preview" />
38-
<PackageReference Include="Microsoft.Graph.Auth" Version="1.0.0-preview.2" />
37+
<PackageReference Include="Microsoft.Graph.Beta" Version="0.18.0-preview" />
38+
<PackageReference Include="Microsoft.Graph.Auth" Version="1.0.0-preview.4" />
3939
</ItemGroup>
4040

4141
<ItemGroup>

Microsoft.Toolkit.Graph.Controls/Providers/InteractiveProviderBehavior.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ namespace Microsoft.Toolkit.Graph.Providers
2020
{
2121
/// <summary>
2222
/// Put in a xaml page with ClientId
23-
/// https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/Acquiring-tokens-interactively
23+
/// https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/Acquiring-tokens-interactively.
2424
/// </summary>
2525
/// <example>
2626
/// <code>

Microsoft.Toolkit.Graph.Controls/Providers/MockProviderBehavior.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ namespace Microsoft.Toolkit.Graph.Providers
2020
{
2121
/// <summary>
2222
/// Put in a xaml page with ClientId
23-
/// https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/Acquiring-tokens-interactively
23+
/// https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/Acquiring-tokens-interactively.
2424
/// </summary>
2525
/// <example>
2626
/// <code>

Microsoft.Toolkit.Graph.Controls/Providers/QuickCreate.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public static class QuickCreate
3030
/// ProviderManager.Instance.GlobalProvider = await QuickCreate.CreateMsalProviderAsync("MyClientId");
3131
/// </code>
3232
/// </example>
33-
/// <param name="clientid">Registered ClientId</param>
33+
/// <param name="clientid">Registered ClientId.</param>
3434
/// <param name="redirectUri">RedirectUri for auth response.</param>
3535
/// <param name="scopes">List of Scopes to initially request.</param>
3636
/// <returns>New <see cref="MsalProvider"/> reference.</returns>

Microsoft.Toolkit.Graph.Controls/Providers/ScopeSet.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@
33
// See the LICENSE file in the project root for more information.
44

55
#if DOTNET
6-
using Microsoft.Xaml.Behaviors;
7-
using System.Collections.Generic;
8-
using System.Collections.ObjectModel;
9-
using System.ComponentModel;
10-
using System.Linq;
6+
using Microsoft.Xaml.Behaviors;
7+
using System.Collections.Generic;
8+
using System.Collections.ObjectModel;
9+
using System.ComponentModel;
10+
using System.Linq;
1111
#else
12-
using System.Collections.Generic;
13-
using System.Collections.ObjectModel;
14-
using System.Linq;
12+
using System.Collections.Generic;
13+
using System.Collections.ObjectModel;
14+
using System.Linq;
1515
#endif
1616

1717
#if DOTNET
@@ -39,7 +39,7 @@ public class ScopeSet : Collection<string>
3939
/// Helper to convert a string of scopes to a list of strings.
4040
/// </summary>
4141
/// <param name="rawString">Comma separated scope list.</param>
42-
/// <returns>New List of strings, i.e. ScopeSet</returns>
42+
/// <returns>New List of strings, i.e. ScopeSet.</returns>
4343
public static ScopeSet ConvertToScopeArray(string rawString)
4444
{
4545
if (rawString != null)

0 commit comments

Comments
 (0)