From c4e31cfeb962b63faa947dadc63a73383869049a Mon Sep 17 00:00:00 2001 From: michael-hawker Date: Thu, 19 Sep 2019 13:52:20 -0400 Subject: [PATCH] Local Test for adding PeoplePicker Needs artifacts from https://github.com/unoplatform/Uno.WindowsCommunityToolkit/pull/59 Don't forget to add ClientID :) --- .../PeoplePicker/PeoplePicker.Properties.cs | 53 ++++++++ .../Controls/PeoplePicker/PeoplePicker.cs | 114 ++++++++++++++++++ .../Controls/PeoplePicker/PeoplePicker.xaml | 37 ++++++ .../Microsoft.Toolkit.Graph.Controls.csproj | 9 +- .../Themes/Generic.xaml | 1 + .../VisualStudioToolsManifest.xml | 1 + .../Microsoft.Toolkit.Graph.csproj | 5 +- .../SampleGraphApp.Droid.csproj | 2 +- .../SampleGraphApp.Shared/MainPage.xaml | 16 ++- .../SampleGraphApp.iOS.csproj | 2 +- 10 files changed, 231 insertions(+), 9 deletions(-) create mode 100644 Microsoft.Toolkit.Graph.Controls/Controls/PeoplePicker/PeoplePicker.Properties.cs create mode 100644 Microsoft.Toolkit.Graph.Controls/Controls/PeoplePicker/PeoplePicker.cs create mode 100644 Microsoft.Toolkit.Graph.Controls/Controls/PeoplePicker/PeoplePicker.xaml diff --git a/Microsoft.Toolkit.Graph.Controls/Controls/PeoplePicker/PeoplePicker.Properties.cs b/Microsoft.Toolkit.Graph.Controls/Controls/PeoplePicker/PeoplePicker.Properties.cs new file mode 100644 index 0000000..1fd4bbe --- /dev/null +++ b/Microsoft.Toolkit.Graph.Controls/Controls/PeoplePicker/PeoplePicker.Properties.cs @@ -0,0 +1,53 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.ObjectModel; +using Microsoft.Graph; +using Microsoft.Toolkit.Uwp.UI.Controls; +using Windows.UI.Xaml; + +namespace Microsoft.Toolkit.Graph.Controls +{ + /// + /// Control which allows user to search for a person or contact within Microsoft Graph. Built on top of . + /// + public partial class PeoplePicker + { + /// + /// Gets the set of objects chosen by the user. + /// + public ObservableCollection PickedPeople + { + get { return (ObservableCollection)GetValue(SelectedPeopleProperty); } + internal set { SetValue(SelectedPeopleProperty, value); } + } + + /// + /// Identifies the dependency property. + /// + /// + /// The identifier for the dependency property. + /// + public static readonly DependencyProperty SelectedPeopleProperty = + DependencyProperty.Register(nameof(PickedPeople), typeof(ObservableCollection), typeof(PeoplePicker), new PropertyMetadata(new ObservableCollection())); + + /// + /// Gets or sets collection of people suggested by the graph from the user's query. + /// + public ObservableCollection SuggestedPeople + { + get { return (ObservableCollection)GetValue(SuggestedPeopleProperty); } + set { SetValue(SuggestedPeopleProperty, value); } + } + + /// + /// Identifies the dependency property. + /// + /// + /// The identifier for the dependency property. + /// + public static readonly DependencyProperty SuggestedPeopleProperty = + DependencyProperty.Register(nameof(SuggestedPeople), typeof(ObservableCollection), typeof(PeoplePicker), new PropertyMetadata(new ObservableCollection())); + } +} diff --git a/Microsoft.Toolkit.Graph.Controls/Controls/PeoplePicker/PeoplePicker.cs b/Microsoft.Toolkit.Graph.Controls/Controls/PeoplePicker/PeoplePicker.cs new file mode 100644 index 0000000..ba528e9 --- /dev/null +++ b/Microsoft.Toolkit.Graph.Controls/Controls/PeoplePicker/PeoplePicker.cs @@ -0,0 +1,114 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Microsoft.Graph; +using Microsoft.Toolkit.Graph.Extensions; +using Microsoft.Toolkit.Graph.Providers; +using Microsoft.Toolkit.Uwp.UI.Controls; +using Microsoft.Toolkit.Uwp.UI.Extensions; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; + +namespace Microsoft.Toolkit.Graph.Controls +{ + /// + /// Control which allows user to search for a person or contact within Microsoft Graph. Built on top of . + /// + [TemplatePart(Name = PeoplePickerTokenizingTextBoxName, Type = typeof(TokenizingTextBox))] + public partial class PeoplePicker : Control + { + private const string PeoplePickerTokenizingTextBoxName = "PART_TokenizingTextBox"; + + private TokenizingTextBox _tokenBox; + + private DispatcherTimer _typeTimer = new DispatcherTimer(); + + /// + /// Initializes a new instance of the class. + /// + public PeoplePicker() + { + this.DefaultStyleKey = typeof(PeoplePicker); + } + + /// + protected override void OnApplyTemplate() + { + base.OnApplyTemplate(); + + if (_tokenBox != null) + { + _tokenBox.QueryTextChanged -= TokenBox_QueryTextChanged; + _tokenBox.TokenItemAdded -= TokenBox_TokenItemAdded; + _tokenBox.TokenItemRemoved -= TokenBox_TokenItemRemoved; + } + + _tokenBox = GetTemplateChild(PeoplePickerTokenizingTextBoxName) as TokenizingTextBox; + + if (_tokenBox != null) + { + _tokenBox.QueryTextChanged += TokenBox_QueryTextChanged; + _tokenBox.TokenItemAdded += TokenBox_TokenItemAdded; + _tokenBox.TokenItemRemoved += TokenBox_TokenItemRemoved; + } + } + + private void TokenBox_TokenItemAdded(TokenizingTextBox sender, TokenizingTextBoxItem args) + { + if (args?.Content is Person person) + { + PickedPeople.Add(person); + } + } + + private void TokenBox_TokenItemRemoved(TokenizingTextBox sender, TokenItemRemovedEventArgs args) + { + PickedPeople.Remove(args.Item as Person); + } + + private string _previousQuery; + + private void TokenBox_QueryTextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args) + { +#if !HAS_UNO + if (!args.CheckCurrent()) + { + return; + } +#endif + + if (args.Reason == AutoSuggestionBoxTextChangeReason.UserInput) + { + var text = sender.Text; + _typeTimer.Debounce( + async () => + { + var graph = ProviderManager.Instance.GlobalProvider.Graph; + if (graph != null) + { + // If empty, clear out + if (string.IsNullOrWhiteSpace(text)) + { + SuggestedPeople.Clear(); + } + else + { + SuggestedPeople.Clear(); + + foreach (var contact in (await graph.FindPersonAsync(text)).CurrentPage) + { + SuggestedPeople.Add(contact); + } + } + + _previousQuery = text; + } + + // TODO: If we don't have Graph connection and just list of Person should we auto-filter here? + }, TimeSpan.FromSeconds(0.3)); + } + } + } +} diff --git a/Microsoft.Toolkit.Graph.Controls/Controls/PeoplePicker/PeoplePicker.xaml b/Microsoft.Toolkit.Graph.Controls/Controls/PeoplePicker/PeoplePicker.xaml new file mode 100644 index 0000000..80f2225 --- /dev/null +++ b/Microsoft.Toolkit.Graph.Controls/Controls/PeoplePicker/PeoplePicker.xaml @@ -0,0 +1,37 @@ + + + + diff --git a/Microsoft.Toolkit.Graph.Controls/Microsoft.Toolkit.Graph.Controls.csproj b/Microsoft.Toolkit.Graph.Controls/Microsoft.Toolkit.Graph.Controls.csproj index d1bad7c..e802084 100644 --- a/Microsoft.Toolkit.Graph.Controls/Microsoft.Toolkit.Graph.Controls.csproj +++ b/Microsoft.Toolkit.Graph.Controls/Microsoft.Toolkit.Graph.Controls.csproj @@ -31,12 +31,15 @@ - - + + + + - + + diff --git a/Microsoft.Toolkit.Graph.Controls/Themes/Generic.xaml b/Microsoft.Toolkit.Graph.Controls/Themes/Generic.xaml index cc156c3..6cf76ca 100644 --- a/Microsoft.Toolkit.Graph.Controls/Themes/Generic.xaml +++ b/Microsoft.Toolkit.Graph.Controls/Themes/Generic.xaml @@ -2,6 +2,7 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> + \ No newline at end of file diff --git a/Microsoft.Toolkit.Graph.Controls/VisualStudioToolsManifest.xml b/Microsoft.Toolkit.Graph.Controls/VisualStudioToolsManifest.xml index 03751c3..71baf39 100644 --- a/Microsoft.Toolkit.Graph.Controls/VisualStudioToolsManifest.xml +++ b/Microsoft.Toolkit.Graph.Controls/VisualStudioToolsManifest.xml @@ -2,6 +2,7 @@ + diff --git a/Microsoft.Toolkit.Graph/Microsoft.Toolkit.Graph.csproj b/Microsoft.Toolkit.Graph/Microsoft.Toolkit.Graph.csproj index 7267057..f916de1 100644 --- a/Microsoft.Toolkit.Graph/Microsoft.Toolkit.Graph.csproj +++ b/Microsoft.Toolkit.Graph/Microsoft.Toolkit.Graph.csproj @@ -2,7 +2,8 @@ $(TargetFrameworksOverride) - Windows Community Toolkit .NET Standard Services + Windows Community Toolkit .NET Standard Graph Services + Uno.Microsoft.Toolkit.Graph This package includes .NET Standard code helpers such as: - GraphExtensions: Helpers for common tasks related to the Microsoft Graph used by the Microsoft.Toolkit.Graph.Controls. @@ -26,6 +27,6 @@ - + diff --git a/SampleGraphApp/SampleGraphApp.Droid/SampleGraphApp.Droid.csproj b/SampleGraphApp/SampleGraphApp.Droid/SampleGraphApp.Droid.csproj index 7e0b2ab..7f30cf7 100644 --- a/SampleGraphApp/SampleGraphApp.Droid/SampleGraphApp.Droid.csproj +++ b/SampleGraphApp/SampleGraphApp.Droid/SampleGraphApp.Droid.csproj @@ -71,7 +71,7 @@ - + diff --git a/SampleGraphApp/SampleGraphApp.Shared/MainPage.xaml b/SampleGraphApp/SampleGraphApp.Shared/MainPage.xaml index 2a50db0..a11083b 100644 --- a/SampleGraphApp/SampleGraphApp.Shared/MainPage.xaml +++ b/SampleGraphApp/SampleGraphApp.Shared/MainPage.xaml @@ -6,10 +6,22 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:wgt="using:Microsoft.Toolkit.Graph.Controls" + xmlns:graph="using:Microsoft.Graph" mc:Ignorable="d"> - - + + + + Picked People: + + + + + + + + diff --git a/SampleGraphApp/SampleGraphApp.iOS/SampleGraphApp.iOS.csproj b/SampleGraphApp/SampleGraphApp.iOS/SampleGraphApp.iOS.csproj index 893a995..07b83de 100644 --- a/SampleGraphApp/SampleGraphApp.iOS/SampleGraphApp.iOS.csproj +++ b/SampleGraphApp/SampleGraphApp.iOS/SampleGraphApp.iOS.csproj @@ -127,7 +127,7 @@ - +