Experimental attribute for GraphPresenter and sample updates (#148)

* Added experimental attributes to GraphPresenter and QueryOption

* Moved GraphPresenter samples into separate pages and added another for OneDrive

* Converting converters into simple methods
This commit is contained in:
Shane Weaver 2021-08-31 09:18:17 -07:00 коммит произвёл GitHub
Родитель 1f01026d2a
Коммит 3ca626410a
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
17 изменённых файлов: 725 добавлений и 337 удалений

Просмотреть файл

@ -9,6 +9,7 @@ using System.Text.Json;
using System.Threading;
using Microsoft.Graph;
using Microsoft.Toolkit.Uwp;
using Windows.Foundation.Metadata;
using Windows.System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
@ -18,9 +19,9 @@ namespace CommunityToolkit.Graph.Uwp.Controls
/// <summary>
/// Specialized <see cref="ContentPresenter"/> to fetch and display data from the Microsoft Graph.
/// </summary>
[Experimental]
public class GraphPresenter : ContentPresenter
{
/// <summary>
/// Identifies the <see cref="RequestBuilder"/> dependency property.
/// </summary>

Просмотреть файл

@ -7,6 +7,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Foundation.Metadata;
using Windows.UI.Xaml;
namespace CommunityToolkit.Graph.Uwp.Controls
@ -14,6 +15,7 @@ namespace CommunityToolkit.Graph.Uwp.Controls
/// <summary>
/// XAML Proxy for <see cref="Microsoft.Graph.QueryOption"/>.
/// </summary>
[Experimental]
public sealed class QueryOption
{
/// <inheritdoc cref="Microsoft.Graph.Option.Name"/>

Просмотреть файл

@ -126,8 +126,20 @@
<Compile Include="Samples\GraphPresenterSample.xaml.cs">
<DependentUpon>GraphPresenterSample.xaml</DependentUpon>
</Compile>
<Compile Include="Samples\OneDriveStorageSample.xaml.cs">
<DependentUpon>OneDriveStorageSample.xaml</DependentUpon>
<Compile Include="Samples\GraphPresenter\CalendarViewSample.xaml.cs">
<DependentUpon>CalendarViewSample.xaml</DependentUpon>
</Compile>
<Compile Include="Samples\GraphPresenter\MailMessagesSample.xaml.cs">
<DependentUpon>MailMessagesSample.xaml</DependentUpon>
</Compile>
<Compile Include="Samples\GraphPresenter\OneDriveSample.xaml.cs">
<DependentUpon>OneDriveSample.xaml</DependentUpon>
</Compile>
<Compile Include="Samples\GraphPresenter\PlannerTasksSample.xaml.cs">
<DependentUpon>PlannerTasksSample.xaml</DependentUpon>
</Compile>
<Compile Include="Samples\GraphPresenter\TeamsChannelMessagesSample.xaml.cs">
<DependentUpon>TeamsChannelMessagesSample.xaml</DependentUpon>
</Compile>
<Compile Include="Samples\PeoplePickerSample.xaml.cs">
<DependentUpon>PeoplePickerSample.xaml</DependentUpon>
@ -166,7 +178,23 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Samples\OneDriveStorageSample.xaml">
<Page Include="Samples\GraphPresenter\CalendarViewSample.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Samples\GraphPresenter\MailMessagesSample.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Samples\GraphPresenter\OneDriveSample.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Samples\GraphPresenter\PlannerTasksSample.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Samples\GraphPresenter\TeamsChannelMessagesSample.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
@ -186,6 +214,12 @@
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
<Version>6.2.12</Version>
</PackageReference>
<PackageReference Include="Microsoft.Toolkit.Mvvm">
<Version>7.1.0-preview1</Version>
</PackageReference>
<PackageReference Include="Microsoft.Toolkit.Uwp.UI.Controls">
<Version>7.1.0-preview1</Version>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\CommunityToolkit.Authentication.Msal\CommunityToolkit.Authentication.Msal.csproj">

Просмотреть файл

@ -0,0 +1,72 @@
<Page
x:Class="SampleTest.Samples.GraphPresenter.CalendarViewSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:SampleTest.Samples.GraphPresenter"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="using:CommunityToolkit.Graph.Uwp.Controls"
xmlns:global="using:System.Globalization"
xmlns:graph="using:Microsoft.Graph"
xmlns:samples="using:SampleTest.Samples"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel>
<TextBlock>
The following example shows the `Me.CalendarView` API.
</TextBlock>
<TextBlock Margin="0,8,0,0" FontWeight="Bold">
My Upcoming Calendar Events:
</TextBlock>
</StackPanel>
<controls:GraphPresenter
Grid.Row="1"
IsCollection="True"
OrderBy="start/dateTime"
RequestBuilder="{x:Bind CalendarViewRequestBuilder, Mode=OneWay}"
ResponseType="graph:Event">
<controls:GraphPresenter.QueryOptions>
<!-- Need to create separate Properties as multiple functions not supported in x:Bind see https://github.com/microsoft/microsoft-ui-xaml/issues/2407 -->
<controls:QueryOption Name="startDateTime" Value="{x:Bind Today.ToString('o', global:CultureInfo.InvariantCulture)}" />
<controls:QueryOption Name="endDateTime" Value="{x:Bind ThreeDaysFromNow.ToString('o', global:CultureInfo.InvariantCulture)}" />
</controls:GraphPresenter.QueryOptions>
<controls:GraphPresenter.ContentTemplate>
<DataTemplate>
<!-- Return result is a collection of Event's as we used 'IsCollection', so bind that first. -->
<ScrollViewer HorizontalScrollMode="Disabled" VerticalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="graph:Event">
<StackPanel>
<TextBlock Style="{StaticResource TitleTextBlockStyle}" Text="{Binding Subject}" />
<TextBlock FontWeight="Bold">
<Run Text="{x:Bind samples:GraphPresenterSample.ToLocalTime(Start), Mode=OneWay}" />
<Run>-</Run>
<Run Text="{x:Bind samples:GraphPresenterSample.ToLocalTime(End), Mode=OneWay}" />
</TextBlock>
<TextBlock>
<Run FontFamily="Segoe MDL2 Assets" Text="&#xE707;" />
<Run />
<Run Text="{x:Bind Location.DisplayName, Mode=OneWay}" />
</TextBlock>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Margin" Value="0,8,0,8" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</ScrollViewer>
</DataTemplate>
</controls:GraphPresenter.ContentTemplate>
</controls:GraphPresenter>
</Grid>
</Page>

Просмотреть файл

@ -0,0 +1,59 @@
// 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 CommunityToolkit.Authentication;
using CommunityToolkit.Graph.Extensions;
using Microsoft.Graph;
using Microsoft.Graph.Extensions;
using Windows.UI.Xaml.Controls;
namespace SampleTest.Samples.GraphPresenter
{
public sealed partial class CalendarViewSample : Page
{
// Workaround for https://github.com/microsoft/microsoft-ui-xaml/issues/2407
public DateTime Today => DateTimeOffset.Now.Date.ToUniversalTime();
// Workaround for https://github.com/microsoft/microsoft-ui-xaml/issues/2407
public DateTime ThreeDaysFromNow => Today.AddDays(3);
public IBaseRequestBuilder CalendarViewRequestBuilder { get; set; }
public CalendarViewSample()
{
this.InitializeComponent();
ProviderManager.Instance.ProviderUpdated += OnProviderUpdated;
ProviderManager.Instance.ProviderStateChanged += OnProviderStateChanged;
}
private void OnProviderUpdated(object sender, IProvider provider)
{
if (provider == null)
{
ClearRequestBuilders();
}
}
private void OnProviderStateChanged(object sender, ProviderStateChangedEventArgs e)
{
if (e.NewState == ProviderState.SignedIn)
{
var graphClient = ProviderManager.Instance.GlobalProvider.GetClient();
CalendarViewRequestBuilder = graphClient.Me.CalendarView;
}
else
{
ClearRequestBuilders();
}
}
private void ClearRequestBuilders()
{
CalendarViewRequestBuilder = null;
}
}
}

Просмотреть файл

@ -0,0 +1,63 @@
<Page
x:Class="SampleTest.Samples.GraphPresenter.MailMessagesSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:SampleTest.Samples.GraphPresenter"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="using:CommunityToolkit.Graph.Uwp.Controls"
xmlns:graph="using:Microsoft.Graph"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel>
<TextBlock>
The following example shows the `Me.Messages` API for getting a user's inbox mail messages.
</TextBlock>
<TextBlock Margin="0,8,0,0" FontWeight="Bold">
My Messages:
</TextBlock>
</StackPanel>
<controls:GraphPresenter
Grid.Row="1"
IsCollection="True"
RequestBuilder="{x:Bind MessagesRequestBuilder, Mode=OneWay}"
ResponseType="graph:Message">
<controls:GraphPresenter.ContentTemplate>
<DataTemplate>
<ScrollViewer HorizontalScrollMode="Disabled" VerticalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="graph:Message">
<StackPanel>
<controls:PersonView
Margin="-4"
PersonQuery="{x:Bind Sender.EmailAddress.Address}"
PersonViewType="OneLine" />
<TextBlock
Padding="0"
Style="{StaticResource BaseTextBlockStyle}"
Text="{x:Bind Subject}" />
<TextBlock
Text="{x:Bind local:MailMessagesSample.RemoveWhitespace(BodyPreview)}"
TextWrapping="WrapWholeWords" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Margin" Value="0,8,0,8" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</ScrollViewer>
</DataTemplate>
</controls:GraphPresenter.ContentTemplate>
</controls:GraphPresenter>
</Grid>
</Page>

Просмотреть файл

@ -0,0 +1,57 @@
// 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.Text.RegularExpressions;
using CommunityToolkit.Authentication;
using CommunityToolkit.Graph.Extensions;
using Microsoft.Graph;
using Windows.UI.Xaml.Controls;
namespace SampleTest.Samples.GraphPresenter
{
public sealed partial class MailMessagesSample : Page
{
public IBaseRequestBuilder MessagesRequestBuilder { get; set; }
public MailMessagesSample()
{
this.InitializeComponent();
ProviderManager.Instance.ProviderUpdated += OnProviderUpdated;
ProviderManager.Instance.ProviderStateChanged += OnProviderStateChanged;
}
private void OnProviderUpdated(object sender, IProvider provider)
{
if (provider == null)
{
ClearRequestBuilders();
}
}
private void OnProviderStateChanged(object sender, ProviderStateChangedEventArgs e)
{
if (e.NewState == ProviderState.SignedIn)
{
var graphClient = ProviderManager.Instance.GlobalProvider.GetClient();
MessagesRequestBuilder = graphClient.Me.Messages;
}
else
{
ClearRequestBuilders();
}
}
private void ClearRequestBuilders()
{
MessagesRequestBuilder = null;
}
public static string RemoveWhitespace(string value)
{
// Workaround for https://github.com/microsoft/microsoft-ui-xaml/issues/2654
return Regex.Replace(value, @"\t|\r|\n", " ");
}
}
}

Просмотреть файл

@ -0,0 +1,64 @@
<Page
x:Class="SampleTest.Samples.GraphPresenter.OneDriveSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:SampleTest.Samples.GraphPresenter"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:wgt="using:CommunityToolkit.Graph.Uwp.Controls"
xmlns:providers="using:CommunityToolkit.Authentication"
xmlns:graph="using:Microsoft.Graph"
xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid>
<wgt:GraphPresenter
RequestBuilder="{x:Bind RecentDriveItemsRequestBuilder, Mode=OneWay}"
ResponseType="graph:DriveItem"
IsCollection="True">
<wgt:GraphPresenter.ContentTemplate>
<DataTemplate>
<!-- Return result is a collection of DriveItem's as we used 'IsCollection', so bind that first. -->
<ScrollViewer HorizontalScrollMode="Disabled" VerticalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="graph:DriveItem">
<Grid ColumnSpacing="8" RowSpacing="4" BorderThickness="0 0 0 1" BorderBrush="{ThemeResource SystemAccentColor}">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<controls:ImageEx
Grid.RowSpan="2"
DataContext="{x:Bind local:OneDriveSample.GetThumbnail(RemoteItem)}"
PlaceholderSource="/Assets/FileIcon.png"
Source="{Binding ResultOrDefault.Medium.Url}"
Width="48"
Height="48" />
<TextBlock
Grid.Column="1"
Text="{Binding Name}"/>
<TextBlock
Grid.Column="1"
Grid.Row="1"
Text="{x:Bind local:OneDriveSample.FormatFileSize(Size)}"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<controls:UniformGrid Columns="2" ColumnSpacing="8" RowSpacing="8" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</ScrollViewer>
</DataTemplate>
</wgt:GraphPresenter.ContentTemplate>
</wgt:GraphPresenter>
</Grid>
</Page>

Просмотреть файл

@ -0,0 +1,101 @@
// 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 System.Threading.Tasks;
using CommunityToolkit.Authentication;
using CommunityToolkit.Graph.Extensions;
using Microsoft.Graph;
using Microsoft.Toolkit;
using Microsoft.Toolkit.Mvvm.ComponentModel;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Data;
namespace SampleTest.Samples.GraphPresenter
{
public sealed partial class OneDriveSample : Page
{
public IBaseRequestBuilder RecentDriveItemsRequestBuilder { get; set; }
public OneDriveSample()
{
InitializeComponent();
ProviderManager.Instance.ProviderStateChanged += (s, e) => UpdateRequestBuilder();
UpdateRequestBuilder();
}
private void UpdateRequestBuilder()
{
var provider = ProviderManager.Instance.GlobalProvider;
switch (provider?.State)
{
case ProviderState.SignedIn:
RecentDriveItemsRequestBuilder = provider.GetClient().Me.Drive.Recent();
break;
default:
RecentDriveItemsRequestBuilder = null;
break;
}
}
private static readonly string[] Suffixes = { "B", "KB", "MB", "GB", "TB" };
public static string FormatFileSize(Int64? size)
{
float number = size ?? throw new ArgumentNullException(nameof(size));
var suffixIndex = 0;
string Output() => $"{Math.Round(number)}{Suffixes[suffixIndex]}";
do
{
if (number < 1024f)
{
return Output();
}
number = number / 1024f;
}
while (++suffixIndex < Suffixes.Length - 1);
return Output();
}
public static AsyncResult<ThumbnailSet> GetThumbnail(RemoteItem ri)
{
// drives/${file.remoteItem.parentReference.driveId}/items/${file.remoteItem.id}/thumbnails/0/medium
var provider = ProviderManager.Instance.GlobalProvider;
if (provider?.State == ProviderState.SignedIn)
{
var graph = provider.GetClient();
return new AsyncResult<ThumbnailSet>(graph.Drives[ri.ParentReference.DriveId].Items[ri.Id].Thumbnails["0"].Request().GetAsync());
}
return null;
}
public sealed class AsyncResult<TResult> : ObservableObject
{
private TaskNotifier<TResult> taskNotifier;
public Task<TResult> Task
{
get => taskNotifier;
private set
{
SetPropertyAndNotifyOnCompletion(ref taskNotifier, value, nameof(ResultOrDefault));
}
}
public AsyncResult(Task<TResult> task)
{
Task = task;
}
public TResult ResultOrDefault => this.Task.GetResultOrDefault();
}
}
}

Просмотреть файл

@ -0,0 +1,81 @@
<Page
x:Class="SampleTest.Samples.GraphPresenter.PlannerTasksSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:SampleTest.Samples.GraphPresenter"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="using:CommunityToolkit.Graph.Uwp.Controls"
xmlns:graph="using:Microsoft.Graph"
xmlns:samples="using:SampleTest.Samples"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel>
<TextBlock>The following example shows the `Me.Planner.Tasks` API for getting a user's tasks.</TextBlock>
<TextBlock Margin="0,8,0,0" FontWeight="Bold">
My Tasks:
</TextBlock>
</StackPanel>
<controls:GraphPresenter
Grid.Row="1"
IsCollection="True"
RequestBuilder="{x:Bind PlannerTasksRequestBuilder, Mode=OneWay}"
ResponseType="graph:PlannerTask">
<controls:GraphPresenter.ContentTemplate>
<DataTemplate>
<ScrollViewer HorizontalScrollMode="Disabled" VerticalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="graph:PlannerTask">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<!-- We've disabled the checkbox as we're not going to make the call back to the graph to modify the item. -->
<CheckBox IsChecked="{x:Bind local:PlannerTasksSample.IsTaskCompleted(PercentComplete), Mode=OneWay}" IsEnabled="False" />
<TextBlock Grid.Column="1" Text="{x:Bind Title, Mode=OneWay}" />
<ItemsControl Grid.Row="1" Grid.Column="1" ItemsSource="{x:Bind Assignments, Mode=OneWay}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<!-- We're getting a KVP from the PlannerAssignments type, the Key is the UserId string, we'll use that to look-up our user info. -->
<controls:PersonView Margin="-4" UserId="{Binding Key}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
<TextBlock Grid.Row="2" Grid.Column="2" FontWeight="Bold">
<Run>Due</Run>
<Run Text="{x:Bind samples:GraphPresenterSample.ToLocalTime(DueDateTime), Mode=OneWay}" />
</TextBlock>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Margin" Value="0,8,0,8" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</ScrollViewer>
</DataTemplate>
</controls:GraphPresenter.ContentTemplate>
</controls:GraphPresenter>
</Grid>
</Page>

Просмотреть файл

@ -0,0 +1,56 @@
// 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 CommunityToolkit.Authentication;
using CommunityToolkit.Graph.Extensions;
using Microsoft.Graph;
using Windows.UI.Xaml.Controls;
namespace SampleTest.Samples.GraphPresenter
{
public sealed partial class PlannerTasksSample : Page
{
public IBaseRequestBuilder PlannerTasksRequestBuilder;
public PlannerTasksSample()
{
this.InitializeComponent();
ProviderManager.Instance.ProviderUpdated += OnProviderUpdated;
ProviderManager.Instance.ProviderStateChanged += OnProviderStateChanged;
}
private void OnProviderUpdated(object sender, IProvider provider)
{
if (provider == null)
{
ClearRequestBuilders();
}
}
private void OnProviderStateChanged(object sender, ProviderStateChangedEventArgs e)
{
if (e.NewState == ProviderState.SignedIn)
{
var graphClient = ProviderManager.Instance.GlobalProvider.GetClient();
PlannerTasksRequestBuilder = graphClient.Me.Planner.Tasks;
}
else
{
ClearRequestBuilders();
}
}
private void ClearRequestBuilders()
{
PlannerTasksRequestBuilder = null;
}
public static bool IsTaskCompleted(int? percentCompleted)
{
return percentCompleted == 100;
}
}
}

Просмотреть файл

@ -0,0 +1,64 @@
<Page
x:Class="SampleTest.Samples.GraphPresenter.TeamsChannelMessagesSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:SampleTest.Samples.GraphPresenter"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="using:CommunityToolkit.Graph.Uwp.Controls"
xmlns:graph="using:Microsoft.Graph"
xmlns:toolkit="using:Microsoft.Toolkit"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel>
<TextBlock>
The following example shows the beta `Teams/id/Channels/id/messages` API for getting a list of messages (without replies) from a Channel in Teams.
</TextBlock>
<TextBlock Margin="0,8,0,0" FontWeight="Bold">
My Chat Messages:
</TextBlock>
</StackPanel>
<controls:GraphPresenter
Grid.Row="1"
IsCollection="True"
RequestBuilder="{x:Bind TeamsChannelMessagesRequestBuilder, Mode=OneWay}"
ResponseType="graph:ChatMessage">
<controls:GraphPresenter.ContentTemplate>
<DataTemplate>
<ScrollViewer HorizontalScrollMode="Disabled" VerticalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="graph:ChatMessage">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<controls:PersonView
Margin="-4,-4,8,-4"
UserId="{x:Bind From.User.Id, Mode=OneWay}" />
<TextBlock
Grid.Column="1"
Text="{x:Bind toolkit:StringExtensions.DecodeHtml(Body.Content), Mode=OneWay}"
TextWrapping="WrapWholeWords" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Margin" Value="0,8,0,8" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</ScrollViewer>
</DataTemplate>
</controls:GraphPresenter.ContentTemplate>
</controls:GraphPresenter>
</Grid>
</Page>

Просмотреть файл

@ -0,0 +1,51 @@
// 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 CommunityToolkit.Authentication;
using CommunityToolkit.Graph.Extensions;
using Microsoft.Graph;
using Windows.UI.Xaml.Controls;
namespace SampleTest.Samples.GraphPresenter
{
public sealed partial class TeamsChannelMessagesSample : Page
{
public IBaseRequestBuilder TeamsChannelMessagesRequestBuilder { get; set; }
public TeamsChannelMessagesSample()
{
this.InitializeComponent();
ProviderManager.Instance.ProviderUpdated += OnProviderUpdated;
ProviderManager.Instance.ProviderStateChanged += OnProviderStateChanged;
}
private void OnProviderUpdated(object sender, IProvider provider)
{
if (provider == null)
{
ClearRequestBuilders();
}
}
private void OnProviderStateChanged(object sender, ProviderStateChangedEventArgs e)
{
if (e.NewState == ProviderState.SignedIn)
{
var graphClient = ProviderManager.Instance.GlobalProvider.GetClient();
TeamsChannelMessagesRequestBuilder = graphClient.Teams["02bd9fd6-8f93-4758-87c3-1fb73740a315"].Channels["19:d0bba23c2fc8413991125a43a54cc30e@thread.skype"].Messages;
}
else
{
ClearRequestBuilders();
}
}
private void ClearRequestBuilders()
{
TeamsChannelMessagesRequestBuilder = null;
}
}
}

Просмотреть файл

@ -3,20 +3,11 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:SampleTest.Samples"
xmlns:toolkit="using:Microsoft.Toolkit"
xmlns:global="using:System.Globalization"
xmlns:controls="using:CommunityToolkit.Graph.Uwp.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:graph="using:Microsoft.Graph"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:graphpresenter="using:SampleTest.Samples.GraphPresenter"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Page.Resources>
<graph:Event x:Key="GraphEvent" />
<graph:Message x:Key="GraphMessage" />
<graph:ChatMessage x:Key="GraphChatMessage" />
<graph:PlannerTask x:Key="GraphPlannerTask" />
</Page.Resources>
<Grid>
<Grid.RowDefinitions>
@ -24,7 +15,8 @@
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock TextWrapping="WrapWholeWords">
The `GraphPresenter` is a unique control in the library which makes it easier for a developer to make any graph call and configure a nice display template in XAML. This opens up a world of possibilities for many uses outside of any other control available within this library. You can see a few examples of what's possible below.
The `GraphPresenter` is a unique control in the library which makes it easier for a developer to make any graph call and configure a nice display template in XAML.
This opens up a world of possibilities for many uses outside of any other control available within this library. You can see a few examples of what's possible below.
</TextBlock>
<Pivot Grid.Row="1">
<Pivot.ItemContainerStyle>
@ -32,241 +24,20 @@
<Setter Property="Margin" Value="8,8,8,0" />
</Style>
</Pivot.ItemContainerStyle>
<PivotItem Header="CalendarView">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel>
<TextBlock>The following example shows the `Me.CalendarView` API.</TextBlock>
<TextBlock Margin="0,8,0,0"
FontWeight="Bold">
My Upcoming Calendar Events:
</TextBlock>
</StackPanel>
<controls:GraphPresenter Grid.Row="1"
IsCollection="True"
OrderBy="start/dateTime"
RequestBuilder="{x:Bind CalendarViewBuilder, Mode=OneWay}"
ResponseType="graph:Event">
<controls:GraphPresenter.QueryOptions>
<!-- Need to create separate Properties as multiple functions not supported in x:Bind see https://github.com/microsoft/microsoft-ui-xaml/issues/2407 -->
<controls:QueryOption Name="startDateTime"
Value="{x:Bind Today.ToString('o', global:CultureInfo.InvariantCulture)}" />
<controls:QueryOption Name="endDateTime"
Value="{x:Bind ThreeDaysFromNow.ToString('o', global:CultureInfo.InvariantCulture)}" />
</controls:GraphPresenter.QueryOptions>
<controls:GraphPresenter.ContentTemplate>
<DataTemplate>
<!-- Return result is a collection of Event's as we used 'IsCollection', so bind that first. -->
<ScrollViewer HorizontalScrollMode="Disabled"
VerticalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="graph:Event">
<StackPanel>
<TextBlock Style="{StaticResource TitleTextBlockStyle}"
Text="{Binding Subject}" />
<TextBlock FontWeight="Bold">
<Run Text="{x:Bind local:GraphPresenterSample.ToLocalTime(Start), Mode=OneWay}" />
<Run>-</Run>
<Run Text="{x:Bind local:GraphPresenterSample.ToLocalTime(End), Mode=OneWay}" />
</TextBlock>
<TextBlock>
<Run FontFamily="Segoe MDL2 Assets"
Text="&#xE707;" />
<Run />
<Run Text="{x:Bind Location.DisplayName, Mode=OneWay}" />
</TextBlock>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Margin" Value="0,8,0,8" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</ScrollViewer>
</DataTemplate>
</controls:GraphPresenter.ContentTemplate>
</controls:GraphPresenter>
</Grid>
<PivotItem Header="Calendar View">
<graphpresenter:CalendarViewSample />
</PivotItem>
<PivotItem Header="(Mail) Messages">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel>
<TextBlock>The following example shows the `Me.Messages` API for getting a user's inbox mail messages.</TextBlock>
<TextBlock Margin="0,8,0,0"
FontWeight="Bold">
My Messages:
</TextBlock>
</StackPanel>
<controls:GraphPresenter Grid.Row="1"
IsCollection="True"
RequestBuilder="{x:Bind MessagesBuilder, Mode=OneWay}"
ResponseType="graph:Message">
<controls:GraphPresenter.ContentTemplate>
<DataTemplate>
<ScrollViewer HorizontalScrollMode="Disabled"
VerticalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="graph:Message">
<StackPanel>
<controls:PersonView Margin="-4"
PersonQuery="{x:Bind Sender.EmailAddress.Address}"
PersonViewType="OneLine" />
<TextBlock Padding="0"
Style="{StaticResource BaseTextBlockStyle}"
Text="{x:Bind Subject}" />
<TextBlock Text="{x:Bind local:GraphPresenterSample.RemoveWhitespace(BodyPreview)}"
TextWrapping="WrapWholeWords" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Margin" Value="0,8,0,8" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</ScrollViewer>
</DataTemplate>
</controls:GraphPresenter.ContentTemplate>
</controls:GraphPresenter>
</Grid>
<PivotItem Header="Mail Messages">
<graphpresenter:MailMessagesSample />
</PivotItem>
<PivotItem Header="Tasks">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel>
<TextBlock>The following example shows the `Me.Planner.Tasks` API for getting a user's tasks.</TextBlock>
<TextBlock Margin="0,8,0,0"
FontWeight="Bold">
My Tasks:
</TextBlock>
</StackPanel>
<controls:GraphPresenter Grid.Row="1"
IsCollection="True"
RequestBuilder="{x:Bind PlannerTasksBuilder, Mode=OneWay}"
ResponseType="graph:PlannerTask">
<controls:GraphPresenter.ContentTemplate>
<DataTemplate>
<ScrollViewer HorizontalScrollMode="Disabled"
VerticalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="graph:PlannerTask">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<!-- We've disabled the checkbox as we're not going to make the call back to the graph to modify the item. -->
<CheckBox IsChecked="{x:Bind local:GraphPresenterSample.IsTaskCompleted(PercentComplete), Mode=OneWay}"
IsEnabled="False" />
<TextBlock Grid.Column="1"
Text="{x:Bind Title, Mode=OneWay}" />
<ItemsControl Grid.Row="1"
Grid.Column="1"
ItemsSource="{x:Bind Assignments, Mode=OneWay}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<!-- We're getting a KVP from the PlannerAssignments type, the Key is the UserId string, we'll use that to look-up our user info. -->
<controls:PersonView Margin="-4"
UserId="{Binding Key}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
<TextBlock Grid.Row="2"
Grid.Column="2"
FontWeight="Bold">
<Run>Due</Run>
<Run Text="{x:Bind local:GraphPresenterSample.ToLocalTime(DueDateTime), Mode=OneWay}" />
</TextBlock>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Margin" Value="0,8,0,8" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</ScrollViewer>
</DataTemplate>
</controls:GraphPresenter.ContentTemplate>
</controls:GraphPresenter>
</Grid>
<PivotItem Header="Planner Tasks">
<graphpresenter:PlannerTasksSample />
</PivotItem>
<PivotItem Header="Teams Messages">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel>
<TextBlock>The following example shows the beta `Teams/id/Channels/id/messages` API for getting a list of messages (without replies) from a Channel in Teams.</TextBlock>
<TextBlock Margin="0,8,0,0"
FontWeight="Bold">
My Chat Messages:
</TextBlock>
</StackPanel>
<controls:GraphPresenter Grid.Row="1"
IsCollection="True"
RequestBuilder="{x:Bind TeamsChannelMessagesBuilder, Mode=OneWay}"
ResponseType="graph:ChatMessage">
<controls:GraphPresenter.ContentTemplate>
<DataTemplate>
<ScrollViewer HorizontalScrollMode="Disabled"
VerticalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="graph:ChatMessage">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<controls:PersonView Margin="-4,-4,8,-4"
UserId="{x:Bind From.User.Id, Mode=OneWay}" />
<TextBlock Grid.Column="1"
Text="{x:Bind toolkit:StringExtensions.DecodeHtml(Body.Content), Mode=OneWay}"
TextWrapping="WrapWholeWords" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Margin" Value="0,8,0,8" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</ScrollViewer>
</DataTemplate>
</controls:GraphPresenter.ContentTemplate>
</controls:GraphPresenter>
</Grid>
<graphpresenter:TeamsChannelMessagesSample />
</PivotItem>
<PivotItem Header="OneDrive">
<graphpresenter:OneDriveSample />
</PivotItem>
</Pivot>
</Grid>

Просмотреть файл

@ -14,58 +14,6 @@ namespace SampleTest.Samples
{
public sealed partial class GraphPresenterSample : Page
{
// Workaround for https://github.com/microsoft/microsoft-ui-xaml/issues/2407
public DateTime Today => DateTimeOffset.Now.Date.ToUniversalTime();
// Workaround for https://github.com/microsoft/microsoft-ui-xaml/issues/2407
public DateTime ThreeDaysFromNow => Today.AddDays(3);
public IBaseRequestBuilder CalendarViewBuilder;
public IBaseRequestBuilder MessagesBuilder;
public IBaseRequestBuilder PlannerTasksBuilder;
public IBaseRequestBuilder TeamsChannelMessagesBuilder;
public GraphPresenterSample()
{
InitializeComponent();
ProviderManager.Instance.ProviderUpdated += OnProviderUpdated;
ProviderManager.Instance.ProviderStateChanged += OnProviderStateChanged;
}
private void OnProviderStateChanged(object sender, ProviderStateChangedEventArgs e)
{
if (e.NewState == ProviderState.SignedIn)
{
var graphClient = ProviderManager.Instance.GlobalProvider.GetClient();
CalendarViewBuilder = graphClient.Me.CalendarView;
MessagesBuilder = graphClient.Me.Messages;
PlannerTasksBuilder = graphClient.Me.Planner.Tasks;
TeamsChannelMessagesBuilder = graphClient.Teams["02bd9fd6-8f93-4758-87c3-1fb73740a315"].Channels["19:d0bba23c2fc8413991125a43a54cc30e@thread.skype"].Messages;
}
else
{
ClearRequestBuilders();
}
}
private void OnProviderUpdated(object sender, IProvider provider)
{
if (provider == null)
{
ClearRequestBuilders();
}
}
private void ClearRequestBuilders()
{
CalendarViewBuilder = null;
MessagesBuilder = null;
PlannerTasksBuilder = null;
TeamsChannelMessagesBuilder = null;
}
public static string ToLocalTime(DateTimeTimeZone value)
{
// Workaround for https://github.com/microsoft/microsoft-ui-xaml/issues/2407
@ -78,15 +26,9 @@ namespace SampleTest.Samples
return value?.LocalDateTime.ToString("g");
}
public static string RemoveWhitespace(string value)
public GraphPresenterSample()
{
// Workaround for https://github.com/microsoft/microsoft-ui-xaml/issues/2654
return Regex.Replace(value, @"\t|\r|\n", " ");
}
public static bool IsTaskCompleted(int? percentCompleted)
{
return percentCompleted == 100;
InitializeComponent();
}
}
}

Просмотреть файл

@ -1,14 +0,0 @@
<Page
x:Class="SampleTest.Samples.OneDriveStorageSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:SampleTest.Samples"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid>
</Grid>
</Page>

Просмотреть файл

@ -1,16 +0,0 @@
// 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 Windows.UI.Xaml.Controls;
namespace SampleTest.Samples
{
public sealed partial class OneDriveStorageSample : Page
{
public OneDriveStorageSample()
{
InitializeComponent();
}
}
}