├── .gitattributes ├── .github ├── ISSUE_TEMPLATE │ ├── ask-a-question.md │ └── bug_report.md ├── dependabot.yml ├── policies │ └── resourceManagement.yml └── workflows │ ├── auto-merge-dependabot.yml │ └── msbuild.yml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── GraphTutorial ├── App.xaml ├── App.xaml.cs ├── Assets │ ├── LockScreenLogo.scale-200.png │ ├── SplashScreen.scale-200.png │ ├── Square150x150Logo.scale-200.png │ ├── Square44x44Logo.scale-200.png │ ├── Square44x44Logo.targetsize-24_altform-unplated.png │ ├── StoreLogo.png │ └── Wide310x150Logo.scale-200.png ├── CalendarPage.xaml ├── CalendarPage.xaml.cs ├── GraphDateTimeTimeZoneConverter.cs ├── GraphTutorial.csproj ├── GraphTutorial.sln ├── HomePage.xaml ├── HomePage.xaml.cs ├── MainPage.xaml ├── MainPage.xaml.cs ├── NewEventPage.xaml ├── NewEventPage.xaml.cs ├── OAuth.resw.example ├── Package.appxmanifest └── Properties │ ├── AssemblyInfo.cs │ └── Default.rd.xml ├── LICENSE ├── README.md └── SECURITY.md /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/ask-a-question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Ask a question 3 | about: Ask a question about Graph, adding features to this sample, etc. 4 | title: '' 5 | labels: question, needs triage 6 | assignees: '' 7 | 8 | --- 9 | 10 | Thank you for taking an interest in Microsoft Graph development! Please feel free to ask a question here, but keep in mind the following: 11 | 12 | - This is not an official Microsoft support channel, and our ability to respond to questions here is limited. Questions about Graph, or questions about adding a new feature to the sample, will be answered on a best-effort basis. 13 | - Questions should be asked on [Stack Overflow](https://stackoverflow.com/questions/tagged/microsoft-graph). 14 | - Issues with Microsoft Graph itself should be handled through [support](https://developer.microsoft.com/graph/support). 15 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug report, needs triage 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Where did you get the code?** 11 | - [ ] Downloaded from GitHub 12 | - [ ] Downloaded from the [Microsoft Graph quick start tool](https://developer.microsoft.com/graph/quick-start) 13 | - [ ] Followed the tutorial from [Microsoft Graph tutorials](https://docs.microsoft.com/graph/tutorials) 14 | 15 | **Describe the bug** 16 | A clear and concise description of what the bug is. 17 | 18 | **To Reproduce** 19 | Steps to reproduce the behavior: 20 | 1. Go to '...' 21 | 2. Click on '....' 22 | 3. Scroll down to '....' 23 | 4. See error 24 | 25 | **Expected behavior** 26 | A clear and concise description of what you expected to happen. 27 | 28 | **Screenshots** 29 | If applicable, add screenshots to help explain your problem. 30 | 31 | **Desktop (please complete the following information):** 32 | - OS: [e.g. iOS] 33 | - Browser [e.g. chrome, safari] 34 | - Version [e.g. 22] 35 | 36 | **Dependency versions** 37 | - Authentication library (MSAL, etc.) version: 38 | - Graph library (Graph SDK, REST library, etc.) version: 39 | 40 | **Additional context** 41 | Add any other context about the problem here. 42 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "nuget" # See documentation for possible values 9 | directory: "/GraphTutorial" # Location of package manifests 10 | schedule: 11 | interval: "weekly" 12 | -------------------------------------------------------------------------------- /.github/policies/resourceManagement.yml: -------------------------------------------------------------------------------- 1 | id: 2 | name: GitOps.PullRequestIssueManagement 3 | description: GitOps.PullRequestIssueManagement primitive 4 | owner: 5 | resource: repository 6 | disabled: false 7 | where: 8 | configuration: 9 | resourceManagementConfiguration: 10 | scheduledSearches: 11 | - description: 12 | frequencies: 13 | - hourly: 14 | hour: 6 15 | filters: 16 | - isIssue 17 | - isOpen 18 | - hasLabel: 19 | label: needs author feedback 20 | - hasLabel: 21 | label: no recent activity 22 | - noActivitySince: 23 | days: 3 24 | actions: 25 | - closeIssue 26 | - description: 27 | frequencies: 28 | - hourly: 29 | hour: 6 30 | filters: 31 | - isIssue 32 | - isOpen 33 | - hasLabel: 34 | label: needs author feedback 35 | - noActivitySince: 36 | days: 4 37 | - isNotLabeledWith: 38 | label: no recent activity 39 | actions: 40 | - addLabel: 41 | label: no recent activity 42 | - addReply: 43 | reply: This issue has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for **4 days**. It will be closed if no further activity occurs **within 3 days of this comment**. 44 | - description: 45 | frequencies: 46 | - hourly: 47 | hour: 6 48 | filters: 49 | - isIssue 50 | - isOpen 51 | - hasLabel: 52 | label: duplicate 53 | - noActivitySince: 54 | days: 1 55 | actions: 56 | - addReply: 57 | reply: This issue has been marked as duplicate and has not had any activity for **1 day**. It will be closed for housekeeping purposes. 58 | - closeIssue 59 | - description: 60 | frequencies: 61 | - hourly: 62 | hour: 3 63 | filters: 64 | - isOpen 65 | - isIssue 66 | - hasLabel: 67 | label: graph question 68 | actions: 69 | - removeLabel: 70 | label: 'needs attention :wave:' 71 | - removeLabel: 72 | label: needs author feedback 73 | - removeLabel: 74 | label: 'needs triage :mag:' 75 | - removeLabel: 76 | label: no recent activity 77 | - addLabel: 78 | label: out of scope 79 | - addReply: 80 | reply: >- 81 | It looks like you are asking a question about using Microsoft Graph or one of the Microsoft Graph SDKs that is not directly related to this sample. Unfortunately we are not set up to answer general questions in this repository, so this issue will be closed. 82 | 83 | 84 | Please try asking your question on [Stack Overflow](https://stackoverflow.com/questions/tagged/microsoft-graph-api), tagging your question with `microsoft-graph-api`. 85 | - closeIssue 86 | - description: 87 | frequencies: 88 | - hourly: 89 | hour: 3 90 | filters: 91 | - isOpen 92 | - isIssue 93 | - hasLabel: 94 | label: graph issue 95 | actions: 96 | - removeLabel: 97 | label: 'needs attention :wave:' 98 | - removeLabel: 99 | label: needs author feedback 100 | - removeLabel: 101 | label: 'needs triage :mag:' 102 | - removeLabel: 103 | label: no recent activity 104 | - addLabel: 105 | label: out of scope 106 | - addReply: 107 | reply: >- 108 | It looks like you are reporting an issue with Microsoft Graph or one of the Microsoft Graph SDKs that is not fixable by changing code in this sample. Unfortunately we are not set up to provide product support in this repository, so this issue will be closed. 109 | 110 | 111 | Please visit one of the following links to report your issue. 112 | 113 | 114 | - Issue with Microsoft Graph service: [Microsoft Graph support](https://developer.microsoft.com/graph/support#report-issues-with-the-service), choose one of the options under **Report issues with the service** 115 | 116 | - Issue with a Microsoft Graph SDK: Open an issue in the SDK's GitHub repository. See [microsoftgraph on GitHub](https://github.com/microsoftgraph?q=sdk+in%3Aname&type=public&language=) for a list of SDK repositories. 117 | - closeIssue 118 | eventResponderTasks: 119 | - if: 120 | - payloadType: Issue_Comment 121 | - isAction: 122 | action: Created 123 | - isActivitySender: 124 | issueAuthor: True 125 | - hasLabel: 126 | label: needs author feedback 127 | - isOpen 128 | then: 129 | - addLabel: 130 | label: 'needs attention :wave:' 131 | - removeLabel: 132 | label: needs author feedback 133 | description: 134 | - if: 135 | - payloadType: Issues 136 | - not: 137 | isAction: 138 | action: Closed 139 | - hasLabel: 140 | label: no recent activity 141 | then: 142 | - removeLabel: 143 | label: no recent activity 144 | description: 145 | - if: 146 | - payloadType: Issue_Comment 147 | - hasLabel: 148 | label: no recent activity 149 | then: 150 | - removeLabel: 151 | label: no recent activity 152 | description: 153 | - if: 154 | - payloadType: Pull_Request 155 | then: 156 | - inPrLabel: 157 | label: in pr 158 | description: 159 | onFailure: 160 | onSuccess: 161 | -------------------------------------------------------------------------------- /.github/workflows/auto-merge-dependabot.yml: -------------------------------------------------------------------------------- 1 | name: Auto-merge dependabot updates 2 | 3 | on: 4 | pull_request: 5 | branches: [ main ] 6 | 7 | permissions: 8 | pull-requests: write 9 | contents: write 10 | 11 | jobs: 12 | 13 | dependabot-merge: 14 | 15 | runs-on: ubuntu-latest 16 | 17 | if: ${{ github.actor == 'dependabot[bot]' }} 18 | 19 | steps: 20 | - name: Dependabot metadata 21 | id: metadata 22 | uses: dependabot/fetch-metadata@v1.1.1 23 | with: 24 | github-token: "${{ secrets.GITHUB_TOKEN }}" 25 | 26 | - name: Enable auto-merge for Dependabot PRs 27 | if: ${{steps.metadata.outputs.update-type != 'version-update:semver-major'}} 28 | run: gh pr merge --auto --merge "$PR_URL" 29 | env: 30 | PR_URL: ${{github.event.pull_request.html_url}} 31 | GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} 32 | -------------------------------------------------------------------------------- /.github/workflows/msbuild.yml: -------------------------------------------------------------------------------- 1 | name: MSBuild 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | branches: [ main ] 8 | workflow_dispatch: 9 | 10 | env: 11 | # Path to the solution file relative to the root of the project. 12 | SOLUTION_FILE_PATH: .\GraphTutorial 13 | 14 | # Configuration type to build. 15 | # You can convert this to a build matrix if you need coverage of multiple configuration types. 16 | # https://docs.github.com/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix 17 | BUILD_CONFIGURATION: Debug 18 | 19 | permissions: 20 | contents: read 21 | 22 | jobs: 23 | build: 24 | runs-on: windows-latest 25 | 26 | steps: 27 | - uses: actions/checkout@v3 28 | 29 | - name: Copy settings file 30 | run: | 31 | copy ${{env.SOLUTION_FILE_PATH}}\OAuth.resw.example ${{env.SOLUTION_FILE_PATH}}\OAuth.resw 32 | 33 | - name: Add MSBuild to PATH 34 | uses: microsoft/setup-msbuild@v1.0.2 35 | 36 | - name: Restore NuGet packages 37 | working-directory: ${{env.GITHUB_WORKSPACE}} 38 | run: nuget restore ${{env.SOLUTION_FILE_PATH}} 39 | 40 | - name: Build 41 | working-directory: ${{env.GITHUB_WORKSPACE}} 42 | # Add additional options to the MSBuild command line here (like platform or verbosity level). 43 | # See https://docs.microsoft.com/visualstudio/msbuild/msbuild-command-line-reference 44 | run: msbuild /m /p:Configuration=${{env.BUILD_CONFIGURATION}} ${{env.SOLUTION_FILE_PATH}} 45 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # User-specific files 2 | *.suo 3 | *.user 4 | *.sln.docstates 5 | .vs/ 6 | 7 | # Build results 8 | [Dd]ebug/ 9 | [Dd]ebugPublic/ 10 | [Rr]elease/ 11 | x64/ 12 | build/ 13 | bld/ 14 | [Bb]in/ 15 | [Oo]bj/ 16 | 17 | # MSTest test Results 18 | [Tt]est[Rr]esult*/ 19 | [Bb]uild[Ll]og.* 20 | 21 | #NUNIT 22 | *.VisualState.xml 23 | TestResult.xml 24 | 25 | # Build Results of an ATL Project 26 | [Dd]ebugPS/ 27 | [Rr]eleasePS/ 28 | dlldata.c 29 | 30 | *_i.c 31 | *_p.c 32 | *_i.h 33 | *.ilk 34 | *.meta 35 | *.obj 36 | *.pch 37 | *.pdb 38 | *.pgc 39 | *.pgd 40 | *.rsp 41 | *.sbr 42 | *.tlb 43 | *.tli 44 | *.tlh 45 | *.tmp 46 | *.tmp_proj 47 | *.log 48 | *.vspscc 49 | *.vssscc 50 | .builds 51 | *.pidb 52 | *.svclog 53 | *.scc 54 | 55 | # Chutzpah Test files 56 | _Chutzpah* 57 | 58 | # Visual C++ cache files 59 | ipch/ 60 | *.aps 61 | *.ncb 62 | *.opensdf 63 | *.sdf 64 | *.cachefile 65 | 66 | # Visual Studio profiler 67 | *.psess 68 | *.vsp 69 | *.vspx 70 | 71 | # TFS 2012 Local Workspace 72 | $tf/ 73 | 74 | # Guidance Automation Toolkit 75 | *.gpState 76 | 77 | # ReSharper is a .NET coding add-in 78 | _ReSharper*/ 79 | *.[Rr]e[Ss]harper 80 | *.DotSettings.user 81 | 82 | # JustCode is a .NET coding addin-in 83 | .JustCode 84 | 85 | # TeamCity is a build add-in 86 | _TeamCity* 87 | 88 | # DotCover is a Code Coverage Tool 89 | *.dotCover 90 | 91 | # NCrunch 92 | *.ncrunch* 93 | _NCrunch_* 94 | .*crunch*.local.xml 95 | 96 | # MightyMoose 97 | *.mm.* 98 | AutoTest.Net/ 99 | 100 | # Web workbench (sass) 101 | .sass-cache/ 102 | 103 | # Installshield output folder 104 | [Ee]xpress/ 105 | 106 | # DocProject is a documentation generator add-in 107 | DocProject/buildhelp/ 108 | DocProject/Help/*.HxT 109 | DocProject/Help/*.HxC 110 | DocProject/Help/*.hhc 111 | DocProject/Help/*.hhk 112 | DocProject/Help/*.hhp 113 | DocProject/Help/Html2 114 | DocProject/Help/html 115 | 116 | # Click-Once directory 117 | publish/ 118 | 119 | # Publish Web Output 120 | *.[Pp]ublish.xml 121 | *.azurePubxml 122 | 123 | # NuGet Packages Directory 124 | packages/ 125 | ## TODO: If the tool you use requires repositories.config uncomment the next line 126 | #!packages/repositories.config 127 | 128 | # Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets 129 | # This line needs to be after the ignore of the build folder (and the packages folder if the line above has been uncommented) 130 | !packages/build/ 131 | 132 | # Windows Azure Build Output 133 | csx/ 134 | *.build.csdef 135 | 136 | # Windows Store app package directory 137 | AppPackages/ 138 | 139 | # Others 140 | sql/ 141 | *.Cache 142 | ClientBin/ 143 | [Ss]tyle[Cc]op.* 144 | ~$* 145 | *~ 146 | *.dbmdl 147 | *.dbproj.schemaview 148 | *.publishsettings 149 | node_modules/ 150 | 151 | # RIA/Silverlight projects 152 | Generated_Code/ 153 | 154 | # Backup & report files from converting an old project file to a newer 155 | # Visual Studio version. Backup files are not needed, because we have git ;-) 156 | _UpgradeReport_Files/ 157 | Backup*/ 158 | UpgradeLog*.XML 159 | UpgradeLog*.htm 160 | 161 | # SQL Server files 162 | *.mdf 163 | *.ldf 164 | 165 | # Business Intelligence projects 166 | *.rdl.data 167 | *.bim.layout 168 | *.bim_*.settings 169 | 170 | # Microsoft Fakes 171 | FakesAssemblies/ 172 | 173 | # MacOS files 174 | **.DS_Store 175 | 176 | ## VS Code 177 | .vscode/ 178 | 179 | ## OAuth settings 180 | OAuth.resw 181 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Microsoft Open Source Code of Conduct 2 | 3 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 4 | 5 | Resources: 6 | 7 | - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) 8 | - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) 9 | - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns 10 | - Employees can reach out at [aka.ms/opensource/moderation-support](https://aka.ms/opensource/moderation-support) 11 | -------------------------------------------------------------------------------- /GraphTutorial/App.xaml: -------------------------------------------------------------------------------- 1 |  3 | 4 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /GraphTutorial/App.xaml.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using Windows.ApplicationModel; 6 | using Windows.ApplicationModel.Activation; 7 | using Windows.UI.Xaml; 8 | using Windows.UI.Xaml.Controls; 9 | using Windows.UI.Xaml.Navigation; 10 | 11 | namespace GraphTutorial 12 | { 13 | /// 14 | /// Provides application-specific behavior to supplement the default Application class. 15 | /// 16 | sealed partial class App : Application 17 | { 18 | public bool IsAuthenticated { get; set; } 19 | 20 | /// 21 | /// Initializes the singleton application object. This is the first line of authored code 22 | /// executed, and as such is the logical equivalent of main() or WinMain(). 23 | /// 24 | public App() 25 | { 26 | this.InitializeComponent(); 27 | this.Suspending += OnSuspending; 28 | } 29 | 30 | /// 31 | /// Invoked when the application is launched normally by the end user. Other entry points 32 | /// will be used such as when the application is launched to open a specific file. 33 | /// 34 | /// Details about the launch request and process. 35 | protected override void OnLaunched(LaunchActivatedEventArgs e) 36 | { 37 | Frame rootFrame = Window.Current.Content as Frame; 38 | 39 | // Do not repeat app initialization when the Window already has content, 40 | // just ensure that the window is active 41 | if (rootFrame == null) 42 | { 43 | // Create a Frame to act as the navigation context and navigate to the first page 44 | rootFrame = new Frame(); 45 | 46 | rootFrame.NavigationFailed += OnNavigationFailed; 47 | 48 | if (e.PreviousExecutionState == ApplicationExecutionState.Terminated) 49 | { 50 | //TODO: Load state from previously suspended application 51 | } 52 | 53 | // Place the frame in the current Window 54 | Window.Current.Content = rootFrame; 55 | } 56 | 57 | if (e.PrelaunchActivated == false) 58 | { 59 | if (rootFrame.Content == null) 60 | { 61 | // When the navigation stack isn't restored navigate to the first page, 62 | // configuring the new page by passing required information as a navigation 63 | // parameter 64 | rootFrame.Navigate(typeof(MainPage), e.Arguments); 65 | } 66 | // Ensure the current window is active 67 | Window.Current.Activate(); 68 | } 69 | } 70 | 71 | /// 72 | /// Invoked when Navigation to a certain page fails 73 | /// 74 | /// The Frame which failed navigation 75 | /// Details about the navigation failure 76 | void OnNavigationFailed(object sender, NavigationFailedEventArgs e) 77 | { 78 | throw new Exception("Failed to load Page " + e.SourcePageType.FullName); 79 | } 80 | 81 | /// 82 | /// Invoked when application execution is being suspended. Application state is saved 83 | /// without knowing whether the application will be terminated or resumed with the contents 84 | /// of memory still intact. 85 | /// 86 | /// The source of the suspend request. 87 | /// Details about the suspend request. 88 | private void OnSuspending(object sender, SuspendingEventArgs e) 89 | { 90 | var deferral = e.SuspendingOperation.GetDeferral(); 91 | //TODO: Save application state and stop any background activity 92 | deferral.Complete(); 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /GraphTutorial/Assets/LockScreenLogo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-sample-uwp/ff29d6db40c5ac0c09b55b71ce9d728f2be23601/GraphTutorial/Assets/LockScreenLogo.scale-200.png -------------------------------------------------------------------------------- /GraphTutorial/Assets/SplashScreen.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-sample-uwp/ff29d6db40c5ac0c09b55b71ce9d728f2be23601/GraphTutorial/Assets/SplashScreen.scale-200.png -------------------------------------------------------------------------------- /GraphTutorial/Assets/Square150x150Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-sample-uwp/ff29d6db40c5ac0c09b55b71ce9d728f2be23601/GraphTutorial/Assets/Square150x150Logo.scale-200.png -------------------------------------------------------------------------------- /GraphTutorial/Assets/Square44x44Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-sample-uwp/ff29d6db40c5ac0c09b55b71ce9d728f2be23601/GraphTutorial/Assets/Square44x44Logo.scale-200.png -------------------------------------------------------------------------------- /GraphTutorial/Assets/Square44x44Logo.targetsize-24_altform-unplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-sample-uwp/ff29d6db40c5ac0c09b55b71ce9d728f2be23601/GraphTutorial/Assets/Square44x44Logo.targetsize-24_altform-unplated.png -------------------------------------------------------------------------------- /GraphTutorial/Assets/StoreLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-sample-uwp/ff29d6db40c5ac0c09b55b71ce9d728f2be23601/GraphTutorial/Assets/StoreLogo.png -------------------------------------------------------------------------------- /GraphTutorial/Assets/Wide310x150Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-sample-uwp/ff29d6db40c5ac0c09b55b71ce9d728f2be23601/GraphTutorial/Assets/Wide310x150Logo.scale-200.png -------------------------------------------------------------------------------- /GraphTutorial/CalendarPage.xaml: -------------------------------------------------------------------------------- 1 |  3 | 4 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 26 | 27 | 32 | 37 | 38 | 43 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /GraphTutorial/CalendarPage.xaml.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using CommunityToolkit.Authentication; 8 | using CommunityToolkit.Graph.Extensions; 9 | using Microsoft.Graph; 10 | using Microsoft.Toolkit.Uwp.UI.Controls; 11 | using Windows.UI.Xaml; 12 | using Windows.UI.Xaml.Controls; 13 | using Windows.UI.Xaml.Navigation; 14 | 15 | // The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238 16 | 17 | namespace GraphTutorial 18 | { 19 | /// 20 | /// An empty page that can be used on its own or navigated to within a Frame. 21 | /// 22 | public sealed partial class CalendarPage : Page 23 | { 24 | public CalendarPage() 25 | { 26 | this.InitializeComponent(); 27 | } 28 | 29 | private void ShowNotification(string message) 30 | { 31 | // Get the main page that contains the InAppNotification 32 | var mainPage = (Window.Current.Content as Frame).Content as MainPage; 33 | 34 | // Get the notification control 35 | var notification = mainPage.FindName("Notification") as InAppNotification; 36 | 37 | notification.Show(message); 38 | } 39 | 40 | protected override async void OnNavigatedTo(NavigationEventArgs e) 41 | { 42 | // Get the Graph client from the provider 43 | var graphClient = ProviderManager.Instance.GlobalProvider.GetClient(); 44 | 45 | try 46 | { 47 | // Get the user's mailbox settings to determine 48 | // their time zone 49 | var user = await graphClient.Me.Request() 50 | .Select(u => new { u.MailboxSettings }) 51 | .GetAsync(); 52 | 53 | var startOfWeek = GetUtcStartOfWeekInTimeZone(DateTime.Today, user.MailboxSettings.TimeZone); 54 | var endOfWeek = startOfWeek.AddDays(7); 55 | 56 | var queryOptions = new List 57 | { 58 | new QueryOption("startDateTime", startOfWeek.ToString("o")), 59 | new QueryOption("endDateTime", endOfWeek.ToString("o")) 60 | }; 61 | 62 | // Get the events 63 | var events = await graphClient.Me.CalendarView.Request(queryOptions) 64 | .Header("Prefer", $"outlook.timezone=\"{user.MailboxSettings.TimeZone}\"") 65 | .Select(ev => new 66 | { 67 | ev.Subject, 68 | ev.Organizer, 69 | ev.Start, 70 | ev.End 71 | }) 72 | .OrderBy("start/dateTime") 73 | .Top(50) 74 | .GetAsync(); 75 | 76 | EventList.ItemsSource = events.CurrentPage.ToList(); 77 | } 78 | catch (ServiceException ex) 79 | { 80 | ShowNotification($"Exception getting events: {ex.Message}"); 81 | } 82 | 83 | base.OnNavigatedTo(e); 84 | } 85 | 86 | private static DateTime GetUtcStartOfWeekInTimeZone(DateTime today, string timeZoneId) 87 | { 88 | TimeZoneInfo userTimeZone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId); 89 | 90 | // Assumes Sunday as first day of week 91 | int diff = System.DayOfWeek.Sunday - today.DayOfWeek; 92 | 93 | // create date as unspecified kind 94 | var unspecifiedStart = DateTime.SpecifyKind(today.AddDays(diff), DateTimeKind.Unspecified); 95 | 96 | // convert to UTC 97 | return TimeZoneInfo.ConvertTimeToUtc(unspecifiedStart, userTimeZone); 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /GraphTutorial/GraphDateTimeTimeZoneConverter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | // 5 | using System; 6 | using Microsoft.Graph; 7 | using Microsoft.Graph.Extensions; 8 | 9 | namespace GraphTutorial 10 | { 11 | class GraphDateTimeTimeZoneConverter : Windows.UI.Xaml.Data.IValueConverter 12 | { 13 | public object Convert(object value, Type targetType, object parameter, string language) 14 | { 15 | DateTimeTimeZone date = value as DateTimeTimeZone; 16 | 17 | if (date != null) 18 | { 19 | return date.ToDateTime().ToString(); 20 | } 21 | 22 | return string.Empty; 23 | } 24 | 25 | public object ConvertBack(object value, Type targetType, object parameter, string language) 26 | { 27 | throw new NotImplementedException(); 28 | } 29 | } 30 | } 31 | // 32 | -------------------------------------------------------------------------------- /GraphTutorial/GraphTutorial.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | x86 7 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52} 8 | AppContainerExe 9 | Properties 10 | GraphTutorial 11 | GraphTutorial 12 | en-US 13 | UAP 14 | 10.0.19041.0 15 | 10.0.17763.0 16 | 14 17 | 512 18 | {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 19 | true 20 | false 21 | 22 | 23 | true 24 | bin\x86\Debug\ 25 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP 26 | ;2008 27 | full 28 | x86 29 | false 30 | prompt 31 | true 32 | 33 | 34 | bin\x86\Release\ 35 | TRACE;NETFX_CORE;WINDOWS_UWP 36 | true 37 | ;2008 38 | pdbonly 39 | x86 40 | false 41 | prompt 42 | true 43 | true 44 | 45 | 46 | true 47 | bin\ARM\Debug\ 48 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP 49 | ;2008 50 | full 51 | ARM 52 | false 53 | prompt 54 | true 55 | 56 | 57 | bin\ARM\Release\ 58 | TRACE;NETFX_CORE;WINDOWS_UWP 59 | true 60 | ;2008 61 | pdbonly 62 | ARM 63 | false 64 | prompt 65 | true 66 | true 67 | 68 | 69 | true 70 | bin\ARM64\Debug\ 71 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP 72 | ;2008 73 | full 74 | ARM64 75 | false 76 | prompt 77 | true 78 | true 79 | 80 | 81 | bin\ARM64\Release\ 82 | TRACE;NETFX_CORE;WINDOWS_UWP 83 | true 84 | ;2008 85 | pdbonly 86 | ARM64 87 | false 88 | prompt 89 | true 90 | true 91 | 92 | 93 | true 94 | bin\x64\Debug\ 95 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP 96 | ;2008 97 | full 98 | x64 99 | false 100 | prompt 101 | true 102 | 103 | 104 | bin\x64\Release\ 105 | TRACE;NETFX_CORE;WINDOWS_UWP 106 | true 107 | ;2008 108 | pdbonly 109 | x64 110 | false 111 | prompt 112 | true 113 | true 114 | 115 | 116 | PackageReference 117 | 118 | 119 | 120 | App.xaml 121 | 122 | 123 | CalendarPage.xaml 124 | 125 | 126 | 127 | HomePage.xaml 128 | 129 | 130 | MainPage.xaml 131 | 132 | 133 | NewEventPage.xaml 134 | 135 | 136 | 137 | 138 | 139 | Designer 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | MSBuild:Compile 155 | Designer 156 | 157 | 158 | Designer 159 | MSBuild:Compile 160 | 161 | 162 | Designer 163 | MSBuild:Compile 164 | 165 | 166 | MSBuild:Compile 167 | Designer 168 | 169 | 170 | Designer 171 | MSBuild:Compile 172 | 173 | 174 | 175 | 176 | 7.1.4 177 | 178 | 179 | 7.1.4 180 | 181 | 182 | 6.2.14 183 | 184 | 185 | 7.1.3 186 | 187 | 188 | 7.1.3 189 | 190 | 191 | 7.1.3 192 | 193 | 194 | 195 | 196 | 197 | 198 | 14.0 199 | 200 | 201 | 208 | -------------------------------------------------------------------------------- /GraphTutorial/GraphTutorial.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.3.32901.215 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GraphTutorial", "GraphTutorial.csproj", "{1359BDFF-04FF-4A5D-B55B-33E447D9FC52}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|ARM = Debug|ARM 11 | Debug|ARM64 = Debug|ARM64 12 | Debug|x64 = Debug|x64 13 | Debug|x86 = Debug|x86 14 | Release|ARM = Release|ARM 15 | Release|ARM64 = Release|ARM64 16 | Release|x64 = Release|x64 17 | Release|x86 = Release|x86 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}.Debug|ARM.ActiveCfg = Debug|ARM 21 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}.Debug|ARM.Build.0 = Debug|ARM 22 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}.Debug|ARM.Deploy.0 = Debug|ARM 23 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}.Debug|ARM64.ActiveCfg = Debug|ARM64 24 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}.Debug|ARM64.Build.0 = Debug|ARM64 25 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}.Debug|ARM64.Deploy.0 = Debug|ARM64 26 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}.Debug|x64.ActiveCfg = Debug|x64 27 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}.Debug|x64.Build.0 = Debug|x64 28 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}.Debug|x64.Deploy.0 = Debug|x64 29 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}.Debug|x86.ActiveCfg = Debug|x86 30 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}.Debug|x86.Build.0 = Debug|x86 31 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}.Debug|x86.Deploy.0 = Debug|x86 32 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}.Release|ARM.ActiveCfg = Release|ARM 33 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}.Release|ARM.Build.0 = Release|ARM 34 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}.Release|ARM.Deploy.0 = Release|ARM 35 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}.Release|ARM64.ActiveCfg = Release|ARM64 36 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}.Release|ARM64.Build.0 = Release|ARM64 37 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}.Release|ARM64.Deploy.0 = Release|ARM64 38 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}.Release|x64.ActiveCfg = Release|x64 39 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}.Release|x64.Build.0 = Release|x64 40 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}.Release|x64.Deploy.0 = Release|x64 41 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}.Release|x86.ActiveCfg = Release|x86 42 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}.Release|x86.Build.0 = Release|x86 43 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}.Release|x86.Deploy.0 = Release|x86 44 | EndGlobalSection 45 | GlobalSection(SolutionProperties) = preSolution 46 | HideSolutionNode = FALSE 47 | EndGlobalSection 48 | GlobalSection(ExtensibilityGlobals) = postSolution 49 | SolutionGuid = {789A7E5E-DBBC-489E-AEF3-7C7A59DD8E9D} 50 | EndGlobalSection 51 | EndGlobal 52 | -------------------------------------------------------------------------------- /GraphTutorial/HomePage.xaml: -------------------------------------------------------------------------------- 1 |  3 | 4 | 13 | 14 | 15 | 16 | 17 | Microsoft Graph UWP Tutorial 18 | Please sign in to continue. 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /GraphTutorial/HomePage.xaml.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Windows.UI.Xaml.Controls; 5 | 6 | // The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238 7 | 8 | namespace GraphTutorial 9 | { 10 | /// 11 | /// An empty page that can be used on its own or navigated to within a Frame. 12 | /// 13 | public sealed partial class HomePage : Page 14 | { 15 | // 16 | public HomePage() 17 | { 18 | this.InitializeComponent(); 19 | 20 | if ((App.Current as App).IsAuthenticated) 21 | { 22 | HomePageMessage.Text = "Welcome! Please use the menu to the left to select a view."; 23 | } 24 | } 25 | // 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /GraphTutorial/MainPage.xaml: -------------------------------------------------------------------------------- 1 |  3 | 4 | 5 | 16 | 17 | 18 | 22 | 23 | 24 | 28 | 29 | 30 | 31 | 35 | 36 | 37 | 38 | 39 | 43 | 44 | 45 | 46 | 47 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /GraphTutorial/MainPage.xaml.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using CommunityToolkit.Authentication; 5 | using Microsoft.Identity.Client; 6 | using Windows.UI.Xaml; 7 | using Windows.UI.Xaml.Controls; 8 | 9 | // The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 10 | 11 | namespace GraphTutorial 12 | { 13 | /// 14 | /// An empty page that can be used on its own or navigated to within a Frame. 15 | /// 16 | public sealed partial class MainPage : Page 17 | { 18 | // 19 | public MainPage() 20 | { 21 | this.InitializeComponent(); 22 | 23 | // Load OAuth settings 24 | var oauthSettings = Windows.ApplicationModel.Resources.ResourceLoader.GetForCurrentView("OAuth"); 25 | var appId = oauthSettings.GetString("AppId"); 26 | var scopes = oauthSettings.GetString("Scopes"); 27 | 28 | if (string.IsNullOrEmpty(appId) || string.IsNullOrEmpty(scopes)) 29 | { 30 | Notification.Show("Could not load OAuth Settings from resource file."); 31 | } 32 | else 33 | { 34 | // Configure MSAL provider 35 | var msalClient = PublicClientApplicationBuilder.Create(appId) 36 | .WithRedirectUri("https://login.microsoftonline.com/common/oauth2/nativeclient") 37 | .Build(); 38 | ProviderManager.Instance.GlobalProvider = new MsalProvider(msalClient, scopes.Split(' ')); 39 | 40 | // Handle auth state change 41 | ProviderManager.Instance.ProviderStateChanged += ProviderUpdated; 42 | 43 | // Navigate to HomePage.xaml 44 | RootFrame.Navigate(typeof(HomePage)); 45 | } 46 | } 47 | // 48 | 49 | // 50 | private void ProviderUpdated(object sender, ProviderStateChangedEventArgs e) 51 | { 52 | var globalProvider = ProviderManager.Instance.GlobalProvider; 53 | SetAuthState(globalProvider != null && globalProvider.State == ProviderState.SignedIn); 54 | RootFrame.Navigate(typeof(HomePage)); 55 | } 56 | // 57 | 58 | // 59 | private void SetAuthState(bool isAuthenticated) 60 | { 61 | (Application.Current as App).IsAuthenticated = isAuthenticated; 62 | 63 | // Toggle controls that require auth 64 | Calendar.IsEnabled = isAuthenticated; 65 | NewEvent.IsEnabled = isAuthenticated; 66 | } 67 | // 68 | 69 | private void NavView_ItemInvoked(NavigationView sender, NavigationViewItemInvokedEventArgs args) 70 | { 71 | var invokedItem = args.InvokedItem as string; 72 | 73 | switch (invokedItem.ToLower()) 74 | { 75 | case "new event": 76 | RootFrame.Navigate(typeof(NewEventPage)); 77 | break; 78 | case "calendar": 79 | RootFrame.Navigate(typeof(CalendarPage)); 80 | break; 81 | case "home": 82 | default: 83 | RootFrame.Navigate(typeof(HomePage)); 84 | break; 85 | } 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /GraphTutorial/NewEventPage.xaml: -------------------------------------------------------------------------------- 1 |  3 | 4 | 5 | 13 | 14 | 15 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 32 | 36 | 40 | 45 | 46 | 53 |