diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 14fe6178110..ee7279502fa 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -38,7 +38,10 @@ What kind of change does this PR introduce? Please check if your PR fulfills the following requirements: - [ ] Tested code with current [supported SDKs](../#supported) -- [ ] Pull Request has been submitted to the documentation repository [instructions](../blob/main/Contributing.md#docs). Link: +- [ ] New component + - [ ] Pull Request has been submitted to the documentation repository [instructions](../blob/main/Contributing.md#docs). Link: + - [ ] Added description of major feature to project description for NuGet package (4000 total character limit, so don't push entire description over that) + - [ ] If control, added to Visual Studio Design project - [ ] Sample in sample app has been added / updated (for bug fixes / features) - [ ] Icon has been created (if new sample) following the [Thumbnail Style Guide and templates](https://github.com/CommunityToolkit/WindowsCommunityToolkit-design-assets) - [ ] New major technical changes in the toolkit have or will be added to the [Wiki](https://github.com/CommunityToolkit/WindowsCommunityToolkit/wiki) e.g. build changes, source generators, testing infrastructure, sample creation changes, etc... @@ -51,4 +54,4 @@ Please note that breaking changes are likely to be rejected within minor release ## Other information - \ No newline at end of file + diff --git a/Microsoft.Toolkit.Mvvm.SourceGenerators/AnalyzerReleases.Unshipped.md b/Microsoft.Toolkit.Mvvm.SourceGenerators/AnalyzerReleases.Unshipped.md index b27b97bcbc6..09be8eafd5f 100644 --- a/Microsoft.Toolkit.Mvvm.SourceGenerators/AnalyzerReleases.Unshipped.md +++ b/Microsoft.Toolkit.Mvvm.SourceGenerators/AnalyzerReleases.Unshipped.md @@ -17,3 +17,4 @@ MVVMTK0009 | Microsoft.Toolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator MVVMTK0010 | Microsoft.Toolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator | Error | See https://aka.ms/mvvmtoolkit/error MVVMTK0011 | Microsoft.Toolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator | Error | See https://aka.ms/mvvmtoolkit/error MVVMTK0012 | Microsoft.Toolkit.Mvvm.SourceGenerators.ICommandGenerator | Error | See https://aka.ms/mvvmtoolkit/error +MVVMTK0013 | Microsoft.CodeAnalysis.CSharp.CSharpParseOptions | Error | See https://aka.ms/mvvmtoolkit/error diff --git a/Microsoft.Toolkit.Mvvm.SourceGenerators/ComponentModel/ObservablePropertyGenerator.cs b/Microsoft.Toolkit.Mvvm.SourceGenerators/ComponentModel/ObservablePropertyGenerator.cs index e5b9402e042..af3d2e43222 100644 --- a/Microsoft.Toolkit.Mvvm.SourceGenerators/ComponentModel/ObservablePropertyGenerator.cs +++ b/Microsoft.Toolkit.Mvvm.SourceGenerators/ComponentModel/ObservablePropertyGenerator.cs @@ -41,6 +41,15 @@ public void Execute(GeneratorExecutionContext context) return; } + // Validate the language version. Note that we're emitting this diagnostic in each generator (excluding the one + // only emitting the nullability annotation attributes if missing) so that the diagnostic is emitted only when + // users are using one of these generators, and not by default as soon as they add a reference to the MVVM Toolkit. + // This ensures that users not using any of the source generators won't be broken when upgrading to this new version. + if (context.ParseOptions is not CSharpParseOptions { LanguageVersion: >= LanguageVersion.CSharp9 }) + { + context.ReportDiagnostic(Diagnostic.Create(UnsupportedCSharpLanguageVersionError, null)); + } + // Sets of discovered property names HashSet propertyChangedNames = new(), @@ -240,6 +249,14 @@ private static PropertyDeclarationSyntax CreatePropertyDeclaration( } } + // In case the backing field is exactly named "value", we need to add the "this." prefix to ensure that comparisons and assignments + // with it in the generated setter body are executed correctly and without conflicts with the implicit value parameter. + ExpressionSyntax fieldExpression = fieldSymbol.Name switch + { + "value" => MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, ThisExpression(), IdentifierName("value")), + string name => IdentifierName(name) + }; + BlockSyntax setterBlock; if (validationAttributes.Count > 0) @@ -263,10 +280,10 @@ private static PropertyDeclarationSyntax CreatePropertyDeclaration( // Generate the inner setter block as follows: // - // if (!global::System.Collections.Generic.EqualityComparer<>.Default.Equals(, value)) + // if (!global::System.Collections.Generic.EqualityComparer<>.Default.Equals(this., value)) // { // OnPropertyChanging(global::Microsoft.Toolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedOrChangingArgs.PropertyNamePropertyChangingEventArgs); // Optional - // = value; + // this. = value; // OnPropertyChanged(global::Microsoft.Toolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedOrChangingArgs.PropertyNamePropertyChangedEventArgs); // ValidateProperty(value, ); // OnPropertyChanged(global::Microsoft.Toolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedOrChangingArgs.Property1PropertyChangedEventArgs); // Optional @@ -291,7 +308,7 @@ private static PropertyDeclarationSyntax CreatePropertyDeclaration( IdentifierName("Default")), IdentifierName("Equals"))) .AddArgumentListArguments( - Argument(IdentifierName(fieldSymbol.Name)), + Argument(fieldExpression), Argument(IdentifierName("value")))), Block( ExpressionStatement( @@ -303,7 +320,7 @@ private static PropertyDeclarationSyntax CreatePropertyDeclaration( ExpressionStatement( AssignmentExpression( SyntaxKind.SimpleAssignmentExpression, - IdentifierName(fieldSymbol.Name), + fieldExpression, IdentifierName("value"))), ExpressionStatement( InvocationExpression(IdentifierName("OnPropertyChanged")) @@ -346,7 +363,7 @@ private static PropertyDeclarationSyntax CreatePropertyDeclaration( ExpressionStatement( AssignmentExpression( SyntaxKind.SimpleAssignmentExpression, - IdentifierName(fieldSymbol.Name), + fieldExpression, IdentifierName("value"))), ExpressionStatement( InvocationExpression(IdentifierName("OnPropertyChanged")) @@ -384,7 +401,7 @@ private static PropertyDeclarationSyntax CreatePropertyDeclaration( IdentifierName("Default")), IdentifierName("Equals"))) .AddArgumentListArguments( - Argument(IdentifierName(fieldSymbol.Name)), + Argument(fieldExpression), Argument(IdentifierName("value")))), updateAndNotificationBlock)); } diff --git a/Microsoft.Toolkit.Mvvm.SourceGenerators/ComponentModel/ObservableValidatorValidateAllPropertiesGenerator.cs b/Microsoft.Toolkit.Mvvm.SourceGenerators/ComponentModel/ObservableValidatorValidateAllPropertiesGenerator.cs index 45a6bb3d449..b1849b515bd 100644 --- a/Microsoft.Toolkit.Mvvm.SourceGenerators/ComponentModel/ObservableValidatorValidateAllPropertiesGenerator.cs +++ b/Microsoft.Toolkit.Mvvm.SourceGenerators/ComponentModel/ObservableValidatorValidateAllPropertiesGenerator.cs @@ -14,6 +14,7 @@ using Microsoft.CodeAnalysis.Text; using Microsoft.Toolkit.Mvvm.SourceGenerators.Extensions; using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory; +using static Microsoft.Toolkit.Mvvm.SourceGenerators.Diagnostics.DiagnosticDescriptors; namespace Microsoft.Toolkit.Mvvm.SourceGenerators { @@ -39,6 +40,12 @@ public void Execute(GeneratorExecutionContext context) return; } + // Validate the language version + if (context.ParseOptions is not CSharpParseOptions { LanguageVersion: >= LanguageVersion.CSharp9 }) + { + context.ReportDiagnostic(Diagnostic.Create(UnsupportedCSharpLanguageVersionError, null)); + } + // Get the symbol for the ValidationAttribute type INamedTypeSymbol validationSymbol = context.Compilation.GetTypeByMetadataName("System.ComponentModel.DataAnnotations.ValidationAttribute")!; diff --git a/Microsoft.Toolkit.Mvvm.SourceGenerators/ComponentModel/TransitiveMembersGenerator.cs b/Microsoft.Toolkit.Mvvm.SourceGenerators/ComponentModel/TransitiveMembersGenerator.cs index bd3f48e284c..6c848347727 100644 --- a/Microsoft.Toolkit.Mvvm.SourceGenerators/ComponentModel/TransitiveMembersGenerator.cs +++ b/Microsoft.Toolkit.Mvvm.SourceGenerators/ComponentModel/TransitiveMembersGenerator.cs @@ -18,6 +18,7 @@ using Microsoft.Toolkit.Mvvm.SourceGenerators.Extensions; using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory; using static Microsoft.CodeAnalysis.SymbolDisplayTypeQualificationStyle; +using static Microsoft.Toolkit.Mvvm.SourceGenerators.Diagnostics.DiagnosticDescriptors; namespace Microsoft.Toolkit.Mvvm.SourceGenerators { @@ -67,6 +68,12 @@ public void Execute(GeneratorExecutionContext context) return; } + // Validate the language version + if (context.ParseOptions is not CSharpParseOptions { LanguageVersion: >= LanguageVersion.CSharp9 }) + { + context.ReportDiagnostic(Diagnostic.Create(UnsupportedCSharpLanguageVersionError, null)); + } + // Load the syntax tree with the members to generate SyntaxTree sourceSyntaxTree = LoadSourceSyntaxTree(); diff --git a/Microsoft.Toolkit.Mvvm.SourceGenerators/Diagnostics/DiagnosticDescriptors.cs b/Microsoft.Toolkit.Mvvm.SourceGenerators/Diagnostics/DiagnosticDescriptors.cs index 81fa09ee7ee..52ab2c33079 100644 --- a/Microsoft.Toolkit.Mvvm.SourceGenerators/Diagnostics/DiagnosticDescriptors.cs +++ b/Microsoft.Toolkit.Mvvm.SourceGenerators/Diagnostics/DiagnosticDescriptors.cs @@ -4,6 +4,7 @@ using System.ComponentModel; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; namespace Microsoft.Toolkit.Mvvm.SourceGenerators.Diagnostics { @@ -201,7 +202,23 @@ internal static class DiagnosticDescriptors category: typeof(ICommandGenerator).FullName, defaultSeverity: DiagnosticSeverity.Error, isEnabledByDefault: true, - description: $"Cannot apply [ICommand] to methods with a signature that doesn't match any of the existing relay command types.", + description: "Cannot apply [ICommand] to methods with a signature that doesn't match any of the existing relay command types.", + helpLinkUri: "https://aka.ms/mvvmtoolkit"); + + /// + /// Gets a indicating when an unsupported C# language version is being used. + /// + /// Format: "The method {0}.{1} cannot be used to generate a command property, as its signature isn't compatible with any of the existing relay command types". + /// + /// + public static readonly DiagnosticDescriptor UnsupportedCSharpLanguageVersionError = new( + id: "MVVMTK0013", + title: "Unsupported C# language version", + messageFormat: "The source generator features from the MVVM Toolkit require consuming projects to set the C# language version to at least C# 9.0", + category: typeof(CSharpParseOptions).FullName, + defaultSeverity: DiagnosticSeverity.Error, + isEnabledByDefault: true, + description: "The source generator features from the MVVM Toolkit require consuming projects to set the C# language version to at least C# 9.0. Make sure to add 9.0 (or above) to your .csproj file.", helpLinkUri: "https://aka.ms/mvvmtoolkit"); } } diff --git a/Microsoft.Toolkit.Mvvm.SourceGenerators/Input/ICommandGenerator.cs b/Microsoft.Toolkit.Mvvm.SourceGenerators/Input/ICommandGenerator.cs index ffcca24f30a..9095f93f36c 100644 --- a/Microsoft.Toolkit.Mvvm.SourceGenerators/Input/ICommandGenerator.cs +++ b/Microsoft.Toolkit.Mvvm.SourceGenerators/Input/ICommandGenerator.cs @@ -43,6 +43,12 @@ public void Execute(GeneratorExecutionContext context) return; } + // Validate the language version + if (context.ParseOptions is not CSharpParseOptions { LanguageVersion: >= LanguageVersion.CSharp9 }) + { + context.ReportDiagnostic(Diagnostic.Create(UnsupportedCSharpLanguageVersionError, null)); + } + foreach (var items in syntaxReceiver.GatheredInfo.GroupBy(static item => item.MethodSymbol.ContainingType, SymbolEqualityComparer.Default)) { if (items.Key.DeclaringSyntaxReferences.Length > 0 && diff --git a/Microsoft.Toolkit.Mvvm.SourceGenerators/Messaging/IMessengerRegisterAllGenerator.cs b/Microsoft.Toolkit.Mvvm.SourceGenerators/Messaging/IMessengerRegisterAllGenerator.cs index 91e4925dd99..9faeecf3ac5 100644 --- a/Microsoft.Toolkit.Mvvm.SourceGenerators/Messaging/IMessengerRegisterAllGenerator.cs +++ b/Microsoft.Toolkit.Mvvm.SourceGenerators/Messaging/IMessengerRegisterAllGenerator.cs @@ -13,6 +13,7 @@ using Microsoft.CodeAnalysis.Text; using Microsoft.Toolkit.Mvvm.SourceGenerators.Extensions; using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory; +using static Microsoft.Toolkit.Mvvm.SourceGenerators.Diagnostics.DiagnosticDescriptors; namespace Microsoft.Toolkit.Mvvm.SourceGenerators { @@ -38,6 +39,12 @@ public void Execute(GeneratorExecutionContext context) return; } + // Validate the language version + if (context.ParseOptions is not CSharpParseOptions { LanguageVersion: >= LanguageVersion.CSharp9 }) + { + context.ReportDiagnostic(Diagnostic.Create(UnsupportedCSharpLanguageVersionError, null)); + } + // Get the symbol for the IRecipient interface type INamedTypeSymbol iRecipientSymbol = context.Compilation.GetTypeByMetadataName("Microsoft.Toolkit.Mvvm.Messaging.IRecipient`1")!; diff --git a/Microsoft.Toolkit.Uwp.Notifications/readme.md b/Microsoft.Toolkit.Uwp.Notifications/ReadMe.md similarity index 100% rename from Microsoft.Toolkit.Uwp.Notifications/readme.md rename to Microsoft.Toolkit.Uwp.Notifications/ReadMe.md diff --git a/Microsoft.Toolkit.Uwp.SampleApp/Assets/mtns.csv b/Microsoft.Toolkit.Uwp.SampleApp/Assets/mtns.csv index 7b7568567d7..2f7eb6fee3d 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/Assets/mtns.csv +++ b/Microsoft.Toolkit.Uwp.SampleApp/Assets/mtns.csv @@ -1,117 +1,117 @@ -1,Mount Everest,8848,Mahalangur Himalaya,27d59m17sN 86d55m31sE,8848,none,1953,>>145 (121) -2,K2/Qogir,8611,Baltoro Karakoram,35d52m53sN 76d30m48sE,4017,Mount Everest,1954,45 (44) -3,Kangchenjunga,8586,Kangchenjunga Himalaya,27d42m12sN 88d08m51sE *,3922,Mount Everest,1955,38 (24) -4,Lhotse,8516,Mahalangur Himalaya,27d57m42sN 86d55m59sE,610,Mount Everest,1956,26 (26) -5,Makalu,8485,Mahalangur Himalaya,27d53m23sN 87d5m20sE,2386,Mount Everest,1955,45 (52) -6,Cho Oyu,8188,Mahalangur Himalaya,28d05m39sN 86d39m39sE,2340,Mount Everest,1954,79 (28) -7,Dhaulagiri I,8167,Dhaulagiri Himalaya,28d41m48sN 83d29m35sE,3357,K2,1960,51 (39) -8,Manaslu,8163,Manaslu Himalaya,28d33m00sN 84d33m35sE,3092,Cho Oyu,1956,49 (45) -9,Nanga Parbat,8126,Nanga Parbat Himalaya,35d14m14sN 74d35m21sE,4608,Dhaulagiri,1953,52 (67) -10,Annapurna I,8091,Annapurna Himalaya,28d35m44sN 83d49m13sE,2984,Cho Oyu,1950,36 (47) -11,Gasherbrum I,8080,Baltoro Karakoram,35d43m28sN 76d41m47sE,2155,K2,1958,31 (16) -12,Broad Peak/K3,8051,Baltoro Karakoram,35d48m38sN 76d34m06sE,1701,Gasherbrum I,1957,39 (19) -13,Gasherbrum II/K4,8034,Baltoro Karakoram,35d45m28sN 76d39m12sE,1523,Gasherbrum I,1956,54 (12) -14,Shishapangma,8027,Jugal Himalaya,28d21m12sN 85d46m43sE,2897,Cho Oyu,1964,43 (19) -15,Gyachung Kang,7952,Mahalangur Himalaya,28d05m53sN 86d44m42sE,700,Cho Oyu,1964,5 (3) -15,Gasherbrum III,7946,Baltoro Karakoram,35d45m33sN 76d38m30sE,355,Gasherbrum II,1975,2 (2) -16,Annapurna II,7937,Annapurna Himalaya,28d32m05sN 84d07m19sE,2437,Annapurna I,1960,6 (19) -17,Gasherbrum IV,7932,Baltoro Karakoram,35d45m38sN 76d36m58sE,715,Gasherbrum III,1958,4 (11) -18,Himalchuli,7893,Manaslu Himalaya,28d26m12sN 84d38m23sE *,1633,Manaslu,1960,6 (12) -19,Distaghil Sar,7884,Hispar Karakoram,36d19m33sN 75d11m16sE,2525,K2,1960,3 (5) -20,Ngadi Chuli,7871,Manaslu Himalaya,28d30m12sN 84d34m00sE,1020,Manaslu,1970,2 (6) -20,Nuptse,7864,Mahalangur Himalaya,27d58m03sN 86d53m13sE,319,Lhotse,1961,5 (12) -21,Khunyang Chhish,7823,Hispar Karakoram,36d12m19sN 75d12m28sE *,1765,Distaghil Sar,1971,2 (6) -22,Masherbrum/K1,7821,Masherbrum Karakoram,35d38m28sN 76d18m21sE,2457,Gasherbrum I,1960,4 (9) -23,Nanda Devi,7816,Garhwal Himalaya,30d22m33sN 79d58m15sE,3139,Dhaulagiri,1936,14 (12) -24,Chomo Lonzo,7804,Mahalangur Himalaya,27d55m50sN 87d06m28sE,590,Makalu,1954,3 (1) -25,Batura Sar,7795,Batura Karakoram,36d30m37sN 74d31m21sE,3118,Distaghil Sar,1976,4 (6) -26,Kanjut Sar,7790,Hispar Karakoram,36d12m20sN 75d25m01sE,1690,Khunyang Chhish,1959,2 (1) -27,Rakaposhi,7788,Rakaposhi-Haramosh Karakoram,36d08m33sN 74d29m22sE,2818,Khunyang Chhish,1958,8 (13) -28,Namcha Barwa,7782,Assam Himalaya,29d37m52sN 95d03m19sE,4106,Kangchenjunga,1992,1 (2) -29,Kamet,7756,Garhwal Himalaya,30d55m12sN 79d35m30sE *,2825,Nanda Devi,1931,23 (14) -30,Dhaulagiri II,7751,Dhaulagiri Himalaya,28d45m46sN 83d23m18sE,2396,Dhaulagiri,1971,4 (11) -31,Saltoro Kangri/K10,7742,Saltoro Karakoram,35d23m57sN 76d50m53sE *,2160,Gasherbrum I,1962,2 (1) -32,Jannu,7711,Kangchenjunga Himalaya,27d40m56sN 88d02m40sE *,1036,Kangchenjunga,1962,17 (12) -33,Tirich Mir,7708,Hindu Kush,36d15m19sN 71d50m30sE *,3910,Batura Sar,1950,20 (11) -33,Molamenqing,7703,Langtang Himalaya,28d21m18sN 85d48m35sE,430,Shishapangma,1981,1 (0) -34,Gurla Mandhata,7694,Nalakankar Himalaya,30d26m19sN 81d17m48sE,2788,Dhaulagiri,1985,6 (4) -35,Saser Kangri I/K22,7672,Saser Karakoram,34d52m00sN 77d45m09sE,2304,Gasherbrum I,1973,6 (4) -36,Chogolisa,7665,Masherbrum Karakoram,35d36m47sN 76d34m29sE,1624,Masherbrum,1975,4 (2) -36,Dhaulagiri IV,7661,Dhaulagiri Himalaya,28d44m09sN 83d18m55sE,469,Dhaulagiri II,1975,2 (10) -37,Kongur Tagh,7649,Kongur Shan Kunlun,38d35m36sN 75d18m48sE,3585,Distaghil Sar,1981,2 (4) -37,Dhaulagiri V,7618,Dhaulagiri Himalaya,28d44m02sN 83d21m41sE *,340,Dhaulagiri IV,1975,2 (3) -38,Shispare,7611,Batura Karakoram,36d26m26sN 74d40m51sE,1240,Batura Sar,1974,3 (1) -39,Trivor,7577,Hispar Karakoram,36d17m15sN 75d05m06sE *,980,Distaghil Sar,1960,2 (5) -40,Gangkhar Puensum,7570,Kula Kangri Himalaya,28d02m50sN 90d27m19sE *,2995,Kangchenjunga,0,0 (3) -41,Gongga Shan,7556,Daxue Shan,29d35m43sN 101d52m47sE,3642,Mount Everest,1932,6 (7) -42,Annapurna III,7555,Annapurna Himalaya,28d35m06sN 83d59m24sE,703,Annapurna I,1961,10 (17) -43,Muztagh Ata,7546,Muztagata Kunlun,38d16m33sN 75d06m58sE,2735,Kongur Tagh,1956,Many -44,Skyang Kangri,7545,Baltoro Karakoram,35d55m35sN 76d34m03sE,1085,K2,1976,1 (2) -45,Changtse,7543,Mahalangur Himalaya,28d01m29sN 86d54m51sE,520,Mount Everest,1982,9 (9) -46,Kula Kangri,7538,Kula Kangri Himalaya,28d13m37sN 90d36m59sE,1650,Gangkhar Puensum,1986,3 (2) -47,Kongur Tiube,7530,Kongur Shan Kunlun,38d36m57sN 75d11m45sE,840,Kongur Tagh,1956,2 (3) -48,Mamostong Kangri,7516,Rimo Karakoram,35d08m31sN 77d34m39sE,1803,Gasherbrum I,1984,5 (0) -49,Saser Kangri II E,7513,Saser Karakoram,34d48m17sN 77d48m24sE,1450,Saser Kangri I,2011,0 (0)[10] -50,Ismoil Somoni Peak,7495,Pamir (Akademiya Nauk Range),38d56m35sN 72d00m57sE,3402,Muztagh Ata,1933, -51,Saser Kangri III,7495,Saser Karakoram,34d50m44sN 77d47m06sE,850,Saser Kangri I,1986,1 (0) -52,Noshaq,7492,Hindu Kush,36d25m56sN 71d49m43sE,2024,Tirich Mir,1960,33 (3) -53,Pumari Chhish,7492,Hispar Karakoram,36d12m41sN 75d15m01sE,890,Khunyang Chhish,1979,1 (2) -54,Pasu Sar,7476,Batura Karakoram,36d29m16sN 74d35m16sE,645,Batura Sar,1994,1 (0) -55,Yukshin Gardan Sar,7469,Hispar Karakoram,36d15m04sN 75d22m29sE,1313,Pumari Chhish,1984,4 (1) -56,Teram Kangri I,7462,Siachen Karakoram,35d34m48sN 77d04m42sE,1702,Gasherbrum I,1975,2 (0) -57,Jongsong Peak,7462,Kangchenjunga Himalaya,27d52m54sN 88d08m09sE,1298,Kangchenjunga,1930,2 (3) -58,Malubiting,7458,Rakaposhi-Haramosh Karakoram,36d00m12sN 74d52m31sE,2193,Rakaposhi,1971,2 (6) -59,Gangapurna,7455,Annapurna Himalaya,28d36m18sN 83d57m49sE,563,Annapurna III,1965,8 (13) -60,Jengish Chokusu,7439,Tian Shan,42d02m05sN 80d07m47sE,4148,Ismail Samani Peak,1938, -61,K12,7428,Saltoro Karakoram,35d17m45sN 77d01m20sE,1978,Saltoro Kangri,1974,4 (2) -62,Yangra,7422,Ganesh Himalaya,28d23m29sN 85d07m38sE,2352,Manaslu,1955,1 (6) -63,Sia Kangri,7422,Siachen Karakoram,35d39m48sN 76d45m42sE,640,Gasherbrum I,1934,6 (0) -64,Momhil Sar,7414,Hispar Karakoram,36d19m04sN 75d02m11sE *,980,Trivor,1964,2 (6) -65,Kabru N,7412,Kangchenjunga Himalaya,27d38m02sN 88d07m00sE,780,Kangchenjunga,1994,1 (2)[11] -66,Skil Brum,7410,Baltoro Karakoram,35d51m03sN 76d25m43sE,1152,K2,1957,2 (1) -67,Haramosh,7409,Rakaposhi Karakoram,35d50m24sN 74d53m51sE,2277,Malubiting,1958,4 (3) -68,Istor-o-Nal,7403,Hindu Kush,36d22m32sN 71d53m54sE,1040,Noshaq,1969,4 (5) -69,Ghent Kangri,7401,Saltoro Karakoram,35d31m04sN 76d48m02sE,1493,Saltoro Kangri,1961,4 (0) -70,Ultar Sar,7388,Batura Karakoram,36d23m27sN 74d43m00sE,700,Shispare,1996,2 (5) -71,Rimo I,7385,Rimo Karakoram,35d21m18sN 77d22m08sE,1438,Teram Kangri I,1988,1 (3) -72,Churen Himal,7385,Dhaulagiri Himalaya,28d44m05sN 83d13m03sE,600,Dhaulagiri IV,1970,3 (0) -73,Teram Kangri III,7382,Siachen Karakoram,35d35m59sN 77d02m53sE,520,Teram Kangri I,1979,1 (0) -74,Sherpi Kangri,7380,Saltoro Karakoram,35d27m58sN 76d46m53sE *,1000,Ghent Kangri,1976,1 (1) -75,Labuche Kang,7367,Labuche Himalaya,28d18m15sN 86d21m03sE,1957,Cho Oyu,1987,1 (0) -76,Kirat Chuli,7362,Kangchenjunga Himalaya,27d47m16sN 88d11m43sE,1168,Kangchenjunga,1939,1 (6) -76,Abi Gamin,7355,Garhwal Himalaya,30d55m57sN 79d36m09sE,217,Kamet,1950,17 (2) -77,Nangpai Gosum,7350,Mahalangur Himalaya,28d04m24sN 86d36m51sE,500,Cho Oyu,1996,3 (1) -77,Gimmigela,7350,Kangchenjunga Himalaya,27d44m27sN 88d09m31sE,432,Kangchenjunga,1994,3 (1) -78,Saraghrar,7349,Hindu Kush,36d32m51sN 72d06m54sE,1979,Noshaq,1959,2 (3) -79,Jomolhari,7326,Jomolhari Himalaya,27d49m36sN 89d16m04sE *,2077,Gangkhar Puensum,1937,4 (0) -80,Chamlang,7321,Mahalangur Himalaya,27d46m30sN 86d58m47sE,1240,Lhotse,1961,7 (1) -81,Chongtar,7315,Baltoro Karakoram,35d54m55sN 76d25m45sE,1300,Skil Brum,1994,1 (1) -82,Baltoro Kangri,7312,Masherbrum Karakoram,35d38m21sN 76d40m24sE,1200,Chogolisa,1976,1 (0) -83,Siguang Ri,7309,Mahalangur Himalaya,28d08m50sN 86d41m06sE,650,Cho Oyu,1989,2 (1) -84,The Crown,7295,Yengisogat Karakoram,36d06m24sN 76d12m21sE,1919,Skil Brum (K2),1993,1 (3) -85,Gyala Peri,7294,Assam Himalaya,29d48m52sN 94d58m07sE,2942,Mount Everest,1986,1 (0) -86,Porong Ri,7292,Langtang Himalaya,28d23m22sN 85d43m12sE,520,Shisha Pangma,1982,5 (0) -87,Baintha Brakk,7285,Panmah Karakoram,35d56m51sN 75d45m12sE *,1891,Kanjut Sar,1977,3 (13) -88,Yutmaru Sar,7283,Hispar Karakoram,36d13m35sN 75d22m02sE,620,Yukshin Gardan Sar,1980,1 (1) -89,Baltistan Peak/K6,7282,Masherbrum Karakoram,35d25m06sN 76d33m06sE,1962,Chogolisa,1970,1 (3) -90,Kangpenqing,7281,Baiku Himalaya,28d33m03sN 85d32m44sE,1340,Shisha Pangma,1982,1 (1) -91,Muztagh Tower,7276,Baltoro Karakoram,35d49m40sN 76d21m40sE,1710,Skil Brum,1956,4 (2) -92,Mana,7272,Garhwal Himalaya,30d52m50sN 79d36m55sE,730,Kamet,1937,7 (3) -92,Dhaulagiri VI,7268,Dhaulagiri Himalaya,28d42m31sN 83d16m27sE,485,Dhaulagiri IV,1970,5 (0) -93,Diran,7266,Rakaposhi-Haramosh Karakoram,36d07m13sN 74d39m42sE,1325,Malubiting,1968,12 (8) -94,Labuche Kang III/East[12],7250,Labuche Himalaya,28d18m05sN 86d23m02sE,570,Labuche Kang,0,0 (0) -95,Putha Hiunchuli,7246,Dhaulagiri Himalaya,28d44m52sN 83d08m46sE,1151,Churen Himal,1954,11 (5) -96,Apsarasas Kangri,7245,Siachen Karakoram,35d32m19sN 77d08m55sE,635,Teram Kangri I,1976,2 (0) -97,Mukut Parbat,7242,Garhwal Himalaya,30d56m57sN 79d34m12sE,840,Kamet,1951,2 (1) -98,Rimo III,7233,Rimo Karakoram,35d22m31sN 77d21m42sE,615,Rimo I,1985,1 (0) -99,Langtang Lirung,7227,Langtang Himalaya,28d15m22sN 85d31m01sE,1525,Shisha Pangma,1978,14 (13) -100,Karjiang,7221,Kula Kangri Himalaya,28d15m27sN 90d38m49sE,880,Kula Kangri,0,0 (2) -101,Annapurna Dakshin,7219,Annapurna Himalaya,28d31m06sN 83d48m22sE,775,Annapurna,1964,10 (16) -102,Khartaphu,7213,Mahalangur Himalaya,28d03m49sN 86d58m39sE,712,Mount Everest,1935,1 (0) -103,Tongshanjiabu,7207,Lunana Himalaya,28d11m12sN 89d57m27sE,1757,Gangkar Puensum,0,0 (0) -104,Malangutti Sar,7207,Hispar Karakoram,36d21m47sN 75d08m57sE,515,Distaghil Sar,1985,1 (0) -105,Noijin Kangsang,7206,Nagarze Himalaya,28d56m48sN 90d10m42sE,2160,Tongshanjiabu,1986,4 (1) -106,Langtang Ri,7205,Langtang Himalaya,28d22m53sN 85d41m01sE,650,Porong Ri,1981,4 (0) -107,Kangphu Kang,7204,Lunana Himalaya,28d09m20sN 90d03m48sE,1200,Tongshanjiabu,2002,1 (0) -108,Singhi Kangri,7202,Siachen Karakoram,35d35m59sN 76d59m01sE,790,Teram Kangri III,1976,2 (0) -109,Lupghar Sar,7200,Hispar Karakoram,36d21m01sN 75d02m13sE *,730,Momhil Sar,1979,1 (0) +1,Mount Everest,8848,Mahalangur Himalaya,27d59m17sN 86d55m31sE,8848,none,05/29/1953,>>145 (121) +2,K2/Qogir,8611,Baltoro Karakoram,35d52m53sN 76d30m48sE,4017,Mount Everest,07/31/1954,45 (44) +3,Kangchenjunga,8586,Kangchenjunga Himalaya,27d42m12sN 88d08m51sE *,3922,Mount Everest,05/25/1955,38 (24) +4,Lhotse,8516,Mahalangur Himalaya,27d57m42sN 86d55m59sE,610,Mount Everest,05/18/1956,26 (26) +5,Makalu,8485,Mahalangur Himalaya,27d53m23sN 87d5m20sE,2386,Mount Everest,05/15/1955,45 (52) +6,Cho Oyu,8188,Mahalangur Himalaya,28d05m39sN 86d39m39sE,2340,Mount Everest,10/19/1954,79 (28) +7,Dhaulagiri I,8167,Dhaulagiri Himalaya,28d41m48sN 83d29m35sE,3357,K2,05/13/1960,51 (39) +8,Manaslu,8163,Manaslu Himalaya,28d33m00sN 84d33m35sE,3092,Cho Oyu,05/9/1956,49 (45) +9,Nanga Parbat,8126,Nanga Parbat Himalaya,35d14m14sN 74d35m21sE,4608,Dhaulagiri,07/03/1953,52 (67) +10,Annapurna I,8091,Annapurna Himalaya,28d35m44sN 83d49m13sE,2984,Cho Oyu,06/03/1950,36 (47) +11,Gasherbrum I,8080,Baltoro Karakoram,35d43m28sN 76d41m47sE,2155,K2,01/01/1958,31 (16) +12,Broad Peak/K3,8051,Baltoro Karakoram,35d48m38sN 76d34m06sE,1701,Gasherbrum I,01/01/1957,39 (19) +13,Gasherbrum II/K4,8034,Baltoro Karakoram,35d45m28sN 76d39m12sE,1523,Gasherbrum I,01/01/1956,54 (12) +14,Shishapangma,8027,Jugal Himalaya,28d21m12sN 85d46m43sE,2897,Cho Oyu,01/01/1964,43 (19) +15,Gyachung Kang,7952,Mahalangur Himalaya,28d05m53sN 86d44m42sE,700,Cho Oyu,01/01/1964,5 (3) +15,Gasherbrum III,7946,Baltoro Karakoram,35d45m33sN 76d38m30sE,355,Gasherbrum II,01/01/1975,2 (2) +16,Annapurna II,7937,Annapurna Himalaya,28d32m05sN 84d07m19sE,2437,Annapurna I,01/01/1960,6 (19) +17,Gasherbrum IV,7932,Baltoro Karakoram,35d45m38sN 76d36m58sE,715,Gasherbrum III,01/01/1958,4 (11) +18,Himalchuli,7893,Manaslu Himalaya,28d26m12sN 84d38m23sE *,1633,Manaslu,01/01/1960,6 (12) +19,Distaghil Sar,7884,Hispar Karakoram,36d19m33sN 75d11m16sE,2525,K2,01/01/1960,3 (5) +20,Ngadi Chuli,7871,Manaslu Himalaya,28d30m12sN 84d34m00sE,1020,Manaslu,01/01/1970,2 (6) +20,Nuptse,7864,Mahalangur Himalaya,27d58m03sN 86d53m13sE,319,Lhotse,01/01/1961,5 (12) +21,Khunyang Chhish,7823,Hispar Karakoram,36d12m19sN 75d12m28sE *,1765,Distaghil Sar,01/01/1971,2 (6) +22,Masherbrum/K1,7821,Masherbrum Karakoram,35d38m28sN 76d18m21sE,2457,Gasherbrum I,01/01/1960,4 (9) +23,Nanda Devi,7816,Garhwal Himalaya,30d22m33sN 79d58m15sE,3139,Dhaulagiri,01/01/1936,14 (12) +24,Chomo Lonzo,7804,Mahalangur Himalaya,27d55m50sN 87d06m28sE,590,Makalu,01/01/1954,3 (1) +25,Batura Sar,7795,Batura Karakoram,36d30m37sN 74d31m21sE,3118,Distaghil Sar,01/01/1976,4 (6) +26,Kanjut Sar,7790,Hispar Karakoram,36d12m20sN 75d25m01sE,1690,Khunyang Chhish,01/01/1959,2 (1) +27,Rakaposhi,7788,Rakaposhi-Haramosh Karakoram,36d08m33sN 74d29m22sE,2818,Khunyang Chhish,01/01/1958,8 (13) +28,Namcha Barwa,7782,Assam Himalaya,29d37m52sN 95d03m19sE,4106,Kangchenjunga,01/01/1992,1 (2) +29,Kamet,7756,Garhwal Himalaya,30d55m12sN 79d35m30sE *,2825,Nanda Devi,01/01/1931,23 (14) +30,Dhaulagiri II,7751,Dhaulagiri Himalaya,28d45m46sN 83d23m18sE,2396,Dhaulagiri,01/01/1971,4 (11) +31,Saltoro Kangri/K10,7742,Saltoro Karakoram,35d23m57sN 76d50m53sE *,2160,Gasherbrum I,01/01/1962,2 (1) +32,Jannu,7711,Kangchenjunga Himalaya,27d40m56sN 88d02m40sE *,1036,Kangchenjunga,01/01/1962,17 (12) +33,Tirich Mir,7708,Hindu Kush,36d15m19sN 71d50m30sE *,3910,Batura Sar,01/01/1950,20 (11) +33,Molamenqing,7703,Langtang Himalaya,28d21m18sN 85d48m35sE,430,Shishapangma,01/01/1981,1 (0) +34,Gurla Mandhata,7694,Nalakankar Himalaya,30d26m19sN 81d17m48sE,2788,Dhaulagiri,01/01/1985,6 (4) +35,Saser Kangri I/K22,7672,Saser Karakoram,34d52m00sN 77d45m09sE,2304,Gasherbrum I,01/01/1973,6 (4) +36,Chogolisa,7665,Masherbrum Karakoram,35d36m47sN 76d34m29sE,1624,Masherbrum,01/01/1975,4 (2) +36,Dhaulagiri IV,7661,Dhaulagiri Himalaya,28d44m09sN 83d18m55sE,469,Dhaulagiri II,01/01/1975,2 (10) +37,Kongur Tagh,7649,Kongur Shan Kunlun,38d35m36sN 75d18m48sE,3585,Distaghil Sar,01/01/1981,2 (4) +37,Dhaulagiri V,7618,Dhaulagiri Himalaya,28d44m02sN 83d21m41sE *,340,Dhaulagiri IV,01/01/1975,2 (3) +38,Shispare,7611,Batura Karakoram,36d26m26sN 74d40m51sE,1240,Batura Sar,01/01/1974,3 (1) +39,Trivor,7577,Hispar Karakoram,36d17m15sN 75d05m06sE *,980,Distaghil Sar,01/01/1960,2 (5) +40,Gangkhar Puensum,7570,Kula Kangri Himalaya,28d02m50sN 90d27m19sE *,2995,Kangchenjunga,01/01/1000,0 (3) +41,Gongga Shan,7556,Daxue Shan,29d35m43sN 101d52m47sE,3642,Mount Everest,01/01/1932,6 (7) +42,Annapurna III,7555,Annapurna Himalaya,28d35m06sN 83d59m24sE,703,Annapurna I,01/01/1961,10 (17) +43,Muztagh Ata,7546,Muztagata Kunlun,38d16m33sN 75d06m58sE,2735,Kongur Tagh,01/01/1956,Many +44,Skyang Kangri,7545,Baltoro Karakoram,35d55m35sN 76d34m03sE,1085,K2,01/01/1976,1 (2) +45,Changtse,7543,Mahalangur Himalaya,28d01m29sN 86d54m51sE,520,Mount Everest,01/01/1982,9 (9) +46,Kula Kangri,7538,Kula Kangri Himalaya,28d13m37sN 90d36m59sE,1650,Gangkhar Puensum,01/01/1986,3 (2) +47,Kongur Tiube,7530,Kongur Shan Kunlun,38d36m57sN 75d11m45sE,840,Kongur Tagh,01/01/1956,2 (3) +48,Mamostong Kangri,7516,Rimo Karakoram,35d08m31sN 77d34m39sE,1803,Gasherbrum I,01/01/1984,5 (0) +49,Saser Kangri II E,7513,Saser Karakoram,34d48m17sN 77d48m24sE,1450,Saser Kangri I,01/01/2011,0 (0)[10] +50,Ismoil Somoni Peak,7495,Pamir (Akademiya Nauk Range),38d56m35sN 72d00m57sE,3402,Muztagh Ata,01/01/1933, +51,Saser Kangri III,7495,Saser Karakoram,34d50m44sN 77d47m06sE,850,Saser Kangri I,01/01/1986,1 (0) +52,Noshaq,7492,Hindu Kush,36d25m56sN 71d49m43sE,2024,Tirich Mir,01/01/1960,33 (3) +53,Pumari Chhish,7492,Hispar Karakoram,36d12m41sN 75d15m01sE,890,Khunyang Chhish,01/01/1979,1 (2) +54,Pasu Sar,7476,Batura Karakoram,36d29m16sN 74d35m16sE,645,Batura Sar,01/01/1994,1 (0) +55,Yukshin Gardan Sar,7469,Hispar Karakoram,36d15m04sN 75d22m29sE,1313,Pumari Chhish,01/01/1984,4 (1) +56,Teram Kangri I,7462,Siachen Karakoram,35d34m48sN 77d04m42sE,1702,Gasherbrum I,01/01/1975,2 (0) +57,Jongsong Peak,7462,Kangchenjunga Himalaya,27d52m54sN 88d08m09sE,1298,Kangchenjunga,01/01/1930,2 (3) +58,Malubiting,7458,Rakaposhi-Haramosh Karakoram,36d00m12sN 74d52m31sE,2193,Rakaposhi,01/01/1971,2 (6) +59,Gangapurna,7455,Annapurna Himalaya,28d36m18sN 83d57m49sE,563,Annapurna III,01/01/1965,8 (13) +60,Jengish Chokusu,7439,Tian Shan,42d02m05sN 80d07m47sE,4148,Ismail Samani Peak,01/01/1938, +61,K12,7428,Saltoro Karakoram,35d17m45sN 77d01m20sE,1978,Saltoro Kangri,01/01/1974,4 (2) +62,Yangra,7422,Ganesh Himalaya,28d23m29sN 85d07m38sE,2352,Manaslu,01/01/1955,1 (6) +63,Sia Kangri,7422,Siachen Karakoram,35d39m48sN 76d45m42sE,640,Gasherbrum I,01/01/1934,6 (0) +64,Momhil Sar,7414,Hispar Karakoram,36d19m04sN 75d02m11sE *,980,Trivor,01/01/1964,2 (6) +65,Kabru N,7412,Kangchenjunga Himalaya,27d38m02sN 88d07m00sE,780,Kangchenjunga,01/01/1994,1 (2)[11] +66,Skil Brum,7410,Baltoro Karakoram,35d51m03sN 76d25m43sE,1152,K2,01/01/1957,2 (1) +67,Haramosh,7409,Rakaposhi Karakoram,35d50m24sN 74d53m51sE,2277,Malubiting,01/01/1958,4 (3) +68,Istor-o-Nal,7403,Hindu Kush,36d22m32sN 71d53m54sE,1040,Noshaq,01/01/1969,4 (5) +69,Ghent Kangri,7401,Saltoro Karakoram,35d31m04sN 76d48m02sE,1493,Saltoro Kangri,01/01/1961,4 (0) +70,Ultar Sar,7388,Batura Karakoram,36d23m27sN 74d43m00sE,700,Shispare,01/01/1996,2 (5) +71,Rimo I,7385,Rimo Karakoram,35d21m18sN 77d22m08sE,1438,Teram Kangri I,01/01/1988,1 (3) +72,Churen Himal,7385,Dhaulagiri Himalaya,28d44m05sN 83d13m03sE,600,Dhaulagiri IV,01/01/1970,3 (0) +73,Teram Kangri III,7382,Siachen Karakoram,35d35m59sN 77d02m53sE,520,Teram Kangri I,01/01/1979,1 (0) +74,Sherpi Kangri,7380,Saltoro Karakoram,35d27m58sN 76d46m53sE *,1000,Ghent Kangri,01/01/1976,1 (1) +75,Labuche Kang,7367,Labuche Himalaya,28d18m15sN 86d21m03sE,1957,Cho Oyu,01/01/1987,1 (0) +76,Kirat Chuli,7362,Kangchenjunga Himalaya,27d47m16sN 88d11m43sE,1168,Kangchenjunga,01/01/1939,1 (6) +76,Abi Gamin,7355,Garhwal Himalaya,30d55m57sN 79d36m09sE,217,Kamet,01/01/1950,17 (2) +77,Nangpai Gosum,7350,Mahalangur Himalaya,28d04m24sN 86d36m51sE,500,Cho Oyu,01/01/1996,3 (1) +77,Gimmigela,7350,Kangchenjunga Himalaya,27d44m27sN 88d09m31sE,432,Kangchenjunga,01/01/1994,3 (1) +78,Saraghrar,7349,Hindu Kush,36d32m51sN 72d06m54sE,1979,Noshaq,01/01/1959,2 (3) +79,Jomolhari,7326,Jomolhari Himalaya,27d49m36sN 89d16m04sE *,2077,Gangkhar Puensum,01/01/1937,4 (0) +80,Chamlang,7321,Mahalangur Himalaya,27d46m30sN 86d58m47sE,1240,Lhotse,01/01/1961,7 (1) +81,Chongtar,7315,Baltoro Karakoram,35d54m55sN 76d25m45sE,1300,Skil Brum,01/01/1994,1 (1) +82,Baltoro Kangri,7312,Masherbrum Karakoram,35d38m21sN 76d40m24sE,1200,Chogolisa,01/01/1976,1 (0) +83,Siguang Ri,7309,Mahalangur Himalaya,28d08m50sN 86d41m06sE,650,Cho Oyu,01/01/1989,2 (1) +84,The Crown,7295,Yengisogat Karakoram,36d06m24sN 76d12m21sE,1919,Skil Brum (K2),01/01/1993,1 (3) +85,Gyala Peri,7294,Assam Himalaya,29d48m52sN 94d58m07sE,2942,Mount Everest,01/01/1986,1 (0) +86,Porong Ri,7292,Langtang Himalaya,28d23m22sN 85d43m12sE,520,Shisha Pangma,01/01/1982,5 (0) +87,Baintha Brakk,7285,Panmah Karakoram,35d56m51sN 75d45m12sE *,1891,Kanjut Sar,01/01/1977,3 (13) +88,Yutmaru Sar,7283,Hispar Karakoram,36d13m35sN 75d22m02sE,620,Yukshin Gardan Sar,01/01/1980,1 (1) +89,Baltistan Peak/K6,7282,Masherbrum Karakoram,35d25m06sN 76d33m06sE,1962,Chogolisa,01/01/1970,1 (3) +90,Kangpenqing,7281,Baiku Himalaya,28d33m03sN 85d32m44sE,1340,Shisha Pangma,01/01/1982,1 (1) +91,Muztagh Tower,7276,Baltoro Karakoram,35d49m40sN 76d21m40sE,1710,Skil Brum,01/01/1956,4 (2) +92,Mana,7272,Garhwal Himalaya,30d52m50sN 79d36m55sE,730,Kamet,01/01/1937,7 (3) +92,Dhaulagiri VI,7268,Dhaulagiri Himalaya,28d42m31sN 83d16m27sE,485,Dhaulagiri IV,01/01/1970,5 (0) +93,Diran,7266,Rakaposhi-Haramosh Karakoram,36d07m13sN 74d39m42sE,1325,Malubiting,01/01/1968,12 (8) +94,Labuche Kang III/East[12],7250,Labuche Himalaya,28d18m05sN 86d23m02sE,570,Labuche Kang,01/01/1000,0 (0) +95,Putha Hiunchuli,7246,Dhaulagiri Himalaya,28d44m52sN 83d08m46sE,1151,Churen Himal,01/01/1954,11 (5) +96,Apsarasas Kangri,7245,Siachen Karakoram,35d32m19sN 77d08m55sE,635,Teram Kangri I,01/01/1976,2 (0) +97,Mukut Parbat,7242,Garhwal Himalaya,30d56m57sN 79d34m12sE,840,Kamet,01/01/1951,2 (1) +98,Rimo III,7233,Rimo Karakoram,35d22m31sN 77d21m42sE,615,Rimo I,01/01/1985,1 (0) +99,Langtang Lirung,7227,Langtang Himalaya,28d15m22sN 85d31m01sE,1525,Shisha Pangma,01/01/1978,14 (13) +100,Karjiang,7221,Kula Kangri Himalaya,28d15m27sN 90d38m49sE,880,Kula Kangri,01/01/1000,0 (2) +101,Annapurna Dakshin,7219,Annapurna Himalaya,28d31m06sN 83d48m22sE,775,Annapurna,01/01/1964,10 (16) +102,Khartaphu,7213,Mahalangur Himalaya,28d03m49sN 86d58m39sE,712,Mount Everest,01/01/1935,1 (0) +103,Tongshanjiabu,7207,Lunana Himalaya,28d11m12sN 89d57m27sE,1757,Gangkar Puensum,01/01/1000,0 (0) +104,Malangutti Sar,7207,Hispar Karakoram,36d21m47sN 75d08m57sE,515,Distaghil Sar,01/01/1985,1 (0) +105,Noijin Kangsang,7206,Nagarze Himalaya,28d56m48sN 90d10m42sE,2160,Tongshanjiabu,01/01/1986,4 (1) +106,Langtang Ri,7205,Langtang Himalaya,28d22m53sN 85d41m01sE,650,Porong Ri,01/01/1981,4 (0) +107,Kangphu Kang,7204,Lunana Himalaya,28d09m20sN 90d03m48sE,1200,Tongshanjiabu,01/01/2002,1 (0) +108,Singhi Kangri,7202,Siachen Karakoram,35d35m59sN 76d59m01sE,790,Teram Kangri III,01/01/1976,2 (0) +109,Lupghar Sar,7200,Hispar Karakoram,36d21m01sN 75d02m13sE *,730,Momhil Sar,01/01/1979,1 (0) diff --git a/Microsoft.Toolkit.Uwp.SampleApp/Common/Vector3Converter.cs b/Microsoft.Toolkit.Uwp.SampleApp/Common/Vector3Converter.cs new file mode 100644 index 00000000000..2aecfcbba28 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.SampleApp/Common/Vector3Converter.cs @@ -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; +using System.Linq; +using System.Numerics; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Data; + +namespace Microsoft.Toolkit.Uwp.SampleApp.Common +{ + public class Vector3Converter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, string language) + { + if (value is string) + { + return value; + } + + var thickness = (Vector3)value; + + return thickness.ToString().TrimStart('<').Replace(" ", string.Empty).TrimEnd('>'); + } + + public object ConvertBack(object value, Type targetType, object parameter, string language) + { + if (value is string vectorString) + { + var vectorTokens = vectorString.Split(',') + .Where(tkn => !string.IsNullOrWhiteSpace(tkn)) + .ToArray(); + switch (vectorTokens.Length) + { + case 1: + var vectorValue = float.Parse(vectorString); + return new Vector3(vectorValue); + case 2: + var xValue = float.Parse(vectorTokens[0]); + var yValue = float.Parse(vectorTokens[1]); + + return new Vector3(xValue, yValue, 0); + case 3: + return new Vector3( + float.Parse(vectorTokens[0]), + float.Parse(vectorTokens[1]), + float.Parse(vectorTokens[2])); + default: + return default(Vector3); + } + } + + return value.ToString(); + } + } +} \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.SampleApp/Controls/PropertyControl.xaml.cs b/Microsoft.Toolkit.Uwp.SampleApp/Controls/PropertyControl.xaml.cs index 51526c86135..e992f56166c 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/Controls/PropertyControl.xaml.cs +++ b/Microsoft.Toolkit.Uwp.SampleApp/Controls/PropertyControl.xaml.cs @@ -179,6 +179,14 @@ private void PropertyControl_OnDataContextChanged(FrameworkElement sender, DataC converter = new ThicknessConverter(); break; + case PropertyKind.Vector3: + var vectorTextBox = new TextBox { Text = (propertyDict[option.Name] as ValueHolder).Value.ToString() }; + + controlToAdd = vectorTextBox; + dependencyProperty = TextBox.TextProperty; + converter = new Vector3Converter(); + break; + default: var textBox = new TextBox { Text = (propertyDict[option.Name] as ValueHolder).Value.ToString() }; diff --git a/Microsoft.Toolkit.Uwp.SampleApp/Data/DataGridDataItem.cs b/Microsoft.Toolkit.Uwp.SampleApp/Data/DataGridDataItem.cs index f942f1f1fe5..f3d0bae93f2 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/Data/DataGridDataItem.cs +++ b/Microsoft.Toolkit.Uwp.SampleApp/Data/DataGridDataItem.cs @@ -149,7 +149,8 @@ public string Parent_mountain public uint Prominence { get; set; } - public uint First_ascent { get; set; } + // You need to use DateTimeOffset to get proper binding to the CalendarDatePicker control, DateTime won't work. + public DateTimeOffset First_ascent { get; set; } public string Ascents { get; set; } diff --git a/Microsoft.Toolkit.Uwp.SampleApp/Data/DataGridDataSource.cs b/Microsoft.Toolkit.Uwp.SampleApp/Data/DataGridDataSource.cs index 01cc02cb71e..688b172925f 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/Data/DataGridDataSource.cs +++ b/Microsoft.Toolkit.Uwp.SampleApp/Data/DataGridDataSource.cs @@ -48,8 +48,8 @@ public async Task> GetDataAsync() Coordinates = values[4], Prominence = uint.Parse(values[5]), Parent_mountain = values[6], - First_ascent = uint.Parse(values[7]), - Ascents = values[8] + First_ascent = DateTimeOffset.Parse(values[7]), + Ascents = values[8], }); } } diff --git a/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj b/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj index 9dddf4fb6b0..d48bda9a5a3 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj +++ b/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj @@ -111,7 +111,7 @@ --> - 2.6.1 + 2.6.2 0.7.0-alpha @@ -274,6 +274,7 @@ + @@ -315,10 +316,10 @@ - + - - + + @@ -397,7 +398,7 @@ - + @@ -488,6 +489,7 @@ + AutoFocusBehaviorPage.xaml @@ -506,6 +508,13 @@ MetadataControlPage.xaml + + AttachedDropShadowPage.xaml + + + RichSuggestBoxPage.xaml + + TilesBrushPage.xaml @@ -626,7 +635,11 @@ Designer + + + + @@ -663,7 +676,6 @@ UniformGridPage.xaml - SampleController.xaml @@ -809,9 +821,6 @@ DispatcherQueueHelperPage.xaml - - DropShadowPanelPage.xaml - ExpanderPage.xaml @@ -986,6 +995,18 @@ Designer + + MSBuild:Compile + Designer + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + MSBuild:Compile Designer @@ -1079,6 +1100,10 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + MSBuild:Compile Designer @@ -1269,10 +1294,6 @@ MSBuild:Compile Designer - - Designer - MSBuild:Compile - Designer MSBuild:Compile @@ -1541,4 +1562,4 @@ - \ No newline at end of file + diff --git a/Microsoft.Toolkit.Uwp.SampleApp/Models/PropertyDescriptor/PropertyKind.cs b/Microsoft.Toolkit.Uwp.SampleApp/Models/PropertyDescriptor/PropertyKind.cs index fcb07035933..f45876a6aae 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/Models/PropertyDescriptor/PropertyKind.cs +++ b/Microsoft.Toolkit.Uwp.SampleApp/Models/PropertyDescriptor/PropertyKind.cs @@ -13,6 +13,7 @@ public enum PropertyKind Bool, Brush, TimeSpan, - Thickness + Thickness, + Vector3, } } \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.SampleApp/Models/Sample.cs b/Microsoft.Toolkit.Uwp.SampleApp/Models/Sample.cs index 6e512819c70..e26a5076895 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/Models/Sample.cs +++ b/Microsoft.Toolkit.Uwp.SampleApp/Models/Sample.cs @@ -418,8 +418,12 @@ public string UpdatedXamlCode { if (proxy[option.Name] is ValueHolder value) { - var newString = value.Value is Windows.UI.Xaml.Media.SolidColorBrush brush ? - brush.Color.ToString() : value.Value.ToString(); + var newString = value.Value switch + { + Windows.UI.Xaml.Media.SolidColorBrush brush => brush.Color.ToString(), + System.Numerics.Vector3 vector => vector.ToString().TrimStart('<').Replace(" ", string.Empty).TrimEnd('>'), + _ => value.Value.ToString() + }; result = result.Replace(option.OriginalString, newString); result = result.Replace("@[" + option.Label + "]@", newString); @@ -630,12 +634,27 @@ public async Task PreparePropertyDescriptorAsync() case PropertyKind.Thickness: try { - var thicknessOptions = new ThicknessPropertyOptions { DefaultValue = value }; + var thicknessOptions = new PropertyOptions { DefaultValue = value }; options = thicknessOptions; } catch (Exception ex) { - Debug.WriteLine($"Unable to extract slider info from {value}({ex.Message})"); + Debug.WriteLine($"Unable to extract thickness info from {value}({ex.Message})"); + TrackingManager.TrackException(ex); + continue; + } + + break; + + case PropertyKind.Vector3: + try + { + var vector3Options = new PropertyOptions { DefaultValue = value }; + options = vector3Options; + } + catch (Exception ex) + { + Debug.WriteLine($"Unable to extract vector3 info from {value}({ex.Message})"); TrackingManager.TrackException(ex); continue; } diff --git a/Microsoft.Toolkit.Uwp.SampleApp/Models/Samples.cs b/Microsoft.Toolkit.Uwp.SampleApp/Models/Samples.cs index a05c2c19f22..8170fb9f29c 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/Models/Samples.cs +++ b/Microsoft.Toolkit.Uwp.SampleApp/Models/Samples.cs @@ -60,7 +60,8 @@ public static async Task> GetCategoriesAsync() { allCategories = await JsonSerializer.DeserializeAsync>(jsonStream.AsStream(), new JsonSerializerOptions { - ReadCommentHandling = JsonCommentHandling.Skip + ReadCommentHandling = JsonCommentHandling.Skip, + AllowTrailingCommas = true, }); } diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Effects/FadeBehaviorXaml.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Effects/FadeBehaviorXaml.bind index 1a0f0eb9081..faa19146253 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Effects/FadeBehaviorXaml.bind +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Effects/FadeBehaviorXaml.bind @@ -7,7 +7,6 @@ xmlns:interactions="using:Microsoft.Xaml.Interactions.Core" xmlns:ani="using:Microsoft.Toolkit.Uwp.UI.Animations" xmlns:behaviors="using:Microsoft.Toolkit.Uwp.UI.Behaviors" - xmlns:core="using:Microsoft.Xaml.Interactions.Core" mc:Ignorable="d"> + + diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ColorPicker/ColorPickerButtonXaml.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ColorPicker/ColorPickerButtonXaml.bind index 8a84e01b04e..939f067a2b3 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ColorPicker/ColorPickerButtonXaml.bind +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ColorPicker/ColorPickerButtonXaml.bind @@ -10,19 +10,11 @@ - - - - - - - - - + + - - - + - - - + - - - + + + + + Ring-shaped spectrum + Alpha channel enabled + Only Color Palette Shown + + + + + + + - + \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ColorPicker/ColorPickerXaml.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ColorPicker/ColorPickerXaml.bind index 59d3454d6c0..1502d4ad1f0 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ColorPicker/ColorPickerXaml.bind +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ColorPicker/ColorPickerXaml.bind @@ -60,7 +60,7 @@ Alpha channel enabled - - + + + + Ring-shaped spectrum + Alpha channel enabled + Only Color Palette Shown + + + \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/DataGrid/DataGridCode.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/DataGrid/DataGridCode.bind index 588589bf48d..874762b3798 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/DataGrid/DataGridCode.bind +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/DataGrid/DataGridCode.bind @@ -1,12 +1,14 @@ + @@ -85,7 +87,19 @@ + + + + + + + + + + + + - \ No newline at end of file + diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/DataGrid/DataGridPage.xaml b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/DataGrid/DataGridPage.xaml index 807dd5214e6..486f886a39f 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/DataGrid/DataGridPage.xaml +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/DataGrid/DataGridPage.xaml @@ -6,13 +6,5 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> - - - - - - - - - + \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/DataGrid/DataGridPage.xaml.cs b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/DataGrid/DataGridPage.xaml.cs index 5dfc2ff19d8..1b2c55a4829 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/DataGrid/DataGridPage.xaml.cs +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/DataGrid/DataGridPage.xaml.cs @@ -41,8 +41,9 @@ public async void OnXamlRendered(FrameworkElement control) dataGrid.Sorting += DataGrid_Sorting; dataGrid.LoadingRowGroup += DataGrid_LoadingRowGroup; dataGrid.ItemsSource = await viewModel.GetDataAsync(); + dataGrid.PreparingCellForEdit += DataGrid_PreparingCellForEdit; - var comboBoxColumn = dataGrid.Columns.FirstOrDefault(x => x.Tag.Equals("Mountain")) as DataGridComboBoxColumn; + var comboBoxColumn = dataGrid.Columns.FirstOrDefault(x => x.Tag?.Equals("Mountain") == true) as DataGridComboBoxColumn; if (comboBoxColumn != null) { comboBoxColumn.ItemsSource = await viewModel.GetMountains(); @@ -111,6 +112,15 @@ public async void OnXamlRendered(FrameworkElement control) } } + private void DataGrid_PreparingCellForEdit(object sender, DataGridPreparingCellForEditEventArgs e) + { + if (e.Column is DataGridTemplateColumn column && (string)column?.Tag == "First_ascent" && + e.EditingElement is CalendarDatePicker calendar) + { + calendar.IsCalendarOpen = true; + } + } + private void DataGrid_LoadingRowGroup(object sender, DataGridRowGroupHeaderEventArgs e) { ICollectionViewGroup group = e.RowGroupHeader.CollectionViewGroup; diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/DropShadowPanel/DropShadowPanelPage.xaml b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/DropShadowPanel/DropShadowPanelPage.xaml deleted file mode 100644 index 10d089fe69c..00000000000 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/DropShadowPanel/DropShadowPanelPage.xaml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/DropShadowPanel/DropShadowPanelPage.xaml.cs b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/DropShadowPanel/DropShadowPanelPage.xaml.cs deleted file mode 100644 index 0c6c06a95a6..00000000000 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/DropShadowPanel/DropShadowPanelPage.xaml.cs +++ /dev/null @@ -1,22 +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 Microsoft.Toolkit.Uwp.SampleApp.SamplePages -{ - /// - /// A page that shows how to use the DropShadowPanel control. - /// - public sealed partial class DropShadowPanelPage : Page - { - /// - /// Initializes a new instance of the class. - /// - public DropShadowPanelPage() - { - InitializeComponent(); - } - } -} \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/RichSuggestBox/RichSuggestBox.png b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/RichSuggestBox/RichSuggestBox.png new file mode 100644 index 00000000000..47e34d69c0c Binary files /dev/null and b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/RichSuggestBox/RichSuggestBox.png differ diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/RichSuggestBox/RichSuggestBoxCode.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/RichSuggestBox/RichSuggestBoxCode.bind new file mode 100644 index 00000000000..0c4e59518fa --- /dev/null +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/RichSuggestBox/RichSuggestBoxCode.bind @@ -0,0 +1,50 @@ +private void SuggestingBox_OnTokenPointerOver(RichSuggestBox sender, RichSuggestTokenPointerOverEventArgs args) +{ + var flyout = (Flyout)FlyoutBase.GetAttachedFlyout(sender); + var pointerPosition = args.CurrentPoint.Position; + + if (flyout?.Content is ContentPresenter cp && sender.TextDocument.Selection.Type != SelectionType.Normal && + (!flyout.IsOpen || cp.Content != args.Token.Item)) + { + this._dispatcherQueue.TryEnqueue(() => + { + cp.Content = args.Token.Item; + flyout.ShowAt(sender, new FlyoutShowOptions + { + Position = pointerPosition, + ExclusionRect = sender.GetRectFromRange(args.Range), + ShowMode = FlyoutShowMode.TransientWithDismissOnPointerMoveAway, + }); + }); + } +} + +private void SuggestingBox_OnSuggestionChosen(RichSuggestBox sender, SuggestionChosenEventArgs args) +{ + if (args.Prefix == "#") + { + args.Format.BackgroundColor = Colors.DarkOrange; + args.Format.ForegroundColor = Colors.OrangeRed; + args.Format.Bold = FormatEffect.On; + args.Format.Italic = FormatEffect.On; + args.DisplayText = ((SampleDataType)args.SelectedItem).Text; + } + else + { + args.DisplayText = ((SampleEmailDataType)args.SelectedItem).DisplayName; + } +} + +private void SuggestingBox_OnSuggestionRequested(RichSuggestBox sender, SuggestionRequestedEventArgs args) +{ + if (args.Prefix == "#") + { + sender.ItemsSource = + this._samples.Where(x => x.Text.Contains(args.QueryText, StringComparison.OrdinalIgnoreCase)); + } + else + { + sender.ItemsSource = + this._emailSamples.Where(x => x.DisplayName.Contains(args.QueryText, StringComparison.OrdinalIgnoreCase)); + } +} diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/RichSuggestBox/RichSuggestBoxPage.xaml b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/RichSuggestBox/RichSuggestBoxPage.xaml new file mode 100644 index 00000000000..a57d44b9576 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/RichSuggestBox/RichSuggestBoxPage.xaml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/RichSuggestBox/RichSuggestBoxPage.xaml.cs b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/RichSuggestBox/RichSuggestBoxPage.xaml.cs new file mode 100644 index 00000000000..20251c74c32 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/RichSuggestBox/RichSuggestBoxPage.xaml.cs @@ -0,0 +1,191 @@ +// 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.Collections.Generic; +using System.Linq; +using Microsoft.Toolkit.Uwp.UI; +using Microsoft.Toolkit.Uwp.UI.Controls; +using Windows.System; +using Windows.UI; +using Windows.UI.Text; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Controls.Primitives; + +namespace Microsoft.Toolkit.Uwp.SampleApp.SamplePages +{ + /// + /// An empty page that can be used on its own or navigated to within a Frame. + /// + public sealed partial class RichSuggestBoxPage : Page, IXamlRenderListener + { + private readonly List _emailSamples = new List() + { + new SampleEmailDataType() { FirstName = "Marcus", FamilyName = "Perryman" }, + new SampleEmailDataType() { FirstName = "Michael", FamilyName = "Hawker" }, + new SampleEmailDataType() { FirstName = "Matt", FamilyName = "Lacey" }, + new SampleEmailDataType() { FirstName = "Alexandre", FamilyName = "Chohfi" }, + new SampleEmailDataType() { FirstName = "Filip", FamilyName = "Wallberg" }, + new SampleEmailDataType() { FirstName = "Shane", FamilyName = "Weaver" }, + new SampleEmailDataType() { FirstName = "Vincent", FamilyName = "Gromfeld" }, + new SampleEmailDataType() { FirstName = "Sergio", FamilyName = "Pedri" }, + new SampleEmailDataType() { FirstName = "Alex", FamilyName = "Wilber" }, + new SampleEmailDataType() { FirstName = "Allan", FamilyName = "Deyoung" }, + new SampleEmailDataType() { FirstName = "Adele", FamilyName = "Vance" }, + new SampleEmailDataType() { FirstName = "Grady", FamilyName = "Archie" }, + new SampleEmailDataType() { FirstName = "Megan", FamilyName = "Bowen" }, + new SampleEmailDataType() { FirstName = "Ben", FamilyName = "Walters" }, + new SampleEmailDataType() { FirstName = "Debra", FamilyName = "Berger" }, + new SampleEmailDataType() { FirstName = "Emily", FamilyName = "Braun" }, + new SampleEmailDataType() { FirstName = "Christine", FamilyName = "Cline" }, + new SampleEmailDataType() { FirstName = "Enrico", FamilyName = "Catteneo" }, + new SampleEmailDataType() { FirstName = "Davit", FamilyName = "Badalyan" }, + new SampleEmailDataType() { FirstName = "Diego", FamilyName = "Siciliani" }, + new SampleEmailDataType() { FirstName = "Raul", FamilyName = "Razo" }, + new SampleEmailDataType() { FirstName = "Miriam", FamilyName = "Graham" }, + new SampleEmailDataType() { FirstName = "Lynne", FamilyName = "Robbins" }, + new SampleEmailDataType() { FirstName = "Lydia", FamilyName = "Holloway" }, + new SampleEmailDataType() { FirstName = "Nestor", FamilyName = "Wilke" }, + new SampleEmailDataType() { FirstName = "Patti", FamilyName = "Fernandez" }, + new SampleEmailDataType() { FirstName = "Pradeep", FamilyName = "Gupta" }, + new SampleEmailDataType() { FirstName = "Joni", FamilyName = "Sherman" }, + new SampleEmailDataType() { FirstName = "Isaiah", FamilyName = "Langer" }, + new SampleEmailDataType() { FirstName = "Irvin", FamilyName = "Sayers" }, + new SampleEmailDataType() { FirstName = "Tung", FamilyName = "Huynh" }, + }; + + private readonly List _samples = new List() + { + new SampleDataType() { Text = "Account", Icon = Symbol.Account }, + new SampleDataType() { Text = "Add Friend", Icon = Symbol.AddFriend }, + new SampleDataType() { Text = "Attach", Icon = Symbol.Attach }, + new SampleDataType() { Text = "Attach Camera", Icon = Symbol.AttachCamera }, + new SampleDataType() { Text = "Audio", Icon = Symbol.Audio }, + new SampleDataType() { Text = "Block Contact", Icon = Symbol.BlockContact }, + new SampleDataType() { Text = "Calculator", Icon = Symbol.Calculator }, + new SampleDataType() { Text = "Calendar", Icon = Symbol.Calendar }, + new SampleDataType() { Text = "Camera", Icon = Symbol.Camera }, + new SampleDataType() { Text = "Contact", Icon = Symbol.Contact }, + new SampleDataType() { Text = "Favorite", Icon = Symbol.Favorite }, + new SampleDataType() { Text = "Link", Icon = Symbol.Link }, + new SampleDataType() { Text = "Mail", Icon = Symbol.Mail }, + new SampleDataType() { Text = "Map", Icon = Symbol.Map }, + new SampleDataType() { Text = "Phone", Icon = Symbol.Phone }, + new SampleDataType() { Text = "Pin", Icon = Symbol.Pin }, + new SampleDataType() { Text = "Rotate", Icon = Symbol.Rotate }, + new SampleDataType() { Text = "Rotate Camera", Icon = Symbol.RotateCamera }, + new SampleDataType() { Text = "Send", Icon = Symbol.Send }, + new SampleDataType() { Text = "Tags", Icon = Symbol.Tag }, + new SampleDataType() { Text = "UnFavorite", Icon = Symbol.UnFavorite }, + new SampleDataType() { Text = "UnPin", Icon = Symbol.UnPin }, + new SampleDataType() { Text = "Zoom", Icon = Symbol.Zoom }, + new SampleDataType() { Text = "ZoomIn", Icon = Symbol.ZoomIn }, + new SampleDataType() { Text = "ZoomOut", Icon = Symbol.ZoomOut }, + }; + + private RichSuggestBox _rsb; + private RichSuggestBox _tsb; + private DispatcherQueue _dispatcherQueue; + + public RichSuggestBoxPage() + { + this.InitializeComponent(); + this._dispatcherQueue = DispatcherQueue.GetForCurrentThread(); + Loaded += (sender, e) => { this.OnXamlRendered(this); }; + } + + public void OnXamlRendered(FrameworkElement control) + { + if (this._rsb != null) + { + this._rsb.SuggestionChosen -= this.SuggestingBox_OnSuggestionChosen; + this._rsb.SuggestionRequested -= this.SuggestingBox_OnSuggestionRequested; + } + + if (this._tsb != null) + { + this._tsb.SuggestionChosen -= this.SuggestingBox_OnSuggestionChosen; + this._tsb.SuggestionRequested -= this.SuggestingBox_OnSuggestionRequested; + this._tsb.TokenPointerOver -= this.SuggestingBox_OnTokenPointerOver; + } + + if (control.FindChild("SuggestingBox") is RichSuggestBox rsb) + { + this._rsb = rsb; + this._rsb.SuggestionChosen += this.SuggestingBox_OnSuggestionChosen; + this._rsb.SuggestionRequested += this.SuggestingBox_OnSuggestionRequested; + } + + if (control.FindChild("PlainTextSuggestingBox") is RichSuggestBox tsb) + { + this._tsb = tsb; + this._tsb.SuggestionChosen += this.SuggestingBox_OnSuggestionChosen; + this._tsb.SuggestionRequested += this.SuggestingBox_OnSuggestionRequested; + this._tsb.TokenPointerOver += this.SuggestingBox_OnTokenPointerOver; + } + + if (control.FindChild("TokenListView1") is ListView tls1) + { + tls1.ItemsSource = this._rsb?.Tokens; + } + + if (control.FindChild("TokenListView2") is ListView tls2) + { + tls2.ItemsSource = this._tsb?.Tokens; + } + } + + private void SuggestingBox_OnTokenPointerOver(RichSuggestBox sender, RichSuggestTokenPointerOverEventArgs args) + { + var flyout = (Flyout)FlyoutBase.GetAttachedFlyout(sender); + var pointerPosition = args.CurrentPoint.Position; + + if (flyout?.Content is ContentPresenter cp && sender.TextDocument.Selection.Type != SelectionType.Normal && + (!flyout.IsOpen || cp.Content != args.Token.Item)) + { + this._dispatcherQueue.TryEnqueue(() => + { + cp.Content = args.Token.Item; + flyout.ShowAt(sender, new FlyoutShowOptions + { + Position = pointerPosition, + ExclusionRect = sender.GetRectFromRange(args.Range), + ShowMode = FlyoutShowMode.TransientWithDismissOnPointerMoveAway, + }); + }); + } + } + + private void SuggestingBox_OnSuggestionChosen(RichSuggestBox sender, SuggestionChosenEventArgs args) + { + if (args.Prefix == "#") + { + args.Format.BackgroundColor = Colors.DarkOrange; + args.Format.ForegroundColor = Colors.OrangeRed; + args.Format.Bold = FormatEffect.On; + args.Format.Italic = FormatEffect.On; + args.DisplayText = ((SampleDataType)args.SelectedItem).Text; + } + else + { + args.DisplayText = ((SampleEmailDataType)args.SelectedItem).DisplayName; + } + } + + private void SuggestingBox_OnSuggestionRequested(RichSuggestBox sender, SuggestionRequestedEventArgs args) + { + if (args.Prefix == "#") + { + sender.ItemsSource = + this._samples.Where(x => x.Text.Contains(args.QueryText, StringComparison.OrdinalIgnoreCase)); + } + else + { + sender.ItemsSource = + this._emailSamples.Where(x => x.DisplayName.Contains(args.QueryText, StringComparison.OrdinalIgnoreCase)); + } + } + } +} diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/RichSuggestBox/RichSuggestBoxXaml.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/RichSuggestBox/RichSuggestBoxXaml.bind new file mode 100644 index 00000000000..e5325501dab --- /dev/null +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/RichSuggestBox/RichSuggestBoxXaml.bind @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + Text: + + Position: + + Id: + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/RichSuggestBox/SuggestionTemplateSelector.cs b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/RichSuggestBox/SuggestionTemplateSelector.cs new file mode 100644 index 00000000000..863a9c62776 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/RichSuggestBox/SuggestionTemplateSelector.cs @@ -0,0 +1,21 @@ +// 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; +using Windows.UI.Xaml.Controls; + +namespace Microsoft.Toolkit.Uwp.SampleApp.SamplePages +{ + public class SuggestionTemplateSelector : DataTemplateSelector + { + public DataTemplate Person { get; set; } + + public DataTemplate Data { get; set; } + + protected override DataTemplate SelectTemplateCore(object item) + { + return item is SampleEmailDataType ? this.Person : this.Data; + } + } +} diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Shadows/AttachedDropShadowPage.xaml b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Shadows/AttachedDropShadowPage.xaml new file mode 100644 index 00000000000..95866761d0b --- /dev/null +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Shadows/AttachedDropShadowPage.xaml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Shadows/AttachedDropShadowPage.xaml.cs b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Shadows/AttachedDropShadowPage.xaml.cs new file mode 100644 index 00000000000..d750e12f30b --- /dev/null +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Shadows/AttachedDropShadowPage.xaml.cs @@ -0,0 +1,30 @@ +// 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 Microsoft.Toolkit.Uwp.UI; +using Windows.UI.Xaml; + +namespace Microsoft.Toolkit.Uwp.SampleApp.SamplePages +{ + public sealed partial class AttachedDropShadowPage : IXamlRenderListener + { + public AttachedDropShadowPage() + { + InitializeComponent(); + } + + public void OnXamlRendered(FrameworkElement control) + { + // This is done as we don't have x:Bind in live xaml, so we find and attach after. + var castToTarget = control.FindChild("ShadowTarget"); + if (castToTarget != null) + { + if (control.Resources.TryGetValue("CommonShadow", out var resource) && resource is AttachedDropShadow shadow) + { + shadow.CastTo = castToTarget; + } + } + } + } +} \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Shadows/AttachedShadowCompositionXaml.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Shadows/AttachedShadowCompositionXaml.bind new file mode 100644 index 00000000000..b594d25096b --- /dev/null +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Shadows/AttachedShadowCompositionXaml.bind @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + +