diff --git a/MADE-Uno.sln b/MADE-Uno.sln index 2271bf0..fc44b96 100644 --- a/MADE-Uno.sln +++ b/MADE-Uno.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.31624.102 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.32126.317 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{01380FB8-F8A7-4416-AABA-5407574B7723}" EndProject @@ -39,6 +39,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MADE.UI.Styling", "src\MADE EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MADE.UI.ViewManagement", "src\MADE.UI.ViewManagement\MADE.UI.ViewManagement.csproj", "{442D1E25-FFD1-405D-A1FC-40CAFCAD190C}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MADE.UI.Controls.ChipBox", "src\MADE.UI.Controls.ChipBox\MADE.UI.Controls.ChipBox.csproj", "{D1A16208-5A34-4CC1-B175-01B5AC99E69E}" +EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution samples\MADE.Samples\MADE.Samples.Shared\MADE.Samples.Shared.projitems*{04f1b32d-9056-43fc-b4c2-b8c5481bdacb}*SharedItemsImports = 4 @@ -799,6 +801,62 @@ Global {442D1E25-FFD1-405D-A1FC-40CAFCAD190C}.Release|x64.Build.0 = Release|Any CPU {442D1E25-FFD1-405D-A1FC-40CAFCAD190C}.Release|x86.ActiveCfg = Release|Any CPU {442D1E25-FFD1-405D-A1FC-40CAFCAD190C}.Release|x86.Build.0 = Release|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.Ad-Hoc|ARM64.ActiveCfg = Debug|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.Ad-Hoc|ARM64.Build.0 = Debug|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.Ad-Hoc|x64.Build.0 = Debug|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.Ad-Hoc|x86.Build.0 = Debug|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.AppStore|ARM.ActiveCfg = Debug|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.AppStore|ARM.Build.0 = Debug|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.AppStore|ARM64.ActiveCfg = Debug|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.AppStore|ARM64.Build.0 = Debug|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.AppStore|iPhone.Build.0 = Debug|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.AppStore|x64.ActiveCfg = Debug|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.AppStore|x64.Build.0 = Debug|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.AppStore|x86.ActiveCfg = Debug|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.AppStore|x86.Build.0 = Debug|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.Debug|ARM.ActiveCfg = Debug|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.Debug|ARM.Build.0 = Debug|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.Debug|ARM64.Build.0 = Debug|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.Debug|iPhone.Build.0 = Debug|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.Debug|x64.ActiveCfg = Debug|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.Debug|x64.Build.0 = Debug|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.Debug|x86.ActiveCfg = Debug|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.Debug|x86.Build.0 = Debug|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.Release|Any CPU.Build.0 = Release|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.Release|ARM.ActiveCfg = Release|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.Release|ARM.Build.0 = Release|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.Release|ARM64.ActiveCfg = Release|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.Release|ARM64.Build.0 = Release|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.Release|iPhone.ActiveCfg = Release|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.Release|iPhone.Build.0 = Release|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.Release|x64.ActiveCfg = Release|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.Release|x64.Build.0 = Release|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.Release|x86.ActiveCfg = Release|Any CPU + {D1A16208-5A34-4CC1-B175-01B5AC99E69E}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -819,6 +877,7 @@ Global {0CA60466-059C-42D3-9B68-6BBB75A75090} = {01380FB8-F8A7-4416-AABA-5407574B7723} {F8D00106-0598-45E7-B92E-EF408249C02E} = {01380FB8-F8A7-4416-AABA-5407574B7723} {442D1E25-FFD1-405D-A1FC-40CAFCAD190C} = {01380FB8-F8A7-4416-AABA-5407574B7723} + {D1A16208-5A34-4CC1-B175-01B5AC99E69E} = {01380FB8-F8A7-4416-AABA-5407574B7723} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {3921AD86-E6C0-4436-8880-2D9EDFAD6151} diff --git a/README.md b/README.md index 2c8313b..5dbb9cd 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,7 @@ As many developers know, projects like MADE Uno are built and maintained in spar | Package | Current | Preview | Downloads | | ------ | ------ | ------ | ------ | | UI | [![NuGet](https://img.shields.io/nuget/v/MADE.UI)](https://www.nuget.org/packages/MADE.UI/) | [![NuGet](https://img.shields.io/nuget/vpre/MADE.UI)](https://www.nuget.org/packages/MADE.UI/) | [![NuGet Downloads](https://img.shields.io/nuget/dt/MADE.UI.svg)](https://www.nuget.org/packages/MADE.UI) | +| UI.Controls.ChipBox | [![NuGet](https://img.shields.io/nuget/v/MADE.UI.Controls.ChipBox)](https://www.nuget.org/packages/MADE.UI.Controls.ChipBox/) | [![NuGet](https://img.shields.io/nuget/vpre/MADE.UI.Controls.ChipBox)](https://www.nuget.org/packages/MADE.UI.Controls.ChipBox/) | [![NuGet Downloads](https://img.shields.io/nuget/dt/MADE.UI.Controls.ChipBox.svg)](https://www.nuget.org/packages/MADE.UI.Controls.ChipBox) | | UI.Controls.DropDownList | [![NuGet](https://img.shields.io/nuget/v/MADE.UI.Controls.DropDownList)](https://www.nuget.org/packages/MADE.UI.Controls.DropDownList/) | [![NuGet](https://img.shields.io/nuget/vpre/MADE.UI.Controls.DropDownList)](https://www.nuget.org/packages/MADE.UI.Controls.DropDownList/) | [![NuGet Downloads](https://img.shields.io/nuget/dt/MADE.UI.Controls.DropDownList.svg)](https://www.nuget.org/packages/MADE.UI.Controls.DropDownList) | | UI.Controls.FilePicker | [![NuGet](https://img.shields.io/nuget/v/MADE.UI.Controls.FilePicker)](https://www.nuget.org/packages/MADE.UI.Controls.FilePicker/) | [![NuGet](https://img.shields.io/nuget/vpre/MADE.UI.Controls.FilePicker)](https://www.nuget.org/packages/MADE.UI.Controls.FilePicker/) | [![NuGet Downloads](https://img.shields.io/nuget/dt/MADE.UI.Controls.FilePicker.svg)](https://www.nuget.org/packages/MADE.UI.Controls.FilePicker) | | UI.Controls.Validator | [![NuGet](https://img.shields.io/nuget/v/MADE.UI.Controls.Validator)](https://www.nuget.org/packages/MADE.UI.Controls.Validator/) | [![NuGet](https://img.shields.io/nuget/vpre/MADE.UI.Controls.Validator)](https://www.nuget.org/packages/MADE.UI.Controls.Validator/) | [![NuGet Downloads](https://img.shields.io/nuget/dt/MADE.UI.Controls.Validator.svg)](https://www.nuget.org/packages/MADE.UI.Controls.Validator) | diff --git a/assets/SampleIcons.afdesign b/assets/SampleIcons.afdesign index ba3d264..601622e 100644 Binary files a/assets/SampleIcons.afdesign and b/assets/SampleIcons.afdesign differ diff --git a/docs/articles/features/ui-controls-chipbox.md b/docs/articles/features/ui-controls-chipbox.md new file mode 100644 index 0000000..518dd97 --- /dev/null +++ b/docs/articles/features/ui-controls-chipbox.md @@ -0,0 +1,132 @@ +--- +uid: package-ui-controls-chipbox +title: Using the ChipBox control +--- + +# Using the ChipBox control + +The `MADE.UI.Controls.ChipBox` element is a custom-built UI element that works with [Uno's supported platforms](https://platform.uno/) that provides a multi value input for a text box with auto-suggest capabilities. Values added are displayed as removable chips. + +The control is a familiar custom input style control used in web applications. + +Shown below is the visuals for the control in its default state, with some chip values already added. + +ChipBox with chip values selected + +## Example usage + +```xml + + + + + + +``` + +## Retrieving added chip values + +The control exposes the selected chips through the `Chips` list property. + +The type of objects contained in this collection will be `ChipItem` which contains the contents of the item as a generic `Object` type. This allows the `ChipBox` control to support any type of input value object. + +## Providing suggestions for chip values + +The `ChipBox` provides a `Suggestions` property that can be used to provide a list of objects that should be displayed to the user as suggestions. + +The control exposes a `TextChangeCommand` property and a `TextChanged` event that can be used to provide the ability to customize and provide relevant suggestions based on the text provided. This is not a baked in feature of the control itself. Here is an example of using this in action. + +```csharp +private static readonly IList Places = new List +{ + "Austria", + "Belgium", + "Bulgaria", + "Croatia", + "Cyprus", + "Czechia", + "Denmark", + "Estonia", + "Finland", + "France", + "Germany", + "Greece", + "Hungary", + "Ireland", + "Italy", + "Latvia", + "Lithuania", + "Luxembourg", + "Malta", + "Netherlands", + "Poland", + "Portugal", + "Romania", + "Slovakia", + "Slovenia", + "Spain", + "Sweden" +}; + +public ICommand SuggestionTextChangeCommand => new RelayCommand(this.OnSuggestionTextChanged); + +public ObservableCollection ChipSuggestions { get; } = new(Places); + +private void OnSuggestionTextChanged(string obj) +{ + ChipSuggestions.MakeEqualTo(Places.Where(x => x.Contains(obj, StringComparison.CurrentCultureIgnoreCase))); +} +``` + +It is up to the developer to implement the logic to provide suggestions. This is to ensure any flexibility in search and filtering is determined by the application rather than the control. + +## Customizing the ChipBox + +The control has many customization properties that are exposed to tailor the experience for your application. + +### HeaderTemplate + +The `Header` can be customized to include custom UI elements as well as a string resource. + +The `HeaderTemplate` is also available to provide a `DataTemplate` for you to define the rendered UI for the `Header`. + +### ChipContentTemplate + +The rendered UI elements for the chips use a MADE `Chip` content control. By default, the chips will be rendered displaying the string equivalent of the content provided to it. To customize the layout and display of the chip's content, apply a `DataTemplate` to the `ChipContentTemplate` property. + +### SuggestionsItemTemplate + +As suggestions could be a list of complex objects rather than a simple string, the control provides a `SuggestionsItemTemplate` property that can be used to provide a `DataTemplate` for the suggestions that are displayed to the user. + +### IsReadonly + +The `ChipBox` has the ability to be rendered in a readonly state. This is useful when you want to display the chips without any user interaction. + +When enabled, the auto-suggest text box will not be displayed to the user, and the ability to remove chips will be disabled. + +### AllowDuplicate + +By default, the `ChipBox` control allows duplicate values to be accepted. The `AllowDuplicate` property can be used to disable this behavior. + +### AllowFreeText + +The control supports the ability to allow free text input for chip values, as well as the option to only support selections from the suggestions list. + +The `AllowFreeText` property, enabled by default, can be used to control this behavior. diff --git a/docs/articles/intro.md b/docs/articles/intro.md index 94a4f1e..e311533 100644 --- a/docs/articles/intro.md +++ b/docs/articles/intro.md @@ -20,6 +20,7 @@ dotnet add package MADE.UI | Package | Version | | --- | --- | | MADE.UI | [![NuGet](https://img.shields.io/nuget/v/MADE.UI)](https://www.nuget.org/packages/MADE.UI/) | +| MADE.UI.Controls.ChipBox | [![NuGet](https://img.shields.io/nuget/v/MADE.UI.Controls.ChipBox)](https://www.nuget.org/packages/MADE.UI.Controls.ChipBox/) | | MADE.UI.Controls.DropDownList | [![NuGet](https://img.shields.io/nuget/v/MADE.UI.Controls.DropDownList)](https://www.nuget.org/packages/MADE.UI.Controls.DropDownList/) | | MADE.UI.Controls.FilePicker | [![NuGet](https://img.shields.io/nuget/v/MADE.UI.Controls.FilePicker)](https://www.nuget.org/packages/MADE.UI.Controls.FilePicker/) | | MADE.UI.Controls.Validator | [![NuGet](https://img.shields.io/nuget/v/MADE.UI.Controls.Validator)](https://www.nuget.org/packages/MADE.UI.Controls.Validator/) | @@ -42,6 +43,16 @@ Taking advantage of the Uno Platform, the UI packages provide extensible feature +#### UI.Controls.ChipBox + +The UI Controls ChipBox library contains a cross-platform UI element that provides a multi value input for a text box with auto-suggest capabilities. Values added are displayed as removable chips. + + + +[Discover UI.Controls.ChipBox](features/ui-controls-chipbox.md) + + + #### UI.Controls.DropDownList The UI Controls DropDownList library contains a Windows UI element that provides a selection user experience, allowing a user to select one or multiple items from a list. diff --git a/docs/articles/toc.yml b/docs/articles/toc.yml index 693f7e1..b74f222 100644 --- a/docs/articles/toc.yml +++ b/docs/articles/toc.yml @@ -8,6 +8,8 @@ href: features/ui.md - name: Controls items: + - name: ChipBox + href: features/ui-controls-chipbox.md - name: DropDownList href: features/ui-controls-dropdownlist.md - name: FilePicker diff --git a/docs/images/ChipBox.png b/docs/images/ChipBox.png new file mode 100644 index 0000000..e833c16 Binary files /dev/null and b/docs/images/ChipBox.png differ diff --git a/samples/MADE.Samples/MADE.Samples.Droid/MADE.Samples.Droid.csproj b/samples/MADE.Samples/MADE.Samples.Droid/MADE.Samples.Droid.csproj index a6f14fe..9fd02b6 100644 --- a/samples/MADE.Samples/MADE.Samples.Droid/MADE.Samples.Droid.csproj +++ b/samples/MADE.Samples/MADE.Samples.Droid/MADE.Samples.Droid.csproj @@ -78,10 +78,10 @@ 2.1.0-uno.32 - 7.1.10 + 7.1.11 - - + + @@ -107,6 +107,10 @@ + + {d1a16208-5a34-4cc1-b175-01b5ac99e69e} + MADE.UI.Controls.ChipBox + {774fd8d5-ccc1-4eed-aa14-f7069bfae5ce} MADE.UI.Controls.FilePicker diff --git a/samples/MADE.Samples/MADE.Samples.Shared/Features/Home/ViewModels/MainPageViewModel.cs b/samples/MADE.Samples/MADE.Samples.Shared/Features/Home/ViewModels/MainPageViewModel.cs index 9fe86c7..c8b24c3 100644 --- a/samples/MADE.Samples/MADE.Samples.Shared/Features/Home/ViewModels/MainPageViewModel.cs +++ b/samples/MADE.Samples/MADE.Samples.Shared/Features/Home/ViewModels/MainPageViewModel.cs @@ -32,6 +32,10 @@ private static ICollection GetSampleGroups() Name = "Controls", Samples = { + new Sample( + "ChipBox", + typeof(ChipBoxPage), + "/Features/Samples/Assets/ChipBox/ChipBox.png"), new Sample( "FilePicker", typeof(FilePickerPage), diff --git a/samples/MADE.Samples/MADE.Samples.Shared/Features/Samples/Assets/ChipBox/ChipBox.png b/samples/MADE.Samples/MADE.Samples.Shared/Features/Samples/Assets/ChipBox/ChipBox.png new file mode 100644 index 0000000..cd74130 Binary files /dev/null and b/samples/MADE.Samples/MADE.Samples.Shared/Features/Samples/Assets/ChipBox/ChipBox.png differ diff --git a/samples/MADE.Samples/MADE.Samples.Shared/Features/Samples/Assets/ChipBox/ChipBoxCode.txt b/samples/MADE.Samples/MADE.Samples.Shared/Features/Samples/Assets/ChipBox/ChipBoxCode.txt new file mode 100644 index 0000000..df10381 --- /dev/null +++ b/samples/MADE.Samples/MADE.Samples.Shared/Features/Samples/Assets/ChipBox/ChipBoxCode.txt @@ -0,0 +1,44 @@ +private static readonly IList Places = new List +{ + "Austria", + "Belgium", + "Bulgaria", + "Croatia", + "Cyprus", + "Czechia", + "Denmark", + "Estonia", + "Finland", + "France", + "Germany", + "Greece", + "Hungary", + "Ireland", + "Italy", + "Latvia", + "Lithuania", + "Luxembourg", + "Malta", + "Netherlands", + "Poland", + "Portugal", + "Romania", + "Slovakia", + "Slovenia", + "Spain", + "Sweden" +}; + +public ICommand SuggestionTextChangeCommand => new RelayCommand(this.OnSuggestionTextChanged); + +public ObservableCollection SelectedChips { get; } = new() +{ + new ChipItem("United Kingdom") +}; + +public ObservableCollection ChipSuggestions { get; } = new(Places); + +private void OnSuggestionTextChanged(string obj) +{ + ChipSuggestions.MakeEqualTo(Places.Where(x => x.Contains(obj, StringComparison.CurrentCultureIgnoreCase))); +} diff --git a/samples/MADE.Samples/MADE.Samples.Shared/Features/Samples/Assets/ChipBox/ChipBoxXaml.txt b/samples/MADE.Samples/MADE.Samples.Shared/Features/Samples/Assets/ChipBox/ChipBoxXaml.txt new file mode 100644 index 0000000..ad55d03 --- /dev/null +++ b/samples/MADE.Samples/MADE.Samples.Shared/Features/Samples/Assets/ChipBox/ChipBoxXaml.txt @@ -0,0 +1,20 @@ + + + + + + diff --git a/samples/MADE.Samples/MADE.Samples.Shared/Features/Samples/Pages/ChipBoxPage.xaml b/samples/MADE.Samples/MADE.Samples.Shared/Features/Samples/Pages/ChipBoxPage.xaml new file mode 100644 index 0000000..e12dd78 --- /dev/null +++ b/samples/MADE.Samples/MADE.Samples.Shared/Features/Samples/Pages/ChipBoxPage.xaml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + diff --git a/samples/MADE.Samples/MADE.Samples.Shared/Features/Samples/Pages/ChipBoxPage.xaml.cs b/samples/MADE.Samples/MADE.Samples.Shared/Features/Samples/Pages/ChipBoxPage.xaml.cs new file mode 100644 index 0000000..59c4ad5 --- /dev/null +++ b/samples/MADE.Samples/MADE.Samples.Shared/Features/Samples/Pages/ChipBoxPage.xaml.cs @@ -0,0 +1,21 @@ +namespace MADE.Samples.Features.Samples.Pages +{ + using CommunityToolkit.Mvvm.Messaging; + using MADE.Samples.Features.Samples.ViewModels; + using MADE.UI.Views.Navigation; + using MADE.UI.Views.Navigation.Pages; + using Microsoft.Extensions.DependencyInjection; + + public sealed partial class ChipBoxPage : MvvmPage + { + public ChipBoxPage() + { + this.InitializeComponent(); + this.DataContext = new ChipBoxPageViewModel( + App.Services.GetService(), + App.Services.GetService()); + } + + public ChipBoxPageViewModel ViewModel => this.DataContext as ChipBoxPageViewModel; + } +} diff --git a/samples/MADE.Samples/MADE.Samples.Shared/Features/Samples/ViewModels/ChipBoxPageViewModel.cs b/samples/MADE.Samples/MADE.Samples.Shared/Features/Samples/ViewModels/ChipBoxPageViewModel.cs new file mode 100644 index 0000000..e3768f0 --- /dev/null +++ b/samples/MADE.Samples/MADE.Samples.Shared/Features/Samples/ViewModels/ChipBoxPageViewModel.cs @@ -0,0 +1,74 @@ +namespace MADE.Samples.Features.Samples.ViewModels +{ + using System; + using System.Collections.Generic; + using System.Collections.ObjectModel; + using System.Linq; + using System.Windows.Input; + using CommunityToolkit.Mvvm.Input; + using CommunityToolkit.Mvvm.Messaging; + using MADE.Collections; + using MADE.UI.Controls; + using MADE.UI.Views.Navigation; + using MADE.UI.Views.Navigation.ViewModels; + + public class ChipBoxPageViewModel : PageViewModel + { + private static readonly IList Places = new List + { + "Austria", + "Belgium", + "Bulgaria", + "Croatia", + "Cyprus", + "Czechia", + "Denmark", + "Estonia", + "Finland", + "France", + "Germany", + "Greece", + "Hungary", + "Ireland", + "Italy", + "Latvia", + "Lithuania", + "Luxembourg", + "Malta", + "Netherlands", + "Poland", + "Portugal", + "Romania", + "Slovakia", + "Slovenia", + "Spain", + "Sweden" + }; + + public ChipBoxPageViewModel(INavigationService navigationService, IMessenger messenger) + : base(navigationService, messenger) + { + } + + public ICommand AddChipCommand => new RelayCommand(this.AddChip); + + public ICommand SuggestionTextChangeCommand => new RelayCommand(this.OnSuggestionTextChanged); + + public ObservableCollection SelectedChips { get; } = new() + { + new ChipItem("United Kingdom") + }; + + public ObservableCollection ChipSuggestions { get; } = new(Places); + + private void OnSuggestionTextChanged(string obj) + { + ChipSuggestions.MakeEqualTo(Places.Where(x => x.Contains(obj, StringComparison.CurrentCultureIgnoreCase))); + } + + private void AddChip() + { + this.SelectedChips.Add(new ChipItem("Global")); + } + } +} \ No newline at end of file diff --git a/samples/MADE.Samples/MADE.Samples.Shared/MADE.Samples.Shared.projitems b/samples/MADE.Samples/MADE.Samples.Shared/MADE.Samples.Shared.projitems index c31f181..d13f6b1 100644 --- a/samples/MADE.Samples/MADE.Samples.Shared/MADE.Samples.Shared.projitems +++ b/samples/MADE.Samples/MADE.Samples.Shared/MADE.Samples.Shared.projitems @@ -27,6 +27,9 @@ AppDialogPage.xaml + + ChipBoxPage.xaml + FilePickerPage.xaml @@ -37,6 +40,7 @@ WindowManagerPage.xaml + @@ -54,6 +58,17 @@ + + + Designer + + + + + Designer + + + Designer @@ -98,6 +113,10 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + Designer MSBuild:Compile diff --git a/samples/MADE.Samples/MADE.Samples.UWP/MADE.Samples.UWP.csproj b/samples/MADE.Samples/MADE.Samples.UWP/MADE.Samples.UWP.csproj index 30a9837..ee6178e 100644 --- a/samples/MADE.Samples/MADE.Samples.UWP/MADE.Samples.UWP.csproj +++ b/samples/MADE.Samples/MADE.Samples.UWP/MADE.Samples.UWP.csproj @@ -41,8 +41,8 @@ MADE.Samples en-US UAP - 10.0.19041.0 - 10.0.17763.0 + 10.0.22000.0 + 10.0.19041.0 14 512 {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} @@ -143,6 +143,10 @@ + + {d1a16208-5a34-4cc1-b175-01b5ac99e69e} + MADE.UI.Controls.ChipBox + {347cdc37-e140-42fa-8710-a0f3297d2b6b} MADE.UI.Controls.DropDownList diff --git a/samples/MADE.Samples/MADE.Samples.Wasm/MADE.Samples.Wasm.csproj b/samples/MADE.Samples/MADE.Samples.Wasm/MADE.Samples.Wasm.csproj index e165854..58c7295 100644 --- a/samples/MADE.Samples/MADE.Samples.Wasm/MADE.Samples.Wasm.csproj +++ b/samples/MADE.Samples/MADE.Samples.Wasm/MADE.Samples.Wasm.csproj @@ -53,14 +53,15 @@ - - - - - - + + + + + + + diff --git a/samples/MADE.Samples/MADE.Samples.iOS/MADE.Samples.iOS.csproj b/samples/MADE.Samples/MADE.Samples.iOS/MADE.Samples.iOS.csproj index 1bce194..82d64d1 100644 --- a/samples/MADE.Samples/MADE.Samples.iOS/MADE.Samples.iOS.csproj +++ b/samples/MADE.Samples/MADE.Samples.iOS/MADE.Samples.iOS.csproj @@ -133,10 +133,10 @@ 2.1.0-uno.32 - 7.1.10 + 7.1.11 - - + + @@ -169,6 +169,10 @@ + + {d1a16208-5a34-4cc1-b175-01b5ac99e69e} + MADE.UI.Controls.ChipBox + {774fd8d5-ccc1-4eed-aa14-f7069bfae5ce} MADE.UI.Controls.FilePicker diff --git a/src/MADE.UI.Controls.ChipBox/Chip.cs b/src/MADE.UI.Controls.ChipBox/Chip.cs new file mode 100644 index 0000000..f891e42 --- /dev/null +++ b/src/MADE.UI.Controls.ChipBox/Chip.cs @@ -0,0 +1,118 @@ +// MADE Apps licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace MADE.UI.Controls +{ + using System.Windows.Input; + using MADE.UI.Extensions; + using Windows.UI.Xaml; + using Windows.UI.Xaml.Automation.Peers; + using Windows.UI.Xaml.Controls; + + /// + /// Defines a control for displaying a value as a chip with remove capabilities. + /// + [TemplatePart(Name = ChipContentPart, Type = typeof(ContentPresenter))] + [TemplatePart(Name = ChipRemoveButtonPart, Type = typeof(Button))] + public sealed partial class Chip : ContentControl, IChip + { + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty RemoveCommandProperty = DependencyProperty.Register( + nameof(RemoveCommand), + typeof(ICommand), + typeof(Chip), + new PropertyMetadata(default(ICommand))); + + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty CanRemoveProperty = DependencyProperty.Register( + nameof(CanRemove), + typeof(bool), + typeof(Chip), + new PropertyMetadata(true, (o, args) => ((Chip)o).SetRemoveButtonVisibility())); + + private const string ChipContentPart = "ChipContent"; + private const string ChipRemoveButtonPart = "ChipRemoveButton"; + + /// + /// Initializes a new instance of the class. + /// + public Chip() + { + this.DefaultStyleKey = typeof(Chip); + } + + /// + /// Occurs when the user pressed the remove chip button. + /// + public event ChipRemovedEventHandler Removed; + + /// + /// Gets or sets the associated with when the user pressed the remove chip button. + /// + public ICommand RemoveCommand + { + get => (ICommand)GetValue(RemoveCommandProperty); + set => SetValue(RemoveCommandProperty, value); + } + + /// + /// Gets or sets a value indicating whether the chip can be removed. + /// + public bool CanRemove + { + get => (bool)GetValue(CanRemoveProperty); + set => SetValue(CanRemoveProperty, value); + } + + /// + /// Gets the view representing the remove chip button. + /// + public Button RemoveButton { get; private set; } + + /// + /// Provides the class-specific implementation for the Microsoft UI Automation infrastructure. + /// + /// The class-specific instance. + protected override AutomationPeer OnCreateAutomationPeer() + { + return new ChipAutomationPeer(this); + } + + /// + /// Loads the relevant control template so that it's parts can be referenced. + /// + protected override void OnApplyTemplate() + { + if (this.RemoveButton != null) + { + this.RemoveButton.Click -= this.OnRemoveClick; + } + + base.OnApplyTemplate(); + + this.RemoveButton = this.GetChildView + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/MADE.UI.Controls.ChipBox/WrapPanel.cs b/src/MADE.UI.Controls.ChipBox/WrapPanel.cs new file mode 100644 index 0000000..68c9c0d --- /dev/null +++ b/src/MADE.UI.Controls.ChipBox/WrapPanel.cs @@ -0,0 +1,375 @@ +// 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 Windows Community Toolkit project root for more information (https://github.com/CommunityToolkit/WindowsCommunityToolkit/blob/main/License.md). + +namespace MADE.UI.Controls +{ + using System; + using System.Collections.Generic; + using System.Linq; + using Windows.Foundation; + using Windows.UI.Xaml; + using Windows.UI.Xaml.Controls; + + /// + /// WrapPanel is a panel that position child control vertically or horizontally based on the orientation and when max width / max height is reached a new row (in case of horizontal) or column (in case of vertical) is created to fit new controls. + /// + internal partial class WrapPanel : Panel + { + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty HorizontalSpacingProperty = + DependencyProperty.Register( + nameof(HorizontalSpacing), + typeof(double), + typeof(WrapPanel), + new PropertyMetadata(0d, LayoutPropertyChanged)); + + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty VerticalSpacingProperty = + DependencyProperty.Register( + nameof(VerticalSpacing), + typeof(double), + typeof(WrapPanel), + new PropertyMetadata(0d, LayoutPropertyChanged)); + + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty OrientationProperty = + DependencyProperty.Register( + nameof(Orientation), + typeof(Orientation), + typeof(WrapPanel), + new PropertyMetadata(Orientation.Horizontal, LayoutPropertyChanged)); + + /// + /// Identifies the Padding dependency property. + /// + /// The identifier for the dependency property. + public static readonly DependencyProperty PaddingProperty = + DependencyProperty.Register( + nameof(Padding), + typeof(Thickness), + typeof(WrapPanel), + new PropertyMetadata(default(Thickness), LayoutPropertyChanged)); + + /// + /// Identifies the dependency property. + /// + /// The identifier for the dependency property. + public static readonly DependencyProperty StretchChildProperty = + DependencyProperty.Register( + nameof(StretchChild), + typeof(StretchChild), + typeof(WrapPanel), + new PropertyMetadata(StretchChild.None, LayoutPropertyChanged)); + + private readonly List rows = new(); + + /// + /// Gets or sets a uniform Horizontal distance (in pixels) between items when is set to Horizontal, + /// or between columns of items when is set to Vertical. + /// + public double HorizontalSpacing + { + get => (double)this.GetValue(HorizontalSpacingProperty); + set => this.SetValue(HorizontalSpacingProperty, value); + } + + /// + /// Gets or sets a uniform Vertical distance (in pixels) between items when is set to Vertical, + /// or between rows of items when is set to Horizontal. + /// + public double VerticalSpacing + { + get => (double)this.GetValue(VerticalSpacingProperty); + set => this.SetValue(VerticalSpacingProperty, value); + } + + /// + /// Gets or sets the orientation of the WrapPanel. + /// Horizontal means that child controls will be added horizontally until the width of the panel is reached, then a new row is added to add new child controls. + /// Vertical means that children will be added vertically until the height of the panel is reached, then a new column is added. + /// + public Orientation Orientation + { + get => (Orientation)this.GetValue(OrientationProperty); + set => this.SetValue(OrientationProperty, value); + } + + /// + /// Gets or sets the distance between the border and its child object. + /// + /// + /// The dimensions of the space between the border and its child as a Thickness value. + /// Thickness is a structure that stores dimension values using pixel measures. + /// + public Thickness Padding + { + get => (Thickness)this.GetValue(PaddingProperty); + set => this.SetValue(PaddingProperty, value); + } + + /// + /// Gets or sets a value indicating how to arrange child items + /// + public StretchChild StretchChild + { + get => (StretchChild)this.GetValue(StretchChildProperty); + set => this.SetValue(StretchChildProperty, value); + } + + private static void LayoutPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + if (d is WrapPanel wp) + { + wp.InvalidateMeasure(); + wp.InvalidateArrange(); + } + } + + /// + protected override Size MeasureOverride(Size availableSize) + { + var childAvailableSize = new Size( + availableSize.Width - this.Padding.Left - this.Padding.Right, + availableSize.Height - this.Padding.Top - this.Padding.Bottom); + foreach (var child in this.Children) + { + child.Measure(childAvailableSize); + } + + var requiredSize = this.UpdateRows(availableSize); + return requiredSize; + } + + /// + protected override Size ArrangeOverride(Size finalSize) + { + if ((this.Orientation == Orientation.Horizontal && finalSize.Width < this.DesiredSize.Width) || + (this.Orientation == Orientation.Vertical && finalSize.Height < this.DesiredSize.Height)) + { + // We haven't received our desired size. We need to refresh the rows. + this.UpdateRows(finalSize); + } + + if (this.rows.Count > 0) + { + // Now that we have all the data, we do the actual arrange pass + var childIndex = 0; + foreach (var row in this.rows) + { + foreach (var rect in row.ChildrenRects) + { + var child = this.Children[childIndex++]; + while (child.Visibility == Visibility.Collapsed) + { + // Collapsed children are not added into the rows, + // we skip them. + child = this.Children[childIndex++]; + } + + var arrangeRect = new UvRect + { + Position = rect.Position, + Size = new UvMeasure { U = rect.Size.U, V = row.Size.V }, + }; + + var finalRect = arrangeRect.ToRect(this.Orientation); + child.Arrange(finalRect); + } + } + } + + return finalSize; + } + + private Size UpdateRows(Size availableSize) + { + this.rows.Clear(); + + var paddingStart = new UvMeasure(this.Orientation, this.Padding.Left, this.Padding.Top); + var paddingEnd = new UvMeasure(this.Orientation, this.Padding.Right, this.Padding.Bottom); + + if (this.Children.Count == 0) + { + var emptySize = paddingStart.Add(paddingEnd).ToSize(this.Orientation); + return emptySize; + } + + var parentMeasure = new UvMeasure(this.Orientation, availableSize.Width, availableSize.Height); + var spacingMeasure = new UvMeasure(this.Orientation, this.HorizontalSpacing, this.VerticalSpacing); + var position = new UvMeasure(this.Orientation, this.Padding.Left, this.Padding.Top); + + var currentRow = new Row(new List(), default); + var finalMeasure = new UvMeasure(this.Orientation, width: 0.0, height: 0.0); + void Arrange(UIElement child, bool isLast = false) + { + if (child.Visibility == Visibility.Collapsed) + { + return; // if an item is collapsed, avoid adding the spacing + } + + var desiredMeasure = new UvMeasure(this.Orientation, child.DesiredSize); + if ((desiredMeasure.U + position.U + paddingEnd.U) > parentMeasure.U) + { + // next row! + position.U = paddingStart.U; + position.V += currentRow.Size.V + spacingMeasure.V; + + this.rows.Add(currentRow); + currentRow = new Row(new List(), default); + } + + // Stretch the last item to fill the available space + if (isLast) + { + desiredMeasure.U = parentMeasure.U - position.U; + } + + currentRow.Add(position, desiredMeasure); + + // adjust the location for the next items + position.U += desiredMeasure.U + spacingMeasure.U; + finalMeasure.U = Math.Max(finalMeasure.U, position.U); + } + + var lastIndex = this.Children.Count - 1; + for (var i = 0; i < lastIndex; i++) + { + Arrange(this.Children[i]); + } + + Arrange(this.Children[lastIndex], this.StretchChild == StretchChild.Last); + if (currentRow.ChildrenRects.Count > 0) + { + this.rows.Add(currentRow); + } + + if (this.rows.Count == 0) + { + var emptySize = paddingStart.Add(paddingEnd).ToSize(this.Orientation); + return emptySize; + } + + // Get max V here before computing final rect + var lastRowRect = this.rows.Last().Rect; + finalMeasure.V = lastRowRect.Position.V + lastRowRect.Size.V; + var finalRect = finalMeasure.Add(paddingEnd).ToSize(this.Orientation); + return finalRect; + } + + [System.Diagnostics.DebuggerDisplay("U = {U} V = {V}")] + private struct UvMeasure + { + internal static UvMeasure Zero => default; + + internal double U { get; set; } + + internal double V { get; set; } + + public UvMeasure(Orientation orientation, Size size) + : this(orientation, size.Width, size.Height) + { + } + + public UvMeasure(Orientation orientation, double width, double height) + { + if (orientation == Orientation.Horizontal) + { + this.U = width; + this.V = height; + } + else + { + this.U = height; + this.V = width; + } + } + + public UvMeasure Add(double u, double v) + { + return new UvMeasure { U = this.U + u, V = this.V + v }; + } + + public UvMeasure Add(UvMeasure measure) + { + return this.Add(measure.U, measure.V); + } + + public Size ToSize(Orientation orientation) + { + return orientation == Orientation.Horizontal ? new Size(this.U, this.V) : new Size(this.V, this.U); + } + } + + private struct UvRect + { + public UvMeasure Position { get; set; } + + public UvMeasure Size { get; set; } + + public Rect ToRect(Orientation orientation) + { + return orientation switch + { + Orientation.Vertical => new Rect(this.Position.V, this.Position.U, this.Size.V, this.Size.U), + Orientation.Horizontal => new Rect(this.Position.U, this.Position.V, this.Size.U, this.Size.V), + _ => ThrowArgumentException() + }; + } + + private static Rect ThrowArgumentException() + { + throw new ArgumentException("The input orientation is not valid."); + } + } + + private struct Row + { + public Row(List childrenRects, UvMeasure size) + { + this.ChildrenRects = childrenRects; + this.Size = size; + } + + public List ChildrenRects { get; } + + public UvMeasure Size { get; set; } + + public UvRect Rect => this.ChildrenRects.Count > 0 ? + new UvRect { Position = this.ChildrenRects[0].Position, Size = this.Size } : + new UvRect { Position = UvMeasure.Zero, Size = this.Size }; + + public void Add(UvMeasure position, UvMeasure size) + { + this.ChildrenRects.Add(new UvRect { Position = position, Size = size }); + this.Size = new UvMeasure + { + U = position.U + size.U, + V = Math.Max(this.Size.V, size.V), + }; + } + } + } + + /// + /// Options for how to calculate the layout of items. + /// + internal enum StretchChild + { + /// + /// Don't apply any additional stretching logic + /// + None, + + /// + /// Make the last child stretch to fill the available space + /// + Last + } +} \ No newline at end of file diff --git a/src/MADE.UI.Controls.DropDownList/MADE.UI.Controls.DropDownList.csproj b/src/MADE.UI.Controls.DropDownList/MADE.UI.Controls.DropDownList.csproj index 4214734..1415751 100644 --- a/src/MADE.UI.Controls.DropDownList/MADE.UI.Controls.DropDownList.csproj +++ b/src/MADE.UI.Controls.DropDownList/MADE.UI.Controls.DropDownList.csproj @@ -1,7 +1,7 @@ - uap10.0.17763 + uap10.0.19041 true MADE.NET UI DropDownList Control diff --git a/src/MADE.UI.Controls.FilePicker/MADE.UI.Controls.FilePicker.csproj b/src/MADE.UI.Controls.FilePicker/MADE.UI.Controls.FilePicker.csproj index b7ca92c..b300c1b 100644 --- a/src/MADE.UI.Controls.FilePicker/MADE.UI.Controls.FilePicker.csproj +++ b/src/MADE.UI.Controls.FilePicker/MADE.UI.Controls.FilePicker.csproj @@ -1,7 +1,7 @@ - uap10.0.17763;MonoAndroid10.0;xamarinios10;netstandard2.0;xamarinmac20 + uap10.0.19041;MonoAndroid10.0;xamarinios10;netstandard2.0;xamarinmac20 true MADE.NET UI FilePicker Control @@ -14,7 +14,7 @@ - + diff --git a/src/MADE.UI.Controls.Validator/MADE.UI.Controls.Validator.csproj b/src/MADE.UI.Controls.Validator/MADE.UI.Controls.Validator.csproj index 20d64de..8df7b90 100644 --- a/src/MADE.UI.Controls.Validator/MADE.UI.Controls.Validator.csproj +++ b/src/MADE.UI.Controls.Validator/MADE.UI.Controls.Validator.csproj @@ -1,7 +1,7 @@ - uap10.0.17763;MonoAndroid10.0;xamarinios10;netstandard2.0;xamarinmac20 + uap10.0.19041;MonoAndroid10.0;xamarinios10;netstandard2.0;xamarinmac20 true MADE.NET UI DropDownList Control @@ -14,7 +14,7 @@ - + diff --git a/src/MADE.UI.Styling/MADE.UI.Styling.csproj b/src/MADE.UI.Styling/MADE.UI.Styling.csproj index bcb069f..6c18d4f 100644 --- a/src/MADE.UI.Styling/MADE.UI.Styling.csproj +++ b/src/MADE.UI.Styling/MADE.UI.Styling.csproj @@ -1,7 +1,7 @@ - uap10.0.17763;MonoAndroid10.0;xamarinios10;netstandard2.0;xamarinmac20 + uap10.0.19041;MonoAndroid10.0;xamarinios10;netstandard2.0;xamarinmac20 true MADE.NET UI Styling @@ -14,7 +14,7 @@ - + diff --git a/src/MADE.UI.ViewManagement/MADE.UI.ViewManagement.csproj b/src/MADE.UI.ViewManagement/MADE.UI.ViewManagement.csproj index f4a7485..e754c5e 100644 --- a/src/MADE.UI.ViewManagement/MADE.UI.ViewManagement.csproj +++ b/src/MADE.UI.ViewManagement/MADE.UI.ViewManagement.csproj @@ -1,7 +1,7 @@ - uap10.0.17763;MonoAndroid10.0;xamarinios10;netstandard2.0;xamarinmac20 + uap10.0.19041;MonoAndroid10.0;xamarinios10;netstandard2.0;xamarinmac20 true MADE.NET UI View Management @@ -14,7 +14,7 @@ - + diff --git a/src/MADE.UI.Views.Dialogs/MADE.UI.Views.Dialogs.csproj b/src/MADE.UI.Views.Dialogs/MADE.UI.Views.Dialogs.csproj index b1764f9..ee90da2 100644 --- a/src/MADE.UI.Views.Dialogs/MADE.UI.Views.Dialogs.csproj +++ b/src/MADE.UI.Views.Dialogs/MADE.UI.Views.Dialogs.csproj @@ -1,7 +1,7 @@ - uap10.0.17763;MonoAndroid10.0;xamarinios10;netstandard2.0;xamarinmac20 + uap10.0.19041;MonoAndroid10.0;xamarinios10;netstandard2.0;xamarinmac20 true MADE.NET UI View Dialogs @@ -13,7 +13,7 @@ - + diff --git a/src/MADE.UI.Views.Navigation.Mvvm/MADE.UI.Views.Navigation.Mvvm.csproj b/src/MADE.UI.Views.Navigation.Mvvm/MADE.UI.Views.Navigation.Mvvm.csproj index 6d7ecab..f5234a2 100644 --- a/src/MADE.UI.Views.Navigation.Mvvm/MADE.UI.Views.Navigation.Mvvm.csproj +++ b/src/MADE.UI.Views.Navigation.Mvvm/MADE.UI.Views.Navigation.Mvvm.csproj @@ -1,7 +1,7 @@ - uap10.0.17763;MonoAndroid10.0;xamarinios10;netstandard2.0;xamarinmac20 + uap10.0.19041;MonoAndroid10.0;xamarinios10;netstandard2.0;xamarinmac20 true MADE.NET UI View Navigation for MVVM Toolkit @@ -14,7 +14,7 @@ - + diff --git a/src/MADE.UI.Views.Navigation/MADE.UI.Views.Navigation.csproj b/src/MADE.UI.Views.Navigation/MADE.UI.Views.Navigation.csproj index 5a2304c..595b525 100644 --- a/src/MADE.UI.Views.Navigation/MADE.UI.Views.Navigation.csproj +++ b/src/MADE.UI.Views.Navigation/MADE.UI.Views.Navigation.csproj @@ -1,7 +1,7 @@ - uap10.0.17763;MonoAndroid10.0;xamarinios10;netstandard2.0;xamarinmac20 + uap10.0.19041;MonoAndroid10.0;xamarinios10;netstandard2.0;xamarinmac20 true MADE.NET UI View Navigation @@ -14,7 +14,7 @@ - + diff --git a/src/MADE.UI/MADE.UI.csproj b/src/MADE.UI/MADE.UI.csproj index ec83ef3..145db05 100644 --- a/src/MADE.UI/MADE.UI.csproj +++ b/src/MADE.UI/MADE.UI.csproj @@ -1,7 +1,7 @@ - uap10.0.17763;MonoAndroid10.0;xamarinios10;netstandard2.0;xamarinmac20 + uap10.0.19041;MonoAndroid10.0;xamarinios10;netstandard2.0;xamarinmac20 true MADE.NET UI @@ -15,7 +15,7 @@ - +