Bringing touch-effect up to date with main (#1383)
* Popup v6 windows (#1086)
Co-authored-by: Brandon Minnick <13558917+brminnick@users.noreply.github.com>
Co-authored-by: Pedro Jesus <pedrojesus.cefet@gmail.com>
Co-authored-by: Shaun Lawrence <shaunrlawrence@gmail.com>
* ♻️ [Housekeeping] Fixed GravatarImageSourceTests.TestDefaultStream (#1335)
* [housekeeping] Automated PR to fix formatting errors (#1327)
* Fix popup margin on iOS (#1329)
* Bump NuGet.Protocol from 6.6.1 to 6.7.0 in /samples (#1330)
* Use fully qualified namespace for Color reference in TextToColorGenerator (#1332)
* Use fully qualified namespace for Color reference in TextToColorGenerator to prevent collisions
This change should prevent "ambiguous reference" error to occur when other packages are included in a MAUI project that provide their own Color objects
* added global prefix to be safer
---------
Co-authored-by: Pedro Jesus <pedrojesus.cefet@gmail.com>
Co-authored-by: Brandon Minnick <13558917+brminnick@users.noreply.github.com>
* Code cleanup and preparation for the next release (breaking changes) (#1324)
* Code cleanup and preparation for .net 8
* Update CompareConverter.shared.cs
* Revert global.json
* More CleanUps
* Remove redundant TrySetCanceled and rely on speech recognition result
* Update Formatting
---------
Co-authored-by: Brandon Minnick <13558917+brminnick@users.noreply.github.com>
* Fix Gestures on Popup on ios (#1342)
* Fix Gestures on Popup on ios
* don't query type cast directly
* Code for AddLogicalChild (.NET 8)
* reduce changes
* setting the parent fixes the BindingContext of the view
* Revert "setting the parent fixes the BindingContext of the view"
This reverts commit 0a64b56ca5
.
* reduce changes
* simplify code
* fixing build
* assigned Element to contentPage.Parent
---------
Co-authored-by: pedrojesus <pedrojesus.cefet@gmail.com>
* `global.json`: Change `"rollForward": "latestMajor",` -> `"rollForward": "latestFeature"`. (#1338)
Update global.json
* Bump Microsoft.NET.Test.Sdk from 17.7.0 to 17.7.1 in /samples (#1348)
Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.7.0 to 17.7.1.
- [Release notes](https://github.com/microsoft/vstest/releases)
- [Changelog](https://github.com/microsoft/vstest/blob/main/docs/releases.md)
- [Commits](https://github.com/microsoft/vstest/compare/v17.7.0...v17.7.1)
---
updated-dependencies:
- dependency-name: Microsoft.NET.Test.Sdk
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* 632 bug avatar view clipping on windows (#1344)
* Resolves issue on Windows where the splash screen icon is not found.
* Resolves an issue with the 'Ratings' sample for AvatarView.
* Spaces and not tabs
* Spaces and not tabs
* Changed MauiImage to point to Images folder.
* Changed splash for Windows to be Resize=False
* Typo in name of MauiImage
* Try to prevent locking.
* Bump Microsoft.CodeAnalysis from 4.6.0 to 4.7.0 in /samples (#1355)
* Bump Microsoft.CodeAnalysis.CSharp.Workspaces from 4.6.0 to 4.7.0 in /samples (#1357)
* Bump FluentAssertions from 6.11.0 to 6.12.0 in /samples (#1365)
* fix IconTintColorBehavior for Windows (#1370)
fix IconTintColorBehavior for windows
Co-authored-by: Oleksii <sokol@managed-code.com>
* Add `MemoryAnalyzer` roslyn analyzer (#1371)
* Add NuGet Package + Update `WarningsAsErrors`
* Fix MA0002
* Fix `MauiDrawingView`
* Fix `MauiPopup`
* Fix Naming
* return `null` for nullable references
* Use Ternary Operator
* `dotnet format`
* iOS popup fix with Shell or TabbedPage (#1343)
* Fix Issue #1256
Better fix
* Fixed Popup on Multiple Level Pages (#822)
---------
Co-authored-by: Vladislav Antonyuk <33021114+VladislavAntonyuk@users.noreply.github.com>
Co-authored-by: Brandon Minnick <13558917+brminnick@users.noreply.github.com>
* [housekeeping] Automated PR to fix formatting errors (#1373)
* Bump Microsoft.NET.Test.Sdk from 17.7.1 to 17.7.2 in /samples (#1378)
---------
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Vladislav Antonyuk <33021114+VladislavAntonyuk@users.noreply.github.com>
Co-authored-by: Brandon Minnick <13558917+brminnick@users.noreply.github.com>
Co-authored-by: Pedro Jesus <pedrojesus.cefet@gmail.com>
Co-authored-by: Shaun Lawrence <shaunrlawrence@gmail.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: cat0363 <125236133+cat0363@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Wolf <132034537+wolfgang-ironsoftware@users.noreply.github.com>
Co-authored-by: Thomas Stocker <thomas.stocker@gmail.com>
Co-authored-by: George Leithead <github@internetwideworld.com>
Co-authored-by: Sokol2001 <53799292+Sokol2001@users.noreply.github.com>
Co-authored-by: Oleksii <sokol@managed-code.com>
Co-authored-by: Andrey Onishchenko <100789522+cucumber-sp@users.noreply.github.com>
This commit is contained in:
Родитель
d69d0b3f2a
Коммит
8d9386744d
|
@ -36,13 +36,16 @@ Please see our [Code of Conduct](https://dotnetfoundation.org/code-of-conduct).
|
|||
|
||||
As should be clear by now: we assume everyone tries to do their best, everyone should be treated with respect and equally.
|
||||
|
||||
In the unfortunate event that doesn't happen, please feel free to report it to any of the team members or reach out to [Gerald](maillo:gerald.versluis@microsoft.com) directly.
|
||||
In the unfortunate event that doesn't happen, please feel free to report it to any of the team members or reach out to [Gerald](mailto:gerald.versluis@microsoft.com) directly.
|
||||
|
||||
We will take appropriate actions and measures if necessary.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
You will need to complete a Contribution License Agreement before any pull request can be accepted. Complete the CLA at https://cla.dotnetfoundation.org/. This will also be triggered whenever you open a PR and the link should guide you through it.
|
||||
1. Install latest stable [.NET SDK](https://dotnet.microsoft.com/en-us/download)
|
||||
1. Install .NET MAUI workloads (we recommend using Visual Studio installer)
|
||||
|
||||
> You will need to complete a Contribution License Agreement before any pull request can be accepted. Complete the CLA at https://cla.dotnetfoundation.org/. This will also be triggered whenever you open a PR and the link should guide you through it.
|
||||
|
||||
## Reporting a bug
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<NetVersion>net7.0</NetVersion>
|
||||
<!-- Fixes https://github.com/dotnet/maui/pull/12114 -->
|
||||
<PublishReadyToRun>false</PublishReadyToRun>
|
||||
<LangVersion>latest</LangVersion>
|
||||
|
@ -26,8 +27,11 @@
|
|||
CS1592: Badly formed XML in included comments file
|
||||
CS1598: XML parser could not be loaded. The XML documentation file will not be generated.
|
||||
CS1658: Identifier expected; 'true' is a keyword
|
||||
CS1734: XML comment has a paramref tag, but there is no parameter by that name -->
|
||||
<WarningsAsErrors>nullable,CS0419,CS1570,CS1571,CS1572,CS1573,CS1574,CS1580,CS1581,CS1584,CS1589,CS1590,CS1592,CS1598,CS1658,CS1734</WarningsAsErrors>
|
||||
CS1734: XML comment has a paramref tag, but there is no parameter by that name
|
||||
MA0001: Don't define public events in NSObject subclasses
|
||||
MA0002: Don't declare members in NSObject subclasses unless they are WeakReference, WeakReference<T>, or Value types
|
||||
MA0003: Don't subscribe to events inside NSObject subclasses unless it's your event (via this.MyEvent) or inherited from a base type, or the method is static -->
|
||||
<WarningsAsErrors>nullable,CS0419,CS1570,CS1571,CS1572,CS1573,CS1574,CS1580,CS1581,CS1584,CS1589,CS1590,CS1592,CS1598,CS1658,CS1734,MA0001,MA0002,MA0003</WarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -1,24 +1,24 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Project>
|
||||
<ItemGroup Condition="$(TargetFramework.StartsWith('Xamarin.iOS')) != true AND $(TargetFramework.StartsWith('net7.0-ios')) != true">
|
||||
<ItemGroup Condition="$(TargetFramework.StartsWith('Xamarin.iOS')) != true AND $(TargetFramework.StartsWith('$(NetVersion)-ios')) != true">
|
||||
<Compile Remove="**\**\*.ios.cs" />
|
||||
<None Include="**\**\*.ios.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
|
||||
<Compile Remove="**\ios\**\*.cs" />
|
||||
<None Include="**\ios\**\*.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="$(TargetFramework.StartsWith('Xamarin.Mac')) != true AND $(TargetFramework.StartsWith('net7.0-maccatalyst')) != true">
|
||||
<ItemGroup Condition="$(TargetFramework.StartsWith('Xamarin.Mac')) != true AND $(TargetFramework.StartsWith('$(NetVersion)-maccatalyst')) != true">
|
||||
<Compile Remove="**\*.macos.cs" />
|
||||
<None Include="**\*.macos.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
|
||||
<Compile Remove="**\macos\**\*.cs" />
|
||||
<None Include="**\macos\**\*.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="$(TargetFramework.StartsWith('Xamarin.Mac')) != true AND $(TargetFramework.StartsWith('Xamarin.iOS')) != true AND $(TargetFramework.StartsWith('net7.0-ios')) != true AND $(TargetFramework.StartsWith('net7.0-maccatalyst')) != true">
|
||||
<ItemGroup Condition="$(TargetFramework.StartsWith('Xamarin.Mac')) != true AND $(TargetFramework.StartsWith('Xamarin.iOS')) != true AND $(TargetFramework.StartsWith('$(NetVersion)-ios')) != true AND $(TargetFramework.StartsWith('$(NetVersion)-maccatalyst')) != true">
|
||||
<Compile Remove="**\*.macios.cs" />
|
||||
<None Include="**\*.macios.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
|
||||
<Compile Remove="**\macios\**\*.cs" />
|
||||
<None Include="**\macios\**\*.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="$(TargetFramework.StartsWith('MonoAndroid')) != true AND $(TargetFramework.StartsWith('net7.0-android')) != true ">
|
||||
<ItemGroup Condition="$(TargetFramework.StartsWith('MonoAndroid')) != true AND $(TargetFramework.StartsWith('$(NetVersion)-android')) != true ">
|
||||
<Compile Remove="**\**\*.android.cs" />
|
||||
<None Include="**\**\*.android.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
|
||||
<Compile Remove="**\android\**\*.cs" />
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"sdk": {
|
||||
"version": "7.0.200",
|
||||
"rollForward": "latestMajor",
|
||||
"rollForward": "latestFeature",
|
||||
"allowPrerelease": false
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net7.0-ios;net7.0-android;net7.0-maccatalyst</TargetFrameworks>
|
||||
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net7.0-windows10.0.19041.0</TargetFrameworks>
|
||||
<TargetFrameworks Condition="'$(IncludeTizenTargetFrameworks)' == 'true'">$(TargetFrameworks);net7.0-tizen</TargetFrameworks>
|
||||
<TargetFrameworks>$(NetVersion)-ios;$(NetVersion)-android;$(NetVersion)-maccatalyst</TargetFrameworks>
|
||||
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);$(NetVersion)-windows10.0.19041.0</TargetFrameworks>
|
||||
<TargetFrameworks Condition="'$(IncludeTizenTargetFrameworks)' == 'true'">$(TargetFrameworks);$(NetVersion)-tizen</TargetFrameworks>
|
||||
<OutputType>Exe</OutputType>
|
||||
<UseMaui>true</UseMaui>
|
||||
<SingleProject>true</SingleProject>
|
||||
|
@ -42,6 +42,7 @@
|
|||
|
||||
<!-- Images -->
|
||||
<MauiImage Include="Resources\Images\*" />
|
||||
<MauiImage Update="Resources\Images\splash.svg" BaseSize="128,128" Color="#512BD4" Resize="false" />
|
||||
|
||||
<!-- Raw Assets (also remove the "Resources\Raw" prefix) -->
|
||||
<MauiAsset Include="Resources\Raw\**" LogicalName="%(RecursiveDir)%(Filename)%(Extension)" />
|
||||
|
@ -49,7 +50,7 @@
|
|||
<EmbeddedResource Include="Resources\Embedded\*" />
|
||||
|
||||
<!-- Custom Fonts -->
|
||||
<MauiFont Include="Resources\Fonts\*" />
|
||||
<MauiFont Include="Resources\Fonts\*" />
|
||||
|
||||
<PackageReference Include="CommunityToolkit.Maui.Markup" Version="3.2.0" />
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.1" />
|
||||
|
@ -83,4 +84,4 @@
|
|||
<RuntimeIdentifiers>maccatalyst-arm64;maccatalyst-x64</RuntimeIdentifiers>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
</Project>
|
|
@ -30,7 +30,7 @@
|
|||
<Picker
|
||||
Grid.Row="2"
|
||||
ItemsSource="{Binding Locales}"
|
||||
SelectedItem="{Binding Locale}"
|
||||
SelectedItem="{Binding CurrentLocale}"
|
||||
ItemDisplayBinding="{Binding ., Converter={StaticResource PickerLocaleDisplayConverter}}"
|
||||
Margin="0,0,0,20">
|
||||
</Picker>
|
||||
|
|
|
@ -53,8 +53,6 @@
|
|||
</Setter>
|
||||
<Setter Property="FontSize" Value="Default" />
|
||||
<Setter Property="TextColor" Value="Silver" />
|
||||
<Setter Property="WidthRequest" Value="48" />
|
||||
<Setter Property="HeightRequest" Value="48" />
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
</VerticalStackLayout.Resources>
|
||||
|
@ -66,7 +64,7 @@
|
|||
Grid.Column="0"
|
||||
HeightRequest="48"
|
||||
SemanticProperties.Description="Sample AvatarView idea using a polyline stroke shape to override the corder radius to draw a star."
|
||||
StrokeShape="Polyline 70,16 76,32 94,32 80,44 84,60 70,50 55,60 60,42 46,32 64,32"
|
||||
StrokeShape="Polyline 24,0 29,16 48,18 34,30 38,48 24,37 10,48 14,30 0,18 19,16"
|
||||
Style="{StaticResource Rating}"
|
||||
Text="1"
|
||||
WidthRequest="48" />
|
||||
|
@ -74,7 +72,7 @@
|
|||
Grid.Column="1"
|
||||
HeightRequest="48"
|
||||
SemanticProperties.Description="Sample AvatarView idea using a polyline stroke shape to override the corder radius to draw a star."
|
||||
StrokeShape="Polyline 70,16 76,32 94,32 80,44 84,60 70,50 55,60 60,42 46,32 64,32"
|
||||
StrokeShape="Polyline 24,0 29,16 48,18 34,30 38,48 24,37 10,48 14,30 0,18 19,16"
|
||||
Style="{StaticResource Rating}"
|
||||
Text="2"
|
||||
WidthRequest="48" />
|
||||
|
@ -82,7 +80,7 @@
|
|||
Grid.Column="2"
|
||||
HeightRequest="48"
|
||||
SemanticProperties.Description="Sample AvatarView idea using a polyline stroke shape to override the corder radius to draw a star."
|
||||
StrokeShape="Polyline 70,16 76,32 94,32 80,44 84,60 70,50 55,60 60,42 46,32 64,32"
|
||||
StrokeShape="Polyline 24,0 29,16 48,18 34,30 38,48 24,37 10,48 14,30 0,18 19,16"
|
||||
Style="{StaticResource Rating}"
|
||||
Text="3"
|
||||
WidthRequest="48" />
|
||||
|
@ -90,7 +88,7 @@
|
|||
Grid.Column="3"
|
||||
HeightRequest="48"
|
||||
SemanticProperties.Description="Sample AvatarView idea using a polyline stroke shape to override the corder radius to draw a star."
|
||||
StrokeShape="Polyline 70,16 76,32 94,32 80,44 84,60 70,50 55,60 60,42 46,32 64,32"
|
||||
StrokeShape="Polyline 24,0 29,16 48,18 34,30 38,48 24,37 10,48 14,30 0,18 19,16"
|
||||
Style="{StaticResource Rating}"
|
||||
Text="4"
|
||||
WidthRequest="48" />
|
||||
|
@ -98,7 +96,7 @@
|
|||
Grid.Column="4"
|
||||
HeightRequest="48"
|
||||
SemanticProperties.Description="Sample AvatarView idea using a polyline stroke shape to override the corder radius to draw a star, cliped by parent size."
|
||||
StrokeShape="Polyline 70,16 76,32 94,32 80,44 84,60 70,50 55,60 60,42 46,32 64,32"
|
||||
StrokeShape="Polyline 24,0 29,16 48,18 34,30 38,48 24,37 10,48 14,30 0,18 19,16"
|
||||
Style="{StaticResource Rating}"
|
||||
Text="5"
|
||||
WidthRequest="48">
|
||||
|
@ -112,7 +110,7 @@
|
|||
HeightRequest="48"
|
||||
ImageSource="avatar_icon.png"
|
||||
SemanticProperties.Description="Sample AvatarView idea using a polyline stroke shape to override the corder radius to draw a star."
|
||||
StrokeShape="Polyline 70,16 76,32 94,32 80,44 84,60 70,50 55,60 60,42 46,32 64,32"
|
||||
StrokeShape="Polyline 24,0 29,16 48,18 34,30 38,48 24,37 10,48 14,30 0,18 19,16"
|
||||
Style="{StaticResource Rating}"
|
||||
Text="1"
|
||||
WidthRequest="48" />
|
||||
|
@ -122,7 +120,7 @@
|
|||
HeightRequest="48"
|
||||
ImageSource="https://aka.ms/campus.jpg"
|
||||
SemanticProperties.Description="Sample AvatarView idea using a polyline stroke shape to override the corder radius to draw a star."
|
||||
StrokeShape="Polyline 70,16 76,32 94,32 80,44 84,60 70,50 55,60 60,42 46,32 64,32"
|
||||
StrokeShape="Polyline 24,0 29,16 48,18 34,30 38,48 24,37 10,48 14,30 0,18 19,16"
|
||||
Style="{StaticResource Rating}"
|
||||
Text="2"
|
||||
WidthRequest="48" />
|
||||
|
@ -132,7 +130,7 @@
|
|||
HeightRequest="48"
|
||||
ImageSource="avatar_icon.png"
|
||||
SemanticProperties.Description="Sample AvatarView idea using a polyline stroke shape to override the corder radius to draw a star, cliped by parent size."
|
||||
StrokeShape="Polyline 70,16 76,32 94,32 80,44 84,60 70,50 55,60 60,42 46,32 64,32"
|
||||
StrokeShape="Polyline 24,0 29,16 48,18 34,30 38,48 24,37 10,48 14,30 0,18 19,16"
|
||||
Style="{StaticResource Rating}"
|
||||
Text="3"
|
||||
WidthRequest="48">
|
||||
|
|
|
@ -13,25 +13,21 @@
|
|||
<ResourceDictionary>
|
||||
<Style x:Key="Header"
|
||||
TargetType="Label">
|
||||
<Setter Property="VerticalOptions" Value="CenterAndExpand" />
|
||||
<Setter Property="HorizontalOptions" Value="CenterAndExpand" />
|
||||
<Setter Property="VerticalOptions" Value="Center" />
|
||||
<Setter Property="HorizontalOptions" Value="Center" />
|
||||
<Setter Property="Margin" Value="15, 10" />
|
||||
</Style>
|
||||
<Style TargetType="ScrollView">
|
||||
<Setter Property="VerticalOptions" Value="FillAndExpand" />
|
||||
</Style>
|
||||
<Style x:Key="ItemsLayout"
|
||||
TargetType="StackLayout">
|
||||
<Setter Property="Spacing" Value="16" />
|
||||
<Setter Property="VerticalOptions" Value="Fill" />
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
</ContentPage.Resources>
|
||||
|
||||
<ScrollView>
|
||||
<Grid ColumnDefinitions="Auto, Auto, Auto"
|
||||
HorizontalOptions="CenterAndExpand"
|
||||
HorizontalOptions="Center"
|
||||
RowDefinitions="Auto, Auto, Auto, Auto"
|
||||
VerticalOptions="CenterAndExpand">
|
||||
VerticalOptions="Center">
|
||||
|
||||
<Label Grid.Row="0"
|
||||
Grid.ColumnSpan="3"
|
||||
|
|
|
@ -20,8 +20,7 @@ public partial class ShowPopupInOnAppearingPage : BasePage<ShowPopupInOnAppearin
|
|||
|
||||
protected override async void OnAppearing()
|
||||
{
|
||||
|
||||
// Proves that we now support showing a popup before the platform is even ready.
|
||||
var result = await this.ShowPopupAsync(new ReturnResultPopup(popupSizeConstants));
|
||||
await this.ShowPopupAsync(new ReturnResultPopup(popupSizeConstants));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="456" height="456" viewBox="0 0 456 456" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<path d="m 105.50037,281.60863 c -2.70293,0 -5.00091,-0.90042 -6.893127,-2.70209 -1.892214,-1.84778 -2.837901,-4.04181 -2.837901,-6.58209 0,-2.58722 0.945687,-4.80389 2.837901,-6.65167 1.892217,-1.84778 4.190197,-2.77167 6.893127,-2.77167 2.74819,0 5.06798,0.92389 6.96019,2.77167 1.93749,1.84778 2.90581,4.06445 2.90581,6.65167 0,2.54028 -0.96832,4.73431 -2.90581,6.58209 -1.89221,1.80167 -4.212,2.70209 -6.96019,2.70209 z" style="fill:#ffffff;fill-rule:nonzero;stroke-width:0.838376" />
|
||||
<path d="M 213.56111,280.08446 H 195.99044 L 149.69953,207.0544 c -1.17121,-1.84778 -2.14037,-3.76515 -2.90581,-5.75126 h -0.40578 c 0.36051,2.12528 0.54076,6.67515 0.54076,13.6496 v 65.13172 h -15.54349 v -99.36009 h 18.71925 l 44.7374,71.29798 c 1.89222,2.95695 3.1087,4.98917 3.64945,6.09751 h 0.26996 c -0.45021,-2.6325 -0.67573,-7.09015 -0.67573,-13.37293 v -64.02256 h 15.47557 z" style="fill:#ffffff;fill-rule:nonzero;stroke-width:0.838376" />
|
||||
<path d="m 289.25134,280.08446 h -54.40052 v -99.36009 h 52.23835 v 13.99669 h -36.15411 v 28.13085 h 33.31621 v 13.9271 h -33.31621 v 29.37835 h 38.31628 z" style="fill:#ffffff;fill-rule:nonzero;stroke-width:0.838376" />
|
||||
<path d="M 366.56466,194.72106 H 338.7222 v 85.3634 h -16.08423 v -85.3634 h -27.77455 v -13.99669 h 71.70124 z" style="fill:#ffffff;fill-rule:nonzero;stroke-width:0.838376" />
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 1.8 KiB |
|
@ -1,4 +1,5 @@
|
|||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using Microsoft.Maui.Dispatching;
|
||||
|
||||
|
@ -58,7 +59,7 @@ public sealed partial class ByteArrayToImageSourceConverterViewModel : BaseViewM
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
Trace.WriteLine(e);
|
||||
OnImageDownloadFailed(e.Message);
|
||||
}
|
||||
finally
|
||||
|
|
|
@ -18,7 +18,7 @@ public partial class SpeechToTextViewModel : BaseViewModel
|
|||
readonly ISpeechToText speechToText;
|
||||
|
||||
[ObservableProperty]
|
||||
Locale? locale;
|
||||
Locale? currentLocale;
|
||||
|
||||
[ObservableProperty]
|
||||
string? recognitionText = "Welcome to .NET MAUI Community Toolkit!";
|
||||
|
@ -45,7 +45,7 @@ public partial class SpeechToTextViewModel : BaseViewModel
|
|||
Locales.Add(locale);
|
||||
}
|
||||
|
||||
Locale = Locales.FirstOrDefault(x => x.Language is defaultLanguage or defaultLanguage_android or defaultLanguage_tizen) ?? Locales.FirstOrDefault();
|
||||
CurrentLocale = Locales.FirstOrDefault(x => x.Language is defaultLanguage or defaultLanguage_android or defaultLanguage_tizen) ?? Locales.FirstOrDefault();
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
|
@ -53,7 +53,7 @@ public partial class SpeechToTextViewModel : BaseViewModel
|
|||
{
|
||||
await textToSpeech.SpeakAsync(RecognitionText ?? "Welcome to .NET MAUI Community Toolkit!", new()
|
||||
{
|
||||
Locale = Locale,
|
||||
Locale = CurrentLocale,
|
||||
Pitch = 2,
|
||||
Volume = 1
|
||||
}, cancellationToken);
|
||||
|
@ -74,7 +74,7 @@ public partial class SpeechToTextViewModel : BaseViewModel
|
|||
RecognitionText = beginSpeakingPrompt;
|
||||
|
||||
var recognitionResult = await speechToText.ListenAsync(
|
||||
CultureInfo.GetCultureInfo(Locale?.Language ?? defaultLanguage),
|
||||
CultureInfo.GetCultureInfo(CurrentLocale?.Language ?? defaultLanguage),
|
||||
new Progress<string>(partialText =>
|
||||
{
|
||||
if (RecognitionText is beginSpeakingPrompt)
|
||||
|
@ -102,6 +102,6 @@ public partial class SpeechToTextViewModel : BaseViewModel
|
|||
|
||||
void HandleLocalesCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
OnPropertyChanged(nameof(Locale));
|
||||
OnPropertyChanged(nameof(CurrentLocale));
|
||||
}
|
||||
}
|
|
@ -11,24 +11,10 @@ public sealed partial class PopupAnchorViewModel : BaseViewModel
|
|||
[RelayCommand]
|
||||
static void ShowPopup(View anchor)
|
||||
{
|
||||
|
||||
// Using the C# version of Popup until this get fixed
|
||||
// https://github.com/dotnet/maui/issues/4300
|
||||
|
||||
// This works
|
||||
|
||||
var popup = new TransparentPopupCSharp()
|
||||
{
|
||||
Anchor = anchor
|
||||
};
|
||||
|
||||
// This doesn't work
|
||||
|
||||
//var popup = new TransparentPopup
|
||||
//{
|
||||
// Anchor = anchor
|
||||
//};
|
||||
|
||||
Page.ShowPopup(popup);
|
||||
}
|
||||
}
|
|
@ -4,5 +4,5 @@ public sealed partial class XamlBindingPopupViewModel : BaseViewModel
|
|||
{
|
||||
public string Title { get; } = "Xaml Binding Popup";
|
||||
|
||||
public string Message { get; } = "This is a platform specific popup with a .NET MAUI View being rendered. The behaviors of the popup will confirm to 100% as each platform implementation look and feel, but still allows you to use your .NET MAUI Controls.";
|
||||
public string Message { get; } = "This is a platform specific popup with a .NET MAUI View being rendered.\nThe behaviors of the popup will confirm to 100% as each platform implementation look and feel, but still allows you to use your .NET MAUI Controls.";
|
||||
}
|
|
@ -31,9 +31,11 @@
|
|||
|
||||
|
||||
<Label x:Name="Title"
|
||||
Style="{StaticResource Title}" />
|
||||
Style="{StaticResource Title}"
|
||||
Text="This Title Is About To Change"/>
|
||||
<BoxView Style="{StaticResource Divider}" />
|
||||
<Label x:Name="Message"
|
||||
Text="This sample changes the title and message in Popup's OnAppearing method"
|
||||
Style="{StaticResource Content}" />
|
||||
</VerticalStackLayout>
|
||||
</mct:Popup>
|
|
@ -14,10 +14,12 @@ public partial class OpenedEventSimplePopup : Popup
|
|||
Opened += OnOpened;
|
||||
}
|
||||
|
||||
void OnOpened(object? sender, PopupOpenedEventArgs e)
|
||||
async void OnOpened(object? sender, PopupOpenedEventArgs e)
|
||||
{
|
||||
Opened -= OnOpened;
|
||||
|
||||
await Task.Delay(TimeSpan.FromSeconds(1));
|
||||
|
||||
Title.Text = "Opened Event Popup";
|
||||
Message.Text = "The content of this popup was updated after the popup was rendered";
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace CommunityToolkit.Maui.Sample.Views.Popups;
|
||||
|
||||
public class TransparentPopupCSharp : Popup
|
||||
public sealed class TransparentPopupCSharp : Popup
|
||||
{
|
||||
public TransparentPopupCSharp(Size popupSize) : this()
|
||||
{
|
||||
|
|
|
@ -10,7 +10,9 @@
|
|||
<vm:XamlBindingPopupViewModel />
|
||||
</mct:Popup.BindingContext>
|
||||
|
||||
<VerticalStackLayout Style="{StaticResource PopupLayout}">
|
||||
<VerticalStackLayout
|
||||
Style="{StaticResource PopupLayout}"
|
||||
HorizontalOptions="Center">
|
||||
<VerticalStackLayout.Resources>
|
||||
<ResourceDictionary>
|
||||
<Style x:Key="Title" TargetType="Label">
|
||||
|
@ -39,6 +41,9 @@
|
|||
Text="{Binding Title}" />
|
||||
<BoxView Style="{StaticResource Divider}" />
|
||||
<Label Style="{StaticResource Content}"
|
||||
HorizontalTextAlignment="Center"
|
||||
MaxLines="5"
|
||||
LineBreakMode="WordWrap"
|
||||
Text="{Binding Message}" />
|
||||
</VerticalStackLayout>
|
||||
</mct:Popup>
|
|
@ -8,7 +8,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.6.0" PrivateAssets="all" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.7.0" PrivateAssets="all" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFramework>$(NetVersion)</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
<UseMaui>true</UseMaui>
|
||||
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
|
||||
|
@ -11,16 +11,16 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FluentAssertions" Version="6.11.0" />
|
||||
<PackageReference Include="FluentAssertions" Version="6.12.0" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Analyzer.Testing.XUnit" Version="1.1.1" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.CodeFix.Testing.XUnit" Version="1.1.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.2" />
|
||||
<PackageReference Include="xunit" Version="2.5.0" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.0" PrivateAssets="All" />
|
||||
<PackageReference Include="coverlet.collector" Version="6.0.0" PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis" Version="4.6.0" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis" Version="4.7.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -28,7 +28,7 @@
|
|||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="System.Net.Http" Version="4.3.4" />
|
||||
<PackageReference Include="System.Text.RegularExpressions" Version="4.3.1" />
|
||||
<PackageReference Include="NuGet.Protocol" Version="6.6.1" />
|
||||
<PackageReference Include="NuGet.Protocol" Version="6.7.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net7.0;net7.0-android;net7.0-ios;net7.0-maccatalyst</TargetFrameworks>
|
||||
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net7.0-windows10.0.19041.0</TargetFrameworks>
|
||||
<TargetFrameworks Condition="'$(IncludeTizenTargetFrameworks)' == 'true'">$(TargetFrameworks);net7.0-tizen</TargetFrameworks>
|
||||
<TargetFrameworks>$(NetVersion);$(NetVersion)-android;$(NetVersion)-ios;$(NetVersion)-maccatalyst</TargetFrameworks>
|
||||
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);$(NetVersion)-windows10.0.19041.0</TargetFrameworks>
|
||||
<TargetFrameworks Condition="'$(IncludeTizenTargetFrameworks)' == 'true'">$(TargetFrameworks);$(NetVersion)-tizen</TargetFrameworks>
|
||||
<UseMauiCore>true</UseMauiCore>
|
||||
<UseMauiEssentials>true</UseMauiEssentials>
|
||||
<SingleProject>true</SingleProject>
|
||||
|
@ -24,7 +24,7 @@
|
|||
<Authors>Microsoft</Authors>
|
||||
<Owners>Microsoft</Owners>
|
||||
<NeutralLanguage>en</NeutralLanguage>
|
||||
<Product>CommunityToolkit.Maui (net7.0)</Product>
|
||||
<Product>CommunityToolkit.Maui ($(NetVersion))</Product>
|
||||
<Copyright>© Microsoft Corporation. All rights reserved.</Copyright>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
<PackageProjectUrl>https://github.com/CommunityToolkit/Maui</PackageProjectUrl>
|
||||
|
@ -56,7 +56,12 @@
|
|||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
||||
<PackageReference Include="System.Speech" Version="7.0.0" Condition="'$(TargetFramework)' == 'net7.0-windows10.0.19041.0'" />
|
||||
<PackageReference Include="MemoryAnalyzers" Version="0.1.0-beta.3">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
|
||||
<PackageReference Include="System.Speech" Version="7.0.0" Condition="'$(TargetFramework)' == '$(NetVersion)-windows10.0.19041.0'" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -25,7 +25,7 @@ public sealed partial class FileSaverImplementation : IFileSaver, IDisposable
|
|||
var isDirectoryCreated = fileManager.CreateDirectory(tempDirectoryPath, true, null, out var error);
|
||||
if (!isDirectoryCreated)
|
||||
{
|
||||
throw new Exception(error?.LocalizedDescription ?? "Unable to create temp directory.");
|
||||
throw new FileSaveException(error?.LocalizedDescription ?? "Unable to create temp directory.");
|
||||
}
|
||||
|
||||
var fileUrl = tempDirectoryPath.Append(fileName, false);
|
||||
|
|
|
@ -86,7 +86,6 @@ public sealed partial class SpeechToTextImplementation
|
|||
await using (cancellationToken.Register(async () =>
|
||||
{
|
||||
await StopRecording();
|
||||
speechRecognitionTaskCompletionSource.SetCanceled();
|
||||
}))
|
||||
{
|
||||
return await speechRecognitionTaskCompletionSource.Task;
|
||||
|
@ -119,7 +118,10 @@ public sealed partial class SpeechToTextImplementation
|
|||
{
|
||||
try
|
||||
{
|
||||
await speechRecognizer?.ContinuousRecognitionSession.StopAsync();
|
||||
if (speechRecognizer is not null)
|
||||
{
|
||||
await speechRecognizer.ContinuousRecognitionSession.StopAsync();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
using CommunityToolkit.Maui.Core.Views;
|
||||
using Microsoft.Maui.Handlers;
|
||||
using Microsoft.Maui.Platform;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Controls.Primitives;
|
||||
|
||||
namespace CommunityToolkit.Maui.Core.Handlers;
|
||||
|
||||
public partial class PopupHandler : ElementHandler<IPopup, MauiPopup>
|
||||
public partial class PopupHandler : ElementHandler<IPopup, Popup>
|
||||
{
|
||||
/// <summary>
|
||||
/// Action that's triggered when the Popup is Dismissed.
|
||||
|
@ -25,7 +28,14 @@ public partial class PopupHandler : ElementHandler<IPopup, MauiPopup>
|
|||
/// <param name="result">We don't need to provide the result parameter here.</param>
|
||||
public static void MapOnOpened(PopupHandler handler, IPopup view, object? result)
|
||||
{
|
||||
handler.PlatformView.Show();
|
||||
ArgumentNullException.ThrowIfNull(view.Parent);
|
||||
ArgumentNullException.ThrowIfNull(handler.MauiContext);
|
||||
var parent = view.Parent.ToPlatform(handler.MauiContext);
|
||||
parent.IsHitTestVisible = false;
|
||||
handler.PlatformView.XamlRoot = parent.XamlRoot;
|
||||
handler.PlatformView.IsHitTestVisible = true;
|
||||
handler.PlatformView.IsOpen = true;
|
||||
view.OnOpened();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -47,7 +57,7 @@ public partial class PopupHandler : ElementHandler<IPopup, MauiPopup>
|
|||
/// <param name="view">An instance of <see cref="IPopup"/>.</param>
|
||||
public static void MapAnchor(PopupHandler handler, IPopup view)
|
||||
{
|
||||
handler.PlatformView.ConfigureControl();
|
||||
handler.PlatformView.SetAnchor(view, handler.MauiContext);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -57,7 +67,8 @@ public partial class PopupHandler : ElementHandler<IPopup, MauiPopup>
|
|||
/// <param name="view">An instance of <see cref="IPopup"/>.</param>
|
||||
public static void MapCanBeDismissedByTappingOutsideOfPopup(PopupHandler handler, IPopup view)
|
||||
{
|
||||
handler.PlatformView.ConfigureControl();
|
||||
handler.PlatformView.IsLightDismissEnabled = view.CanBeDismissedByTappingOutsideOfPopup;
|
||||
handler.PlatformView.LightDismissOverlayMode = view.CanBeDismissedByTappingOutsideOfPopup ? LightDismissOverlayMode.On : LightDismissOverlayMode.Off;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -68,7 +79,6 @@ public partial class PopupHandler : ElementHandler<IPopup, MauiPopup>
|
|||
public static void MapColor(PopupHandler handler, IPopup view)
|
||||
{
|
||||
handler.PlatformView.SetColor(view);
|
||||
handler.PlatformView.ConfigureControl();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -78,26 +88,40 @@ public partial class PopupHandler : ElementHandler<IPopup, MauiPopup>
|
|||
/// <param name="view">An instance of <see cref="IPopup"/>.</param>
|
||||
public static void MapSize(PopupHandler handler, IPopup view)
|
||||
{
|
||||
handler.PlatformView.ConfigureControl();
|
||||
handler.PlatformView.SetSize(view);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void DisconnectHandler(MauiPopup platformView)
|
||||
protected override void DisconnectHandler(Popup platformView)
|
||||
{
|
||||
platformView.CleanUp();
|
||||
ArgumentNullException.ThrowIfNull(VirtualView.Parent);
|
||||
ArgumentNullException.ThrowIfNull(VirtualView.Handler?.MauiContext);
|
||||
var parent = VirtualView.Parent.ToPlatform(VirtualView.Handler.MauiContext);
|
||||
parent.IsHitTestVisible = true;
|
||||
platformView.IsOpen = false;
|
||||
platformView.Closed -= OnClosed;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override MauiPopup CreatePlatformElement()
|
||||
protected override Popup CreatePlatformElement()
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(MauiContext);
|
||||
return new MauiPopup(MauiContext);
|
||||
var popup = new Popup();
|
||||
return popup;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void ConnectHandler(MauiPopup platformView)
|
||||
protected override void ConnectHandler(Popup platformView)
|
||||
{
|
||||
platformView.SetElement(VirtualView);
|
||||
platformView.Closed += OnClosed;
|
||||
platformView.ConfigureControl(VirtualView, MauiContext);
|
||||
base.ConnectHandler(platformView);
|
||||
}
|
||||
|
||||
void OnClosed(object? sender, object e)
|
||||
{
|
||||
if (!PlatformView.IsOpen && VirtualView.CanBeDismissedByTappingOutsideOfPopup)
|
||||
{
|
||||
VirtualView.Handler?.Invoke(nameof(IPopup.OnDismissedByTappingOutsideOfPopup));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@ namespace CommunityToolkit.Maui.Core.Platform;
|
|||
|
||||
static partial class StatusBar
|
||||
{
|
||||
static void PlatformSetColor(Color color) => throw new NotSupportedException($"{nameof(PlatformSetColor)} is only supported on net6.0-ios and net6.0-android and later");
|
||||
static void PlatformSetColor(Color color) => throw new NotSupportedException($"{nameof(PlatformSetColor)} is only supported on iOS and Android 23 and later");
|
||||
|
||||
static void PlatformSetStyle(StatusBarStyle statusBarStyle) => throw new NotSupportedException($"{nameof(PlatformSetStyle)} is only supported on net6.0-ios and net6.0-android and later");
|
||||
static void PlatformSetStyle(StatusBarStyle statusBarStyle) => throw new NotSupportedException($"{nameof(PlatformSetStyle)} is only supported on iOS and Android 23 and later");
|
||||
}
|
|
@ -9,6 +9,8 @@ namespace CommunityToolkit.Maui.Core.Views;
|
|||
public class AlertView : UIView
|
||||
{
|
||||
readonly List<UIView> children = Enumerable.Empty<UIView>().ToList();
|
||||
readonly WeakReference<UIView?> anchorViewReference = new(null);
|
||||
readonly WeakReference<UIStackView?> containerReference = new(null);
|
||||
|
||||
/// <summary>
|
||||
/// Parent UIView
|
||||
|
@ -20,20 +22,28 @@ public class AlertView : UIView
|
|||
/// </summary>
|
||||
public IReadOnlyList<UIView> Children => children;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UIView"/> on which Alert will appear. When null, <see cref="AlertView"/> will appear at bottom of screen.
|
||||
/// </summary>
|
||||
public UIView? AnchorView { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="AlertViewVisualOptions"/>
|
||||
/// </summary>
|
||||
public AlertViewVisualOptions VisualOptions { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="UIView"/> on which Alert will appear. When null, <see cref="AlertView"/> will appear at bottom of screen.
|
||||
/// </summary>
|
||||
public UIView? AnchorView
|
||||
{
|
||||
get => anchorViewReference.TryGetTarget(out var anchorView) ? anchorView : null;
|
||||
set => anchorViewReference.SetTarget(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Container of <see cref="AlertView"/>
|
||||
/// </summary>
|
||||
protected UIStackView? Container { get; set; }
|
||||
protected UIStackView? Container
|
||||
{
|
||||
get => containerReference.TryGetTarget(out var container) ? container : null;
|
||||
set => containerReference.SetTarget(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dismisses the Popup from the screen
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
using System.Collections.ObjectModel;
|
||||
using Android.Content;
|
||||
using Android.Views;
|
||||
using CommunityToolkit.Maui.Core.Extensions;
|
||||
using Microsoft.Maui.Platform;
|
||||
using AColor = Android.Graphics.Color;
|
||||
using APaint = Android.Graphics.Paint;
|
||||
using APath = Android.Graphics.Path;
|
||||
using AView = Android.Views.View;
|
||||
|
||||
namespace CommunityToolkit.Maui.Core.Views;
|
||||
|
||||
|
@ -24,6 +22,7 @@ public partial class MauiDrawingView : PlatformTouchGraphicsView
|
|||
if (disposing)
|
||||
{
|
||||
currentPath.Dispose();
|
||||
proxy?.Dispose();
|
||||
}
|
||||
|
||||
base.Dispose(disposing);
|
||||
|
@ -78,11 +77,24 @@ public partial class MauiDrawingView : PlatformTouchGraphicsView
|
|||
public void Initialize()
|
||||
{
|
||||
Drawable = new DrawingViewDrawable(this);
|
||||
Lines.CollectionChanged += OnLinesCollectionChanged;
|
||||
proxy = new(this);
|
||||
}
|
||||
|
||||
void Redraw()
|
||||
{
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
static ObservableCollection<PointF> CreateCollectionWithNormalizedPoints(in ObservableCollection<PointF> points, in int drawingViewWidth, in int drawingViewHeight, in float canvasScale)
|
||||
{
|
||||
var newPoints = new List<PointF>();
|
||||
foreach (var point in points)
|
||||
{
|
||||
var pointX = Math.Clamp(point.X, 0, drawingViewWidth / canvasScale);
|
||||
var pointY = Math.Clamp(point.Y, 0, drawingViewHeight / canvasScale);
|
||||
newPoints.Add(new PointF(pointX, pointY));
|
||||
}
|
||||
|
||||
return newPoints.ToObservableCollection();
|
||||
}
|
||||
}
|
|
@ -49,7 +49,7 @@ public partial class MauiDrawingView : PlatformTouchGraphicsView
|
|||
public void Initialize()
|
||||
{
|
||||
Drawable = new DrawingViewDrawable(this);
|
||||
Lines.CollectionChanged += OnLinesCollectionChanged;
|
||||
proxy = new(this);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
@ -58,6 +58,7 @@ public partial class MauiDrawingView : PlatformTouchGraphicsView
|
|||
if (disposing)
|
||||
{
|
||||
currentPath.Dispose();
|
||||
proxy?.Dispose();
|
||||
}
|
||||
|
||||
base.Dispose(disposing);
|
||||
|
|
|
@ -9,11 +9,13 @@ namespace CommunityToolkit.Maui.Core.Views;
|
|||
public partial class MauiDrawingView
|
||||
{
|
||||
readonly WeakEventManager weakEventManager = new();
|
||||
readonly WeakReference<Action<ICanvas, RectF>?> drawActionReference = new(null);
|
||||
|
||||
bool isDrawing;
|
||||
PointF previousPoint;
|
||||
PathF currentPath = new();
|
||||
MauiDrawingLine? currentLine;
|
||||
MauiDrawingViewProxy? proxy;
|
||||
Paint paint = new SolidPaint(DrawingViewDefaults.BackgroundColor);
|
||||
|
||||
/// <summary>
|
||||
|
@ -53,7 +55,11 @@ public partial class MauiDrawingView
|
|||
/// <summary>
|
||||
/// Used to draw any shape on the canvas
|
||||
/// </summary>
|
||||
public Action<ICanvas, RectF>? DrawAction { get; set; }
|
||||
public Action<ICanvas, RectF>? DrawAction
|
||||
{
|
||||
get => drawActionReference.TryGetTarget(out var drawAction) ? drawAction : null;
|
||||
set => drawActionReference.SetTarget(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Drawable background
|
||||
|
@ -103,7 +109,7 @@ public partial class MauiDrawingView
|
|||
|
||||
Redraw();
|
||||
|
||||
Lines.CollectionChanged += OnLinesCollectionChanged;
|
||||
proxy?.SubscribeCollectionChanged();
|
||||
}
|
||||
|
||||
void OnMoving(PointF currentPoint)
|
||||
|
@ -165,7 +171,7 @@ public partial class MauiDrawingView
|
|||
currentPath = new PathF();
|
||||
}
|
||||
|
||||
class DrawingViewDrawable : IDrawable
|
||||
sealed class DrawingViewDrawable : IDrawable
|
||||
{
|
||||
readonly MauiDrawingView drawingView;
|
||||
|
||||
|
@ -192,8 +198,8 @@ public partial class MauiDrawingView
|
|||
canvas.StrokeColor = lineColor;
|
||||
canvas.StrokeSize = lineWidth;
|
||||
canvas.StrokeDashOffset = 0;
|
||||
canvas.StrokeLineCap = LineCap.Butt;
|
||||
canvas.StrokeLineJoin = LineJoin.Miter;
|
||||
canvas.StrokeLineCap = LineCap.Round;
|
||||
canvas.StrokeLineJoin = LineJoin.Round;
|
||||
canvas.StrokeDashPattern = Array.Empty<float>();
|
||||
}
|
||||
|
||||
|
@ -221,20 +227,32 @@ public partial class MauiDrawingView
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if ANDROID
|
||||
static ObservableCollection<PointF> CreateCollectionWithNormalizedPoints(in ObservableCollection<PointF> points, in int drawingViewWidth, in int drawingViewHeight, in float canvasScale)
|
||||
// Proxy class required to avoid memory leaks on iOS, resolving MA0003
|
||||
// Inspired by SearchbarHandler.MauiSearchBarProxy https://github.com/dotnet/maui/blob/911ea757e996d1213711f786f81e05461df6fc2f/src/Core/src/Handlers/SearchBar/SearchBarHandler.iOS.cs#L155-L251
|
||||
sealed partial class MauiDrawingViewProxy : IDisposable
|
||||
{
|
||||
readonly WeakReference<MauiDrawingView> platformView;
|
||||
|
||||
public MauiDrawingViewProxy(MauiDrawingView view)
|
||||
{
|
||||
var newPoints = new List<PointF>();
|
||||
foreach (var point in points)
|
||||
{
|
||||
var pointX = Math.Clamp(point.X, 0, drawingViewWidth / canvasScale);
|
||||
var pointY = Math.Clamp(point.Y, 0, drawingViewHeight / canvasScale);
|
||||
newPoints.Add(new PointF(pointX, pointY));
|
||||
}
|
||||
|
||||
return newPoints.ToObservableCollection();
|
||||
platformView = new(view);
|
||||
SubscribeCollectionChanged();
|
||||
}
|
||||
|
||||
MauiDrawingView PlatformView => platformView.TryGetTarget(out var drawingView)
|
||||
? drawingView
|
||||
: throw new ObjectDisposedException(nameof(PlatformView));
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
PlatformView.Lines.CollectionChanged -= PlatformView.OnLinesCollectionChanged;
|
||||
}
|
||||
|
||||
public void SubscribeCollectionChanged()
|
||||
{
|
||||
PlatformView.Lines.CollectionChanged += PlatformView.OnLinesCollectionChanged;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -20,7 +20,7 @@ public partial class MauiDrawingView : PlatformTouchGraphicsView
|
|||
public void Initialize()
|
||||
{
|
||||
Drawable = new DrawingViewDrawable(this);
|
||||
Lines.CollectionChanged += OnLinesCollectionChanged;
|
||||
proxy = new(this);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
@ -29,6 +29,7 @@ public partial class MauiDrawingView : PlatformTouchGraphicsView
|
|||
if (disposing)
|
||||
{
|
||||
currentPath.Dispose();
|
||||
proxy?.Dispose();
|
||||
TouchEvent -= OnTouch;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ public partial class MauiDrawingView : PlatformTouchGraphicsView, IDisposable
|
|||
System.Diagnostics.Trace.WriteLine("DrawingView requires Windows 10.0.18362 or higher.");
|
||||
}
|
||||
|
||||
Lines.CollectionChanged += OnLinesCollectionChanged;
|
||||
proxy = new(this);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
@ -49,6 +49,7 @@ public partial class MauiDrawingView : PlatformTouchGraphicsView, IDisposable
|
|||
if (disposing)
|
||||
{
|
||||
currentPath.Dispose();
|
||||
proxy?.Dispose();
|
||||
}
|
||||
|
||||
isDisposed = true;
|
||||
|
|
|
@ -10,6 +10,7 @@ namespace CommunityToolkit.Maui.Core.Views;
|
|||
public class MauiPopup : UIViewController
|
||||
{
|
||||
readonly IMauiContext mauiContext;
|
||||
readonly WeakReference<UIViewController?> viewControllerReference = new(null);
|
||||
|
||||
/// <summary>
|
||||
/// Constructor of <see cref="MauiPopup"/>.
|
||||
|
@ -31,7 +32,11 @@ public class MauiPopup : UIViewController
|
|||
/// </summary>
|
||||
public IPopup? VirtualView { get; private set; }
|
||||
|
||||
internal UIViewController? ViewController { get; private set; }
|
||||
internal UIViewController? ViewController
|
||||
{
|
||||
get => viewControllerReference.TryGetTarget(out var viewController) ? viewController : null;
|
||||
set => viewControllerReference.SetTarget(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method to update the Popup's size.
|
||||
|
@ -163,8 +168,7 @@ public class MauiPopup : UIViewController
|
|||
|
||||
void SetPresentationController()
|
||||
{
|
||||
var popOverDelegate = new PopoverDelegate();
|
||||
popOverDelegate.PopoverDismissedEvent += HandlePopoverDelegateDismissed;
|
||||
var popOverDelegate = new PopoverDelegate(this);
|
||||
|
||||
UIPopoverPresentationController presentationController = (UIPopoverPresentationController)(PresentationController ?? throw new InvalidOperationException($"{nameof(PresentationController)} cannot be null."));
|
||||
presentationController.SourceView = ViewController?.View ?? throw new InvalidOperationException($"{nameof(ViewController.View)} cannot be null.");
|
||||
|
@ -172,13 +176,6 @@ public class MauiPopup : UIViewController
|
|||
presentationController.Delegate = popOverDelegate;
|
||||
}
|
||||
|
||||
[MemberNotNull(nameof(VirtualView))]
|
||||
void HandlePopoverDelegateDismissed(object? sender, UIPresentationController e)
|
||||
{
|
||||
_ = VirtualView ?? throw new InvalidOperationException($"{nameof(VirtualView)} cannot be null.");
|
||||
VirtualView.Handler?.Invoke(nameof(IPopup.OnDismissedByTappingOutsideOfPopup));
|
||||
}
|
||||
|
||||
void AddToCurrentPageViewController(UIViewController viewController)
|
||||
{
|
||||
viewController.PresentViewController(this, true, null);
|
||||
|
@ -187,6 +184,13 @@ public class MauiPopup : UIViewController
|
|||
sealed class PopoverDelegate : UIPopoverPresentationControllerDelegate
|
||||
{
|
||||
readonly WeakEventManager popoverDismissedEventmanager = new();
|
||||
readonly WeakReference<MauiPopup> mauiPopup;
|
||||
|
||||
public PopoverDelegate(MauiPopup mauiPopup)
|
||||
{
|
||||
this.mauiPopup = new(mauiPopup);
|
||||
PopoverDismissedEvent += HandlePopoverDelegateDismissed;
|
||||
}
|
||||
|
||||
public event EventHandler<UIPresentationController> PopoverDismissedEvent
|
||||
{
|
||||
|
@ -194,10 +198,19 @@ public class MauiPopup : UIViewController
|
|||
remove => popoverDismissedEventmanager.RemoveEventHandler(value);
|
||||
}
|
||||
|
||||
MauiPopup MauiPopup => mauiPopup.TryGetTarget(out var virtualView)
|
||||
? virtualView
|
||||
: throw new ObjectDisposedException(nameof(MauiPopup));
|
||||
|
||||
public override UIModalPresentationStyle GetAdaptivePresentationStyle(UIPresentationController forPresentationController) =>
|
||||
UIModalPresentationStyle.None;
|
||||
|
||||
public override void DidDismiss(UIPresentationController presentationController) =>
|
||||
popoverDismissedEventmanager.HandleEvent(this, presentationController, nameof(PopoverDismissedEvent));
|
||||
|
||||
void HandlePopoverDelegateDismissed(object? sender, UIPresentationController e)
|
||||
{
|
||||
MauiPopup.VirtualView?.Handler?.Invoke(nameof(IPopup.OnDismissedByTappingOutsideOfPopup));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,288 +0,0 @@
|
|||
using CommunityToolkit.Maui.Core.Handlers;
|
||||
using Microsoft.Maui.Platform;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Controls.Primitives;
|
||||
using LayoutAlignment = Microsoft.Maui.Primitives.LayoutAlignment;
|
||||
using WindowsThickness = Microsoft.UI.Xaml.Thickness;
|
||||
using XamlStyle = Microsoft.UI.Xaml.Style;
|
||||
|
||||
namespace CommunityToolkit.Maui.Core.Views;
|
||||
|
||||
/// <summary>
|
||||
/// The native implementation of Popup control.
|
||||
/// </summary>
|
||||
public class MauiPopup : Flyout
|
||||
{
|
||||
const double defaultBorderThickness = 0;
|
||||
const double defaultSize = 600;
|
||||
readonly IMauiContext mauiContext;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor of <see cref="MauiPopup"/>.
|
||||
/// </summary>
|
||||
/// <param name="mauiContext">An instance of <see cref="IMauiContext"/>.</param>
|
||||
/// <exception cref="ArgumentNullException">If <paramref name="mauiContext"/> is null an exception will be thrown. </exception>
|
||||
public MauiPopup(IMauiContext mauiContext)
|
||||
{
|
||||
this.mauiContext = mauiContext ?? throw new ArgumentNullException(nameof(mauiContext));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An instance of the <see cref="IPopup"/>.
|
||||
/// </summary>
|
||||
public IPopup? VirtualView { get; private set; }
|
||||
|
||||
internal Panel? Control { get; set; }
|
||||
internal XamlStyle FlyoutStyle { get; private set; } = new(typeof(FlyoutPresenter));
|
||||
|
||||
Action<Panel>? panelCleanUp;
|
||||
Func<PopupHandler, Panel?>? createControl;
|
||||
|
||||
/// <summary>
|
||||
/// Method to initialize the native implementation.
|
||||
/// </summary>
|
||||
/// <param name="element">An instance of <see cref="IPopup"/>.</param>
|
||||
public void SetElement(IPopup element)
|
||||
{
|
||||
VirtualView = element;
|
||||
Closing += OnClosing;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method to setup the Content of the Popup using a WrapperControl
|
||||
/// </summary>
|
||||
/// <param name="panelCleanUp">Action to be executed when the Handler discconect</param>
|
||||
/// <param name="createControl">Function to be executed during the create of the popup content</param>
|
||||
public void SetUpPlatformView(Action<Panel> panelCleanUp, Func<PopupHandler, Panel?> createControl)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(panelCleanUp);
|
||||
ArgumentNullException.ThrowIfNull(createControl);
|
||||
|
||||
this.panelCleanUp = panelCleanUp;
|
||||
this.createControl = createControl;
|
||||
|
||||
CreateControl();
|
||||
ConfigureControl();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method to update all the values of the Popup Control.
|
||||
/// </summary>
|
||||
public void ConfigureControl()
|
||||
{
|
||||
if (VirtualView is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
FlyoutStyle = new(typeof(FlyoutPresenter));
|
||||
SetFlyoutColor();
|
||||
SetSize();
|
||||
SetLayout();
|
||||
ApplyStyles();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method to show the Popup.
|
||||
/// </summary>
|
||||
public void Show()
|
||||
{
|
||||
if (VirtualView is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ArgumentNullException.ThrowIfNull(VirtualView.Parent);
|
||||
|
||||
if (VirtualView.Anchor is not null)
|
||||
{
|
||||
var anchor = VirtualView.Anchor.ToPlatform(mauiContext);
|
||||
SetAttachedFlyout(anchor, this);
|
||||
ShowAttachedFlyout(anchor);
|
||||
}
|
||||
else
|
||||
{
|
||||
var frameworkElement = VirtualView.Parent.ToPlatform(mauiContext);
|
||||
frameworkElement.ContextFlyout = this;
|
||||
SetAttachedFlyout(frameworkElement, this);
|
||||
ShowAttachedFlyout(frameworkElement);
|
||||
}
|
||||
VirtualView.OnOpened();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method to CleanUp the resources of the <see cref="MauiPopup"/>.
|
||||
/// </summary>
|
||||
public void CleanUp()
|
||||
{
|
||||
Closing -= OnClosing;
|
||||
Hide();
|
||||
|
||||
|
||||
if (Control is not null)
|
||||
{
|
||||
panelCleanUp?.Invoke(Control);
|
||||
}
|
||||
|
||||
VirtualView = null;
|
||||
Control = null;
|
||||
|
||||
if (Target is not null)
|
||||
{
|
||||
Target.ContextFlyout = null;
|
||||
}
|
||||
}
|
||||
|
||||
void CreateControl()
|
||||
{
|
||||
if (Control is null && VirtualView?.Content is not null && createControl is not null && VirtualView.Handler is PopupHandler handler)
|
||||
{
|
||||
Control = createControl(handler);
|
||||
Content = Control;
|
||||
}
|
||||
}
|
||||
|
||||
void SetSize()
|
||||
{
|
||||
_ = VirtualView ?? throw new InvalidOperationException($"{nameof(VirtualView)} cannot be null.");
|
||||
|
||||
if (Control is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var standardSize = new Size { Width = defaultSize, Height = defaultSize / 2 };
|
||||
|
||||
var currentSize = VirtualView.Size != default ? VirtualView.Size : standardSize;
|
||||
|
||||
if (VirtualView.Content is not null && VirtualView.Size == default)
|
||||
{
|
||||
var content = VirtualView.Content;
|
||||
// There are some situations when the Width and Height values will be NaN
|
||||
// normally when the dev doesn't set the HeightRequest and WidthRequest
|
||||
// and we can't use comparasion on those, so the only to prevent the application to crash
|
||||
// is using this try/catch
|
||||
try
|
||||
{
|
||||
currentSize = new Size(content.Width, content.Height);
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
Control.Width = currentSize.Width;
|
||||
Control.Height = currentSize.Height;
|
||||
|
||||
FlyoutStyle.Setters.Add(new Microsoft.UI.Xaml.Setter(FlyoutPresenter.MinHeightProperty, currentSize.Height + (defaultBorderThickness * 2)));
|
||||
FlyoutStyle.Setters.Add(new Microsoft.UI.Xaml.Setter(FlyoutPresenter.MinWidthProperty, currentSize.Width + (defaultBorderThickness * 2)));
|
||||
FlyoutStyle.Setters.Add(new Microsoft.UI.Xaml.Setter(FlyoutPresenter.MaxHeightProperty, currentSize.Height + (defaultBorderThickness * 2)));
|
||||
FlyoutStyle.Setters.Add(new Microsoft.UI.Xaml.Setter(FlyoutPresenter.MaxWidthProperty, currentSize.Width + (defaultBorderThickness * 2)));
|
||||
}
|
||||
|
||||
void SetLayout()
|
||||
{
|
||||
LightDismissOverlayMode = LightDismissOverlayMode.On;
|
||||
|
||||
if (VirtualView is not null)
|
||||
{
|
||||
this.SetDialogPosition(VirtualView.VerticalOptions, VirtualView.HorizontalOptions);
|
||||
}
|
||||
}
|
||||
|
||||
void SetFlyoutColor()
|
||||
{
|
||||
_ = VirtualView?.Content ?? throw new NullReferenceException(nameof(IPopup.Content));
|
||||
|
||||
var color = VirtualView.Color ?? Colors.Transparent;
|
||||
|
||||
FlyoutStyle.Setters.Add(new Microsoft.UI.Xaml.Setter(FlyoutPresenter.BackgroundProperty, color.ToWindowsColor()));
|
||||
|
||||
if (VirtualView.Color == Colors.Transparent)
|
||||
{
|
||||
FlyoutStyle.Setters.Add(new Microsoft.UI.Xaml.Setter(FlyoutPresenter.IsDefaultShadowEnabledProperty, false));
|
||||
}
|
||||
|
||||
//Configure border
|
||||
|
||||
FlyoutStyle.Setters.Add(new Microsoft.UI.Xaml.Setter(FlyoutPresenter.PaddingProperty, 0));
|
||||
FlyoutStyle.Setters.Add(new Microsoft.UI.Xaml.Setter(FlyoutPresenter.BorderThicknessProperty, new WindowsThickness(defaultBorderThickness)));
|
||||
FlyoutStyle.Setters.Add(new Microsoft.UI.Xaml.Setter(FlyoutPresenter.BorderBrushProperty, Color.FromArgb("#2e6da0").ToWindowsColor()));
|
||||
}
|
||||
|
||||
void ApplyStyles()
|
||||
{
|
||||
if (Control is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
FlyoutPresenterStyle = FlyoutStyle;
|
||||
}
|
||||
|
||||
void SetDialogPosition(LayoutAlignment verticalOptions, LayoutAlignment horizontalOptions)
|
||||
{
|
||||
if (IsTopLeft(verticalOptions, horizontalOptions))
|
||||
{
|
||||
Placement = FlyoutPlacementMode.TopEdgeAlignedLeft;
|
||||
}
|
||||
else if (IsTop(verticalOptions, horizontalOptions))
|
||||
{
|
||||
Placement = FlyoutPlacementMode.Top;
|
||||
}
|
||||
else if (IsTopRight(verticalOptions, horizontalOptions))
|
||||
{
|
||||
Placement = FlyoutPlacementMode.TopEdgeAlignedRight;
|
||||
}
|
||||
else if (IsRight(verticalOptions, horizontalOptions))
|
||||
{
|
||||
Placement = FlyoutPlacementMode.Right;
|
||||
}
|
||||
else if (IsBottomRight(verticalOptions, horizontalOptions))
|
||||
{
|
||||
Placement = FlyoutPlacementMode.BottomEdgeAlignedRight;
|
||||
}
|
||||
else if (IsBottom(verticalOptions, horizontalOptions))
|
||||
{
|
||||
Placement = FlyoutPlacementMode.Bottom;
|
||||
}
|
||||
else if (IsBottomLeft(verticalOptions, horizontalOptions))
|
||||
{
|
||||
Placement = FlyoutPlacementMode.BottomEdgeAlignedLeft;
|
||||
}
|
||||
else if (IsLeft(verticalOptions, horizontalOptions))
|
||||
{
|
||||
Placement = FlyoutPlacementMode.Left;
|
||||
}
|
||||
else if (VirtualView is not null && VirtualView.Anchor is null)
|
||||
{
|
||||
Placement = FlyoutPlacementMode.Full;
|
||||
}
|
||||
else
|
||||
{
|
||||
Placement = FlyoutPlacementMode.Top;
|
||||
}
|
||||
|
||||
static bool IsTopLeft(LayoutAlignment verticalOptions, LayoutAlignment horizontalOptions) => verticalOptions == LayoutAlignment.Start && horizontalOptions == LayoutAlignment.Start;
|
||||
static bool IsTop(LayoutAlignment verticalOptions, LayoutAlignment horizontalOptions) => verticalOptions == LayoutAlignment.Start && horizontalOptions == LayoutAlignment.Center;
|
||||
static bool IsTopRight(LayoutAlignment verticalOptions, LayoutAlignment horizontalOptions) => verticalOptions == LayoutAlignment.Start && horizontalOptions == LayoutAlignment.End;
|
||||
static bool IsRight(LayoutAlignment verticalOptions, LayoutAlignment horizontalOptions) => verticalOptions == LayoutAlignment.Center && horizontalOptions == LayoutAlignment.End;
|
||||
static bool IsBottomRight(LayoutAlignment verticalOptions, LayoutAlignment horizontalOptions) => verticalOptions == LayoutAlignment.End && horizontalOptions == LayoutAlignment.End;
|
||||
static bool IsBottom(LayoutAlignment verticalOptions, LayoutAlignment horizontalOptions) => verticalOptions == LayoutAlignment.End && horizontalOptions == LayoutAlignment.Center;
|
||||
static bool IsBottomLeft(LayoutAlignment verticalOptions, LayoutAlignment horizontalOptions) => verticalOptions == LayoutAlignment.End && horizontalOptions == LayoutAlignment.Start;
|
||||
static bool IsLeft(LayoutAlignment verticalOptions, LayoutAlignment horizontalOptions) => verticalOptions == LayoutAlignment.Center && horizontalOptions == LayoutAlignment.Start;
|
||||
}
|
||||
|
||||
void OnClosing(object? sender, FlyoutBaseClosingEventArgs e)
|
||||
{
|
||||
var isLightDismissEnabled = VirtualView?.CanBeDismissedByTappingOutsideOfPopup is true;
|
||||
if (!isLightDismissEnabled)
|
||||
{
|
||||
e.Cancel = true;
|
||||
}
|
||||
|
||||
if (IsOpen && isLightDismissEnabled)
|
||||
{
|
||||
VirtualView?.Handler?.Invoke(nameof(IPopup.OnDismissedByTappingOutsideOfPopup));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -133,6 +133,10 @@ public static class PopupExtensions
|
|||
|
||||
mauiPopup.PopoverPresentationController.SourceRect = new CGRect(originX, originY, 0, 0);
|
||||
mauiPopup.PopoverPresentationController.PermittedArrowDirections = 0;
|
||||
// From the point of view of usability, the top, bottom, left, and right values of UIEdgeInsets cannot all be 0.
|
||||
// If you specify 0 for the top, bottom, left, and right of UIEdgeInsets, the default margins will be added, so
|
||||
// specify a value as close to 0 here as possible.
|
||||
mauiPopup.PopoverPresentationController.PopoverLayoutMargins = new UIEdgeInsets(0.0001f, 0.0001f, 0.0001f, 0.0001f);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
using Microsoft.Maui.Platform;
|
||||
using CommunityToolkit.Maui.Core.Handlers;
|
||||
using Microsoft.Maui.Platform;
|
||||
using Microsoft.Maui.Primitives;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls.Primitives;
|
||||
|
||||
namespace CommunityToolkit.Maui.Core.Views;
|
||||
|
||||
|
@ -10,17 +14,174 @@ public static class PopupExtensions
|
|||
/// <summary>
|
||||
/// Method to update the <see cref="Maui.Core.IPopup.Content"/> based on the <see cref="Maui.Core.IPopup.Color"/>.
|
||||
/// </summary>
|
||||
/// <param name="flyout">An instance of <see cref="MauiPopup"/>.</param>
|
||||
/// <param name="mauiPopup">An instance of <see cref="Popup"/>.</param>
|
||||
/// <param name="popup">An instance of <see cref="Maui.Core.IPopup"/>.</param>
|
||||
public static void SetColor(this MauiPopup flyout, IPopup popup)
|
||||
public static void SetColor(this Popup mauiPopup, IPopup popup)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(popup.Content);
|
||||
|
||||
var color = popup.Color ?? Colors.Transparent;
|
||||
var view = popup.Content;
|
||||
if (view.Background is null && flyout.Control is not null)
|
||||
if (mauiPopup.Child is FrameworkElement content)
|
||||
{
|
||||
flyout.Control.Background = color.ToPlatform();
|
||||
var backgroundProperty = content.GetType().GetProperty("Background");
|
||||
backgroundProperty?.SetValue(content, color.ToPlatform());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method to update the popup anchor based on the <see cref="Maui.Core.IPopup.Anchor"/>.
|
||||
/// </summary>
|
||||
/// <param name="mauiPopup">An instance of <see cref="Popup"/>.</param>
|
||||
/// <param name="popup">An instance of <see cref="IPopup"/>.</param>
|
||||
/// <param name="mauiContext">An instance of <see cref="IMauiContext"/>.</param>
|
||||
public static void SetAnchor(this Popup mauiPopup, IPopup popup, IMauiContext? mauiContext)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(mauiContext);
|
||||
mauiPopup.PlacementTarget = popup.Anchor?.ToPlatform(mauiContext);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method to prepare control.
|
||||
/// </summary>
|
||||
/// <param name="mauiPopup">An instance of <see cref="Popup"/>.</param>
|
||||
/// <param name="popup">An instance of <see cref="IPopup"/>.</param>
|
||||
/// <param name="mauiContext">An instance of <see cref="IMauiContext"/>.</param>
|
||||
public static void ConfigureControl(this Popup mauiPopup, IPopup popup, IMauiContext? mauiContext)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(mauiContext);
|
||||
if (popup.Content is not null && popup.Handler is PopupHandler handler)
|
||||
{
|
||||
mauiPopup.Child = handler.VirtualView.Content?.ToPlatform(mauiContext);
|
||||
}
|
||||
|
||||
mauiPopup.SetSize(popup);
|
||||
mauiPopup.SetLayout(popup, mauiContext);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method to update the popup size based on the <see cref="Maui.Core.IPopup.Size"/>.
|
||||
/// </summary>
|
||||
/// <param name="mauiPopup">An instance of <see cref="Popup"/>.</param>
|
||||
/// <param name="popup">An instance of <see cref="IPopup"/>.</param>
|
||||
public static void SetSize(this Popup mauiPopup, IPopup popup)
|
||||
{
|
||||
const double defaultBorderThickness = 0;
|
||||
const double defaultSize = 600;
|
||||
|
||||
var standardSize = new Size { Width = defaultSize, Height = defaultSize / 2 };
|
||||
|
||||
var currentSize = popup.Size != default ? popup.Size : standardSize;
|
||||
|
||||
if (popup.Content is not null && popup.Size == default)
|
||||
{
|
||||
var content = popup.Content;
|
||||
// There are some situations when the Width and Height values will be NaN
|
||||
// normally when the dev doesn't set the HeightRequest and WidthRequest
|
||||
// and we can't use comparison on those, so the only to prevent the application to crash
|
||||
// is using this try/catch
|
||||
try
|
||||
{
|
||||
currentSize = new Size(content.Width, content.Height);
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
if (popup.Parent is IView popupParent)
|
||||
{
|
||||
currentSize.Width = Math.Min(currentSize.Width, popupParent.Frame.Width);
|
||||
currentSize.Height = Math.Min(currentSize.Height, popupParent.Frame.Height);
|
||||
}
|
||||
|
||||
mauiPopup.Width = currentSize.Width;
|
||||
mauiPopup.Height = currentSize.Height;
|
||||
mauiPopup.MinWidth = mauiPopup.MaxWidth = currentSize.Width + (defaultBorderThickness * 2);
|
||||
mauiPopup.MinHeight = mauiPopup.MaxHeight = currentSize.Height + (defaultBorderThickness * 2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method to update the popup layout.
|
||||
/// </summary>
|
||||
/// <param name="mauiPopup">An instance of <see cref="Popup"/>.</param>
|
||||
/// <param name="popup">An instance of <see cref="IPopup"/>.</param>
|
||||
/// <param name="mauiContext">An instance of <see cref="IMauiContext"/>.</param>
|
||||
public static void SetLayout(this Popup mauiPopup, IPopup popup, IMauiContext? mauiContext)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(mauiContext);
|
||||
var popupParent = popup.Parent as IView;
|
||||
popup.Content?.Measure(double.PositiveInfinity, double.PositiveInfinity);
|
||||
var contentSize = popup.Content?.ToPlatform(mauiContext).DesiredSize ?? Windows.Foundation.Size.Empty;
|
||||
var popupParentFrame = popupParent?.Frame ?? new Rect(0, 0, contentSize.Width, contentSize.Height);
|
||||
|
||||
var verticalOptions = popup.VerticalOptions;
|
||||
var horizontalOptions = popup.HorizontalOptions;
|
||||
if (IsTopLeft(verticalOptions, horizontalOptions))
|
||||
{
|
||||
mauiPopup.DesiredPlacement = PopupPlacementMode.TopEdgeAlignedLeft;
|
||||
mauiPopup.HorizontalOffset = 0;
|
||||
mauiPopup.VerticalOffset = 0;
|
||||
}
|
||||
else if (IsTop(verticalOptions, horizontalOptions))
|
||||
{
|
||||
mauiPopup.DesiredPlacement = PopupPlacementMode.Top;
|
||||
mauiPopup.HorizontalOffset = (popupParentFrame.Width - contentSize.Width) / 2;
|
||||
mauiPopup.VerticalOffset = 0;
|
||||
}
|
||||
else if (IsTopRight(verticalOptions, horizontalOptions))
|
||||
{
|
||||
mauiPopup.DesiredPlacement = PopupPlacementMode.TopEdgeAlignedRight;
|
||||
mauiPopup.HorizontalOffset = (popupParentFrame.Width - contentSize.Width);
|
||||
mauiPopup.VerticalOffset = 0;
|
||||
}
|
||||
else if (IsRight(verticalOptions, horizontalOptions))
|
||||
{
|
||||
mauiPopup.DesiredPlacement = PopupPlacementMode.Right;
|
||||
mauiPopup.HorizontalOffset = (popupParentFrame.Width - contentSize.Width);
|
||||
mauiPopup.VerticalOffset = (popupParentFrame.Height - contentSize.Height) / 2;
|
||||
}
|
||||
else if (IsBottomRight(verticalOptions, horizontalOptions))
|
||||
{
|
||||
mauiPopup.DesiredPlacement = PopupPlacementMode.BottomEdgeAlignedRight;
|
||||
mauiPopup.HorizontalOffset = (popupParentFrame.Width - contentSize.Width);
|
||||
mauiPopup.VerticalOffset = popupParentFrame.Height + contentSize.Height / 2;
|
||||
}
|
||||
else if (IsBottom(verticalOptions, horizontalOptions))
|
||||
{
|
||||
mauiPopup.DesiredPlacement = PopupPlacementMode.Bottom;
|
||||
mauiPopup.HorizontalOffset = (popupParentFrame.Width - contentSize.Width) / 2;
|
||||
mauiPopup.VerticalOffset = popupParentFrame.Height + contentSize.Height / 2;
|
||||
}
|
||||
else if (IsBottomLeft(verticalOptions, horizontalOptions))
|
||||
{
|
||||
mauiPopup.DesiredPlacement = PopupPlacementMode.BottomEdgeAlignedLeft;
|
||||
mauiPopup.HorizontalOffset = 0;
|
||||
mauiPopup.VerticalOffset = popupParentFrame.Height + contentSize.Height / 2;
|
||||
}
|
||||
else if (IsLeft(verticalOptions, horizontalOptions))
|
||||
{
|
||||
mauiPopup.DesiredPlacement = PopupPlacementMode.Left;
|
||||
mauiPopup.HorizontalOffset = 0;
|
||||
mauiPopup.VerticalOffset = (popupParentFrame.Height - contentSize.Height) / 2;
|
||||
}
|
||||
else if (popup.Anchor is null)
|
||||
{
|
||||
mauiPopup.DesiredPlacement = PopupPlacementMode.Auto;
|
||||
mauiPopup.HorizontalOffset = (popupParentFrame.Width - contentSize.Width) / 2;
|
||||
mauiPopup.VerticalOffset = (popupParentFrame.Height - contentSize.Height) / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
mauiPopup.DesiredPlacement = PopupPlacementMode.Top;
|
||||
}
|
||||
|
||||
static bool IsTopLeft(LayoutAlignment verticalOptions, LayoutAlignment horizontalOptions) => verticalOptions == LayoutAlignment.Start && horizontalOptions == LayoutAlignment.Start;
|
||||
static bool IsTop(LayoutAlignment verticalOptions, LayoutAlignment horizontalOptions) => verticalOptions == LayoutAlignment.Start && horizontalOptions == LayoutAlignment.Center;
|
||||
static bool IsTopRight(LayoutAlignment verticalOptions, LayoutAlignment horizontalOptions) => verticalOptions == LayoutAlignment.Start && horizontalOptions == LayoutAlignment.End;
|
||||
static bool IsRight(LayoutAlignment verticalOptions, LayoutAlignment horizontalOptions) => verticalOptions == LayoutAlignment.Center && horizontalOptions == LayoutAlignment.End;
|
||||
static bool IsBottomRight(LayoutAlignment verticalOptions, LayoutAlignment horizontalOptions) => verticalOptions == LayoutAlignment.End && horizontalOptions == LayoutAlignment.End;
|
||||
static bool IsBottom(LayoutAlignment verticalOptions, LayoutAlignment horizontalOptions) => verticalOptions == LayoutAlignment.End && horizontalOptions == LayoutAlignment.Center;
|
||||
static bool IsBottomLeft(LayoutAlignment verticalOptions, LayoutAlignment horizontalOptions) => verticalOptions == LayoutAlignment.End && horizontalOptions == LayoutAlignment.Start;
|
||||
static bool IsLeft(LayoutAlignment verticalOptions, LayoutAlignment horizontalOptions) => verticalOptions == LayoutAlignment.Center && horizontalOptions == LayoutAlignment.Start;
|
||||
}
|
||||
}
|
|
@ -1,79 +0,0 @@
|
|||
using System.Runtime.InteropServices;
|
||||
using CoreAnimation;
|
||||
|
||||
namespace CommunityToolkit.Maui.Core.Views;
|
||||
|
||||
/// <summary>
|
||||
/// A rounded <see cref="UIStackView"/>
|
||||
/// </summary>
|
||||
[Obsolete]
|
||||
public class RoundedStackView : UIStackView
|
||||
{
|
||||
/// <summary>
|
||||
/// Initialize <see cref="RoundedStackView"/>
|
||||
/// </summary>
|
||||
public RoundedStackView(NFloat leftPadding, NFloat topPadding, NFloat rightPadding, NFloat bottomPadding)
|
||||
{
|
||||
LeftPadding = leftPadding;
|
||||
TopPadding = topPadding;
|
||||
RightPadding = rightPadding;
|
||||
BottomPadding = bottomPadding;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Left Padding
|
||||
/// </summary>
|
||||
public NFloat LeftPadding { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Top Padding
|
||||
/// </summary>
|
||||
public NFloat TopPadding { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Right Padding
|
||||
/// </summary>
|
||||
public NFloat RightPadding { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Bottom Padding
|
||||
/// </summary>
|
||||
public NFloat BottomPadding { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Draw(CGRect rect)
|
||||
{
|
||||
ClipsToBounds = true;
|
||||
|
||||
var path = GetRoundedPath(rect, LeftPadding, TopPadding, RightPadding, BottomPadding);
|
||||
var maskLayer = new CAShapeLayer
|
||||
{
|
||||
Frame = rect,
|
||||
Path = path
|
||||
};
|
||||
|
||||
Layer.Mask = maskLayer;
|
||||
Layer.MasksToBounds = true;
|
||||
}
|
||||
|
||||
static CGPath? GetRoundedPath(CGRect rect, NFloat left, NFloat top, NFloat right, NFloat bottom)
|
||||
{
|
||||
var path = new UIBezierPath();
|
||||
path.MoveTo(new CGPoint(rect.Width - right, rect.Y));
|
||||
|
||||
path.AddArc(new CGPoint(rect.X + rect.Width - right, rect.Y + right), right, (NFloat)(Math.PI * 1.5), (NFloat)Math.PI * 2, true);
|
||||
path.AddLineTo(new CGPoint(rect.Width, rect.Height - bottom));
|
||||
|
||||
path.AddArc(new CGPoint(rect.X + rect.Width - bottom, rect.Y + rect.Height - bottom), bottom, 0, (NFloat)(Math.PI * .5), true);
|
||||
path.AddLineTo(new CGPoint(left, rect.Height));
|
||||
|
||||
path.AddArc(new CGPoint(rect.X + left, rect.Y + rect.Height - left), left, (NFloat)(Math.PI * .5), (NFloat)Math.PI, true);
|
||||
path.AddLineTo(new CGPoint(rect.X, top));
|
||||
|
||||
path.AddArc(new CGPoint(rect.X + top, rect.Y + top), top, (NFloat)Math.PI, (NFloat)(Math.PI * 1.5), true);
|
||||
|
||||
path.ClosePath();
|
||||
|
||||
return path.CGPath;
|
||||
}
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net7.0;net7.0-android;net7.0-ios;net7.0-maccatalyst</TargetFrameworks>
|
||||
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net7.0-windows10.0.19041.0</TargetFrameworks>
|
||||
<TargetFrameworks Condition="'$(IncludeTizenTargetFrameworks)' == 'true'">$(TargetFrameworks);net7.0-tizen</TargetFrameworks>
|
||||
<TargetFrameworks>$(NetVersion);$(NetVersion)-android;$(NetVersion)-ios;$(NetVersion)-maccatalyst</TargetFrameworks>
|
||||
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);$(NetVersion)-windows10.0.19041.0</TargetFrameworks>
|
||||
<TargetFrameworks Condition="'$(IncludeTizenTargetFrameworks)' == 'true'">$(TargetFrameworks);$(NetVersion)-tizen</TargetFrameworks>
|
||||
<UseMaui>true</UseMaui>
|
||||
<SingleProject>true</SingleProject>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
|
@ -23,7 +23,7 @@
|
|||
<Authors>Microsoft</Authors>
|
||||
<Owners>Microsoft</Owners>
|
||||
<NeutralLanguage>en</NeutralLanguage>
|
||||
<Product>CommunityToolkit.Maui (net7.0)</Product>
|
||||
<Product>CommunityToolkit.Maui ($(NetVersion))</Product>
|
||||
<Copyright>© Microsoft Corporation. All rights reserved.</Copyright>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
<PackageProjectUrl>https://github.com/CommunityToolkit/Maui</PackageProjectUrl>
|
||||
|
@ -51,6 +51,11 @@
|
|||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Maui.Controls.Maps" Version="7.0.86" />
|
||||
|
||||
<PackageReference Include="MemoryAnalyzers" Version="0.1.0-beta.3">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.6.0" PrivateAssets="all" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.7.0" PrivateAssets="all" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net7.0;net7.0-android;net7.0-ios;net7.0-maccatalyst</TargetFrameworks>
|
||||
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net7.0-windows10.0.19041.0</TargetFrameworks>
|
||||
<TargetFrameworks Condition="'$(IncludeTizenTargetFrameworks)' == 'true'">$(TargetFrameworks);net7.0-tizen</TargetFrameworks>
|
||||
<TargetFrameworks>$(NetVersion);$(NetVersion)-android;$(NetVersion)-ios;$(NetVersion)-maccatalyst</TargetFrameworks>
|
||||
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);$(NetVersion)-windows10.0.19041.0</TargetFrameworks>
|
||||
<TargetFrameworks Condition="'$(IncludeTizenTargetFrameworks)' == 'true'">$(TargetFrameworks);$(NetVersion)-tizen</TargetFrameworks>
|
||||
<UseMaui>true</UseMaui>
|
||||
<SingleProject>true</SingleProject>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
|
@ -25,7 +25,7 @@
|
|||
<Authors>Microsoft</Authors>
|
||||
<Owners>Microsoft</Owners>
|
||||
<NeutralLanguage>en</NeutralLanguage>
|
||||
<Product>CommunityToolkit.Maui (net7.0)</Product>
|
||||
<Product>CommunityToolkit.Maui ($(NetVersion))</Product>
|
||||
<Copyright>© Microsoft Corporation. All rights reserved.</Copyright>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
<PackageProjectUrl>https://github.com/CommunityToolkit/Maui</PackageProjectUrl>
|
||||
|
@ -53,11 +53,18 @@
|
|||
<None Include="ReadMe.txt" pack="true" PackagePath="." />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\CommunityToolkit.Maui.MediaElement.Analyzers\bin\$(Configuration)\netstandard2.0\CommunityToolkit.Maui.MediaElement.Analyzers.dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
|
||||
<None Include="..\CommunityToolkit.Maui.MediaElement.Analyzers.CodeFixes\bin\$(Configuration)\netstandard2.0\CommunityToolkit.Maui.MediaElement.Analyzers.CodeFixes.dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MemoryAnalyzers" Version="0.1.0-beta.3">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="$(TargetFramework.Contains('-android'))">
|
||||
<PackageReference Include="Xam.Plugins.Android.ExoPlayer" Version="2.18.10" />
|
||||
<PackageReference Include="Xam.Plugins.Android.ExoPlayer.Transformer" Version="2.18.10" />
|
||||
|
|
|
@ -44,13 +44,10 @@ public class MauiMediaElement : CoordinatorLayout
|
|||
{
|
||||
if (disposing)
|
||||
{
|
||||
if (playerView is not null)
|
||||
{
|
||||
// https://github.com/google/ExoPlayer/issues/1855#issuecomment-251041500
|
||||
playerView.Player?.Release();
|
||||
playerView.Player?.Dispose();
|
||||
playerView.Dispose();
|
||||
}
|
||||
// https://github.com/google/ExoPlayer/issues/1855#issuecomment-251041500
|
||||
playerView.Player?.Release();
|
||||
playerView.Player?.Dispose();
|
||||
playerView.Dispose();
|
||||
}
|
||||
|
||||
base.Dispose(disposing);
|
||||
|
|
|
@ -7,7 +7,7 @@ namespace CommunityToolkit.Maui.Core.Views;
|
|||
/// <summary>
|
||||
/// The user-interface element that represents the <see cref="MediaElement"/> on Windows.
|
||||
/// </summary>
|
||||
public class MauiMediaElement : Grid
|
||||
public class MauiMediaElement : Grid, IDisposable
|
||||
{
|
||||
readonly MediaPlayerElement mediaElement;
|
||||
|
||||
|
@ -26,6 +26,18 @@ public class MauiMediaElement : Grid
|
|||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
mediaElement?.MediaPlayer.Dispose();
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Releases the managed and unmanaged resources used by the <see cref="MauiMediaElement"/>.
|
||||
/// </summary>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
mediaElement.MediaPlayer.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -208,7 +208,7 @@ public partial class MediaManager : Java.Lang.Object, IPlayer.IListener
|
|||
/// </remarks>
|
||||
public void OnVolumeChanged(float volume)
|
||||
{
|
||||
if (Player is null || MediaElement is null)
|
||||
if (Player is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -252,8 +252,7 @@ public partial class MediaManager : Java.Lang.Object, IPlayer.IListener
|
|||
|
||||
protected virtual partial void PlatformStop()
|
||||
{
|
||||
if (Player is null || MediaElement is null
|
||||
|| MediaElement.Source is null)
|
||||
if (Player is null || MediaElement.Source is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -315,7 +314,7 @@ public partial class MediaManager : Java.Lang.Object, IPlayer.IListener
|
|||
var path = resourceMediaSource.Path;
|
||||
if (!string.IsNullOrWhiteSpace(path))
|
||||
{
|
||||
string assetFilePath = "asset://" + package + "/" + path;
|
||||
var assetFilePath = $"asset://{package}{Path.PathSeparator}{path}";
|
||||
|
||||
Player.SetMediaItem(MediaItem.FromUri(assetFilePath));
|
||||
Player.Prepare();
|
||||
|
|
|
@ -24,6 +24,7 @@ class TextColorToGenerator : IIncrementalGenerator
|
|||
const string iTextStyleInterface = "Microsoft.Maui.ITextStyle";
|
||||
const string iAnimatableInterface = "Microsoft.Maui.Controls.IAnimatable";
|
||||
const string mauiControlsAssembly = "Microsoft.Maui.Controls";
|
||||
const string mauiColorFullName = "global::Microsoft.Maui.Graphics.Color";
|
||||
|
||||
public void Initialize(IncrementalGeneratorInitializationContext context)
|
||||
{
|
||||
|
@ -115,7 +116,7 @@ namespace {{textStyleClassMetadata.Namespace}};
|
|||
/// <param name="length">The duration, in milliseconds, of the animation</param>
|
||||
/// <param name="easing">The easing function to be used in the animation</param>
|
||||
/// <returns>Value indicating if the animation completed successfully or not</returns>
|
||||
public static Task<bool> TextColorTo{{textStyleClassMetadata.GenericArguments}}(this {{textStyleClassMetadata.Namespace}}.{{textStyleClassMetadata.ClassName}}{{textStyleClassMetadata.GenericArguments}} element, Color color, uint rate = 16u, uint length = 250u, Easing? easing = null)
|
||||
public static Task<bool> TextColorTo{{textStyleClassMetadata.GenericArguments}}(this global::{{textStyleClassMetadata.Namespace}}.{{textStyleClassMetadata.ClassName}}{{textStyleClassMetadata.GenericArguments}} element, {{mauiColorFullName}} color, uint rate = 16u, uint length = 250u, Easing? easing = null)
|
||||
{{textStyleClassMetadata.GenericConstraints}}
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(element);
|
||||
|
|
|
@ -44,7 +44,7 @@ public class StatusBarBehaviorTests : BaseTest
|
|||
{
|
||||
var statusBarBehavior = new StatusBarBehavior();
|
||||
var exception = Assert.Throws<NotSupportedException>(() => statusBarBehavior.StatusBarColor = Colors.Red);
|
||||
exception.Message.Should().Be("PlatformSetColor is only supported on net6.0-ios and net6.0-android and later");
|
||||
exception.Message.Should().Be("PlatformSetColor is only supported on iOS and Android 23 and later");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -52,6 +52,6 @@ public class StatusBarBehaviorTests : BaseTest
|
|||
{
|
||||
var statusBarBehavior = new StatusBarBehavior();
|
||||
var exception = Assert.Throws<NotSupportedException>(() => statusBarBehavior.StatusBarStyle = StatusBarStyle.DarkContent);
|
||||
exception.Message.Should().Be("PlatformSetStyle is only supported on net6.0-ios and net6.0-android and later");
|
||||
exception.Message.Should().Be("PlatformSetStyle is only supported on iOS and Android 23 and later");
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFramework>$(NetVersion)</TargetFramework>
|
||||
<UseMaui>true</UseMaui>
|
||||
<IsPackable>false</IsPackable>
|
||||
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
|
||||
|
@ -10,8 +10,8 @@
|
|||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AutoFixture.Xunit2" Version="4.18.0" />
|
||||
<PackageReference Include="FluentAssertions" Version="6.11.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.0" />
|
||||
<PackageReference Include="FluentAssertions" Version="6.12.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.2" />
|
||||
<PackageReference Include="xunit" Version="2.5.0" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.0" PrivateAssets="All" />
|
||||
<PackageReference Include="coverlet.collector" Version="6.0.0" PrivateAssets="All" />
|
||||
|
|
|
@ -53,7 +53,7 @@ public class IntToBoolConverterTests : BaseConverterTest<IntToBoolConverter>
|
|||
{
|
||||
var intToBoolConverter = new IntToBoolConverter();
|
||||
Assert.Throws<ArgumentNullException>(() => ((ICommunityToolkitValueConverter)intToBoolConverter).Convert(null, typeof(bool), null, CultureInfo.CurrentCulture));
|
||||
Assert.Throws<ArgumentNullException>(() => ((ICommunityToolkitValueConverter)intToBoolConverter).ConvertBack(null, typeof(bool), null, CultureInfo.CurrentCulture)); ;
|
||||
Assert.Throws<ArgumentNullException>(() => ((ICommunityToolkitValueConverter)intToBoolConverter).ConvertBack(null, typeof(bool), null, CultureInfo.CurrentCulture));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
|
|
|
@ -348,7 +348,7 @@ public class GravatarImageSourceTests : BaseHandlerTest
|
|||
CancellationTokenSource cts = new();
|
||||
var gravatarImageSource = new GravatarImageSource();
|
||||
Stream? stream = await gravatarImageSource.Stream(cts.Token);
|
||||
stream.Should().BeNull();
|
||||
stream.Should().NotBeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
|
@ -66,14 +66,14 @@ public class StateContainerTests : BaseTest
|
|||
[Fact]
|
||||
public void StateView_HasStateKey()
|
||||
{
|
||||
var view = StateContainer.GetStateViews(layout).First();
|
||||
var view = StateContainer.GetStateViews(layout)[0];
|
||||
Assert.Equal(StateKey.Loading, StateView.GetStateKey(view));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void StateView_SetsStateKey()
|
||||
{
|
||||
var view = (View)layout.Children.First();
|
||||
var view = (View)layout.Children[0];
|
||||
StateView.SetStateKey(view, StateKey.Anything);
|
||||
Assert.Equal(StateKey.Anything, StateView.GetStateKey(view));
|
||||
}
|
||||
|
@ -484,7 +484,7 @@ public class StateContainerTests : BaseTest
|
|||
public void Controller_SwitchesToStateFromContentSuccess()
|
||||
{
|
||||
controller.SwitchToState(StateKey.Loading);
|
||||
var state = controller.GetLayout().Children.First();
|
||||
var state = controller.GetLayout().Children[0];
|
||||
|
||||
Assert.IsType<Label>(state);
|
||||
Assert.Equal("Loading", ((Label)state).Text);
|
||||
|
@ -494,13 +494,13 @@ public class StateContainerTests : BaseTest
|
|||
public void Controller_SwitchesToContentFromStateSuccess()
|
||||
{
|
||||
controller.SwitchToState(StateKey.Loading);
|
||||
var label = controller.GetLayout().Children.First();
|
||||
var label = controller.GetLayout().Children[0];
|
||||
|
||||
Assert.IsType<Label>(label);
|
||||
Assert.Equal("Loading", ((Label)label).Text);
|
||||
|
||||
controller.SwitchToContent();
|
||||
label = controller.GetLayout().Children.First();
|
||||
label = controller.GetLayout().Children[0];
|
||||
|
||||
Assert.IsType<Label>(label);
|
||||
Assert.Equal("Default", ((Label)label).Text);
|
||||
|
@ -510,13 +510,13 @@ public class StateContainerTests : BaseTest
|
|||
public void Controller_SwitchesToStateFromStateSuccess()
|
||||
{
|
||||
controller.SwitchToState(StateKey.Anything);
|
||||
var label = controller.GetLayout().Children.First();
|
||||
var label = controller.GetLayout().Children[0];
|
||||
|
||||
Assert.IsType<Label>(label);
|
||||
Assert.Equal("Anything", ((Label)label).Text);
|
||||
|
||||
controller.SwitchToState(StateKey.Loading);
|
||||
label = controller.GetLayout().Children.First();
|
||||
label = controller.GetLayout().Children[0];
|
||||
|
||||
Assert.IsType<Label>(label);
|
||||
Assert.Equal("Loading", ((Label)label).Text);
|
||||
|
@ -526,13 +526,13 @@ public class StateContainerTests : BaseTest
|
|||
public void Controller_SwitchesToStateFromSameStateSuccess()
|
||||
{
|
||||
controller.SwitchToState(StateKey.Loading);
|
||||
var label = controller.GetLayout().Children.First();
|
||||
var label = controller.GetLayout().Children[0];
|
||||
|
||||
Assert.IsType<Label>(label);
|
||||
Assert.Equal("Loading", ((Label)label).Text);
|
||||
|
||||
controller.SwitchToState(StateKey.Loading);
|
||||
label = controller.GetLayout().Children.First();
|
||||
label = controller.GetLayout().Children[0];
|
||||
|
||||
Assert.IsType<Label>(label);
|
||||
Assert.Equal("Loading", ((Label)label).Text);
|
||||
|
@ -542,7 +542,7 @@ public class StateContainerTests : BaseTest
|
|||
public void Controller_GridStateViewSpansParent()
|
||||
{
|
||||
gridController.SwitchToState(StateKey.Loading);
|
||||
var view = (View)gridController.GetLayout().Children.First();
|
||||
var view = (View)gridController.GetLayout().Children[0];
|
||||
|
||||
Assert.Equal(Grid.GetColumnSpan(view), grid.ColumnDefinitions.Count);
|
||||
Assert.Equal(Grid.GetRowSpan(view), grid.RowDefinitions.Count);
|
||||
|
|
|
@ -39,7 +39,7 @@ sealed class MockDispatcherProvider : IDispatcherProvider, IDisposable
|
|||
}
|
||||
}
|
||||
|
||||
class DispatcherTimerStub : IDispatcherTimer, IDisposable
|
||||
sealed class DispatcherTimerStub : IDispatcherTimer, IDisposable
|
||||
{
|
||||
readonly DispatcherMock dispatcher;
|
||||
|
||||
|
|
|
@ -19,10 +19,6 @@ public partial class Toast
|
|||
return;
|
||||
}
|
||||
|
||||
if (isDisposing)
|
||||
{
|
||||
}
|
||||
|
||||
isDisposed = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,6 @@ public abstract class BaseBehavior<TView> : Behavior<TView> where TView : Visual
|
|||
defaultBindingContextBinding = null;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -117,6 +116,6 @@ public abstract class BaseBehavior<TView> : Behavior<TView> where TView : Visual
|
|||
catch (Exception ex) when (Options.ShouldSuppressExceptionsInBehaviors)
|
||||
{
|
||||
Trace.WriteLine(ex);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -33,7 +33,7 @@ public class EventToCommandBehavior : BaseBehavior<VisualElement>
|
|||
public static readonly BindableProperty EventArgsConverterProperty =
|
||||
BindableProperty.Create(nameof(EventArgsConverter), typeof(IValueConverter), typeof(EventToCommandBehavior));
|
||||
|
||||
readonly MethodInfo eventHandlerMethodInfo = typeof(EventToCommandBehavior).GetTypeInfo()?.GetDeclaredMethod(nameof(OnTriggerHandled)) ?? throw new InvalidOperationException($"Cannot find method {nameof(OnTriggerHandled)}");
|
||||
readonly MethodInfo eventHandlerMethodInfo = typeof(EventToCommandBehavior).GetTypeInfo().GetDeclaredMethod(nameof(OnTriggerHandled)) ?? throw new InvalidOperationException($"Cannot find method {nameof(OnTriggerHandled)}");
|
||||
|
||||
Delegate? eventHandler;
|
||||
|
||||
|
@ -102,7 +102,7 @@ public class EventToCommandBehavior : BaseBehavior<VisualElement>
|
|||
return;
|
||||
}
|
||||
|
||||
eventInfo = View.GetType()?.GetRuntimeEvent(eventName) ??
|
||||
eventInfo = View.GetType().GetRuntimeEvent(eventName) ??
|
||||
throw new ArgumentException($"{nameof(EventToCommandBehavior)}: Couldn't resolve the event.", nameof(EventName));
|
||||
|
||||
ArgumentNullException.ThrowIfNull(eventInfo.EventHandlerType);
|
||||
|
|
|
@ -118,14 +118,7 @@ public partial class IconTintColorBehavior
|
|||
|
||||
void LoadAndApplyImageTintColor(View element, WImage image, Color color)
|
||||
{
|
||||
if (image.IsLoaded)
|
||||
{
|
||||
ApplyTintColor();
|
||||
}
|
||||
else
|
||||
{
|
||||
image.ImageOpened += OnImageOpened;
|
||||
}
|
||||
image.ImageOpened += OnImageOpened;
|
||||
|
||||
void OnImageOpened(object sender, RoutedEventArgs e)
|
||||
{
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Runtime.Versioning;
|
||||
using System.Text;
|
||||
|
@ -74,7 +75,7 @@ public class SelectAllTextBehavior : PlatformBehavior<InputView>
|
|||
{
|
||||
if (OperatingSystem.IsMacCatalyst())
|
||||
{
|
||||
Console.WriteLine("WARNING: `SelectAllTextBehavior` does not support `Microsoft.Maui.Controls.Editor` on MacCatalyst. For more information, see https://github.com/CommunityToolkit/Maui/issues/432");
|
||||
Trace.WriteLine("WARNING: `SelectAllTextBehavior` does not support `Microsoft.Maui.Controls.Editor` on MacCatalyst. For more information, see https://github.com/CommunityToolkit/Maui/issues/432");
|
||||
}
|
||||
|
||||
if (element is not Editor mauiControl)
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net7.0;net7.0-android;net7.0-ios;net7.0-maccatalyst</TargetFrameworks>
|
||||
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net7.0-windows10.0.19041.0</TargetFrameworks>
|
||||
<TargetFrameworks Condition="'$(IncludeTizenTargetFrameworks)' == 'true'">$(TargetFrameworks);net7.0-tizen</TargetFrameworks>
|
||||
<TargetFrameworks>$(NetVersion);$(NetVersion)-android;$(NetVersion)-ios;$(NetVersion)-maccatalyst</TargetFrameworks>
|
||||
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);$(NetVersion)-windows10.0.19041.0</TargetFrameworks>
|
||||
<TargetFrameworks Condition="'$(IncludeTizenTargetFrameworks)' == 'true'">$(TargetFrameworks);$(NetVersion)-tizen</TargetFrameworks>
|
||||
<UseMaui>true</UseMaui>
|
||||
<SingleProject>true</SingleProject>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
|
@ -26,7 +26,7 @@
|
|||
<Authors>Microsoft</Authors>
|
||||
<Owners>Microsoft</Owners>
|
||||
<NeutralLanguage>en</NeutralLanguage>
|
||||
<Product>CommunityToolkit.Maui (net7.0)</Product>
|
||||
<Product>CommunityToolkit.Maui ($(NetVersion))</Product>
|
||||
<Copyright>© Microsoft Corporation. All rights reserved.</Copyright>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
<PackageProjectUrl>https://github.com/CommunityToolkit/Maui</PackageProjectUrl>
|
||||
|
@ -67,6 +67,11 @@
|
|||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
||||
<PackageReference Include="MemoryAnalyzers" Version="0.1.0-beta.3">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -76,7 +76,7 @@ public abstract class CompareConverter<TObject> : BaseConverterOneWay<IComparabl
|
|||
public TObject? FalseObject { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Converts an object that implements IComparable to a specified object or a boolean based on a comparaison result.
|
||||
/// Converts an object that implements IComparable to a specified object or a boolean based on a comparison result.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to convert.</param>
|
||||
/// <param name="culture">The culture to use in the converter. This is not implemented.</param>
|
||||
|
@ -90,7 +90,7 @@ public abstract class CompareConverter<TObject> : BaseConverterOneWay<IComparabl
|
|||
|
||||
if (!Enum.IsDefined(typeof(OperatorType), ComparisonOperator))
|
||||
{
|
||||
throw new ArgumentOutOfRangeException($"is expected to be of type {nameof(OperatorType)}", nameof(ComparisonOperator));
|
||||
throw new ArgumentOutOfRangeException(nameof(ComparisonOperator), ComparingValue, $"is expected to be of type {nameof(OperatorType)}");
|
||||
}
|
||||
|
||||
if (!(TrueObject is null ^ FalseObject is not null))
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using CommunityToolkit.Maui.Core;
|
||||
using CommunityToolkit.Maui.Core.Handlers;
|
||||
using Microsoft.Maui.Controls;
|
||||
using Microsoft.Maui.Handlers;
|
||||
using Microsoft.Maui.Platform;
|
||||
|
||||
|
@ -26,7 +27,8 @@ public partial class Popup
|
|||
view.SetBinding(BindingContextProperty, new Binding { Source = virtualView, Path = BindingContextProperty.PropertyName });
|
||||
var contentPage = new ContentPage
|
||||
{
|
||||
Content = view
|
||||
Content = view,
|
||||
Parent = virtualView.Parent as Element
|
||||
};
|
||||
|
||||
return (PageHandler)contentPage.ToHandler(mauiContext);
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
using CommunityToolkit.Maui.Core.Handlers;
|
||||
using CommunityToolkit.Maui.Core.Views;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
|
||||
namespace CommunityToolkit.Maui.Views;
|
||||
|
||||
public partial class Popup
|
||||
{
|
||||
void OnPopupHandlerChanged(object? sender, EventArgs e)
|
||||
{
|
||||
if (Handler?.PlatformView is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
((MauiPopup)Handler.PlatformView).SetUpPlatformView(CleanUp, CreateWrapperContent);
|
||||
|
||||
static void CleanUp(Panel wrapper)
|
||||
{
|
||||
((WrapperControl)wrapper).CleanUp();
|
||||
}
|
||||
|
||||
static Panel? CreateWrapperContent(PopupHandler handler)
|
||||
{
|
||||
if (handler.VirtualView.Content is null || handler.MauiContext is null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return new WrapperControl((View)handler.VirtualView.Content, handler.MauiContext);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -56,9 +56,6 @@ public partial class Popup : Element, IPopup, IWindowController, IPropertyPropag
|
|||
platformConfigurationRegistry = new Lazy<PlatformConfigurationRegistry<Popup>>(() => new(this));
|
||||
|
||||
VerticalOptions = HorizontalOptions = LayoutAlignment.Center;
|
||||
#if WINDOWS
|
||||
this.HandlerChanged += OnPopupHandlerChanged;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -52,6 +52,8 @@ public static partial class PopupExtensions
|
|||
/// </returns>
|
||||
public static Task<object?> ShowPopupAsync<TPopup>(this Page page, TPopup popup) where TPopup : Popup
|
||||
{
|
||||
page = PageExtensions.GetCurrentPage(page);
|
||||
|
||||
if (page.IsPlatformEnabled)
|
||||
{
|
||||
return CreateAndShowPopupAsync(page, popup);
|
||||
|
|
Загрузка…
Ссылка в новой задаче