diff --git a/.github/workflows/dotnet-autoformat-pr-push.yml b/.github/workflows/dotnet-autoformat-pr-push.yml
index 16237d240a06..7eaab91d8e9f 100644
--- a/.github/workflows/dotnet-autoformat-pr-push.yml
+++ b/.github/workflows/dotnet-autoformat-pr-push.yml
@@ -18,7 +18,7 @@ jobs:
github.event.workflow_run.conclusion == 'success'
steps:
- name: 'Push autoformatted patch'
- uses: rolfbjarne/autoformat-push@v0.1
+ uses: rolfbjarne/autoformat-push@v0.2
with:
githubToken: ${{ secrets.GITHUB_TOKEN }}
- commentContents: 'Thank you for your pull request. We are auto-formating your source code to follow our code guidelines.'
\ No newline at end of file
+ commentContents: 'Thank you for your pull request. We are auto-formating your source code to follow our code guidelines.'
diff --git a/eng/Versions.props b/eng/Versions.props
index f4e06424be23..176543e11930 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -27,17 +27,17 @@
10.0.22621.755
1.0.4
- 7.0.2
- 7.0.2
- 7.0.2
- 7.0.2
+ 7.0.3
+ 7.0.3
+ 7.0.3
+ 7.0.3
7.0.1
7.0.1
7.0.1
- 7.0.2
- 7.0.2
+ 7.0.3
+ 7.0.3
7.0.1
- 7.0.2
+ 7.0.3
8.0.0-preview1.23067.2
3.3.3
@@ -51,7 +51,7 @@
4.3.0
4.3.0
6.0.0
- <_MicrosoftWebWebView2Version>1.0.1518.46
+ <_MicrosoftWebWebView2Version>1.0.1587.40
<_XamarinAndroidGlideVersion>4.13.2.2
diff --git a/eng/pipelines/common/pack.yml b/eng/pipelines/common/pack.yml
index 1db1fe361e4f..58ecc3e84d08 100644
--- a/eng/pipelines/common/pack.yml
+++ b/eng/pipelines/common/pack.yml
@@ -48,48 +48,57 @@ steps:
- pwsh: ./build.ps1 --target=dotnet --configuration="Release" --verbosity=diagnostic --nugetsource="${{ parameters.nugetFolder }}"
displayName: 'Install .NET'
retryCountOnTaskFailure: 3
+ workingDirectory: ${{ parameters.checkoutDirectory }}
env:
DOTNET_TOKEN: $(dotnetbuilds-internal-container-read-token)
PRIVATE_BUILD: $(PrivateBuild)
+
- pwsh: ./build.ps1 --target=dotnet-pack --configuration="Release" --verbosity=diagnostic --nugetsource="${{ parameters.nugetFolder }}"
displayName: 'Pack .NET Maui'
name: PackMaui
+ workingDirectory: ${{ parameters.checkoutDirectory }}
env:
DOTNET_TOKEN: $(dotnetbuilds-internal-container-read-token)
PRIVATE_BUILD: $(PrivateBuild)
+
- ${{ if eq(parameters.platform, 'Windows') }}:
- pwsh: ./build.ps1 --target=dotnet-diff --configuration="Release" --verbosity=diagnostic
displayName: 'Diff .NET Maui artifacts with NuGet'
+ workingDirectory: ${{ parameters.checkoutDirectory }}
+
# artifacts
- task: CopyFiles@2
condition: always()
displayName: 'Copy files to staging'
inputs:
Contents: |
- artifacts/**/*.*nupkg
- artifacts/**/*.zip
- artifacts/vs-workload.props
- eng/automation/SignList.xml
- !artifacts/docs-packs/**
+ ${{ parameters.checkoutDirectory }}/artifacts/**/*.*nupkg
+ ${{ parameters.checkoutDirectory }}/artifacts/**/*.zip
+ ${{ parameters.checkoutDirectory }}/artifacts/vs-workload.props
+ ${{ parameters.checkoutDirectory }}/eng/automation/SignList.xml
+ !${{ parameters.checkoutDirectory}}/artifacts/docs-packs/**
TargetFolder: $(build.artifactstagingdirectory)
flattenFolders: true
+
- task: CopyFiles@2
condition: always()
displayName: 'Copy metadata to staging'
inputs:
- SourceFolder: artifacts
+ SourceFolder: ${{ parameters.checkoutDirectory }}/artifacts
Contents: |
metadata/**
api-diff/**
TargetFolder: $(build.artifactstagingdirectory)
+
- task: CopyFiles@2
displayName: 'Copy Log Files'
condition: always()
inputs:
Contents: |
- artifacts/logs/**
+ ${{ parameters.checkoutDirectory }}/artifacts/logs/**
TargetFolder: $(build.artifactstagingdirectory)/logs
flattenFolders: true
+
- task: PublishBuildArtifacts@1
condition: always()
displayName: publish artifacts
@@ -101,6 +110,6 @@ steps:
condition: always()
displayName: publish docs artifacts
inputs:
- PathToPublish: artifacts/docs-packs
+ PathToPublish: ${{ parameters.checkoutDirectory }}/artifacts/docs-packs
ArtifactName: xml-docs
diff --git a/src/Controls/src/Core/BindableObject.cs b/src/Controls/src/Core/BindableObject.cs
index ab9a93d90853..04424724fd5f 100644
--- a/src/Controls/src/Core/BindableObject.cs
+++ b/src/Controls/src/Core/BindableObject.cs
@@ -31,7 +31,7 @@ public BindableObject()
readonly Dictionary _properties = new Dictionary(4);
bool _applying;
- object _inheritedContext;
+ WeakReference _inheritedContext;
///
public static readonly BindableProperty BindingContextProperty =
@@ -41,7 +41,7 @@ public BindableObject()
///
public object BindingContext
{
- get => _inheritedContext ?? GetValue(BindingContextProperty);
+ get => _inheritedContext?.Target ?? GetValue(BindingContextProperty);
set => SetValue(BindingContextProperty, value);
}
@@ -238,7 +238,7 @@ public static void SetInheritedBindingContext(BindableObject bindable, object va
if (bpContext != null && ((bpContext.Attributes & BindableContextAttributes.IsManuallySet) != 0))
return;
- object oldContext = bindable._inheritedContext;
+ object oldContext = bindable._inheritedContext?.Target;
if (ReferenceEquals(oldContext, value))
return;
@@ -253,7 +253,7 @@ public static void SetInheritedBindingContext(BindableObject bindable, object va
}
else
{
- bindable._inheritedContext = value;
+ bindable._inheritedContext = new WeakReference(value);
}
bindable.ApplyBindings(skipBindingContext: false, fromBindingContextChanged: true);
@@ -557,7 +557,7 @@ internal void ApplyBindings(bool skipBindingContext, bool fromBindingContextChan
static void BindingContextPropertyBindingChanging(BindableObject bindable, BindingBase oldBindingBase, BindingBase newBindingBase)
{
- object context = bindable._inheritedContext;
+ object context = bindable._inheritedContext?.Target;
var oldBinding = oldBindingBase as Binding;
var newBinding = newBindingBase as Binding;
diff --git a/src/Controls/src/Core/BindingExpression.cs b/src/Controls/src/Core/BindingExpression.cs
index 57bed11e3cbb..ab1fb95294f8 100644
--- a/src/Controls/src/Core/BindingExpression.cs
+++ b/src/Controls/src/Core/BindingExpression.cs
@@ -635,7 +635,7 @@ public void SubscribeTo(INotifyPropertyChanged source, PropertyChangedEventHandl
_listener.SetTarget(listener);
}
- public void Unsubscribe()
+ public void Unsubscribe(bool finalizer = false)
{
INotifyPropertyChanged source;
if (_source.TryGetTarget(out source) && source != null)
@@ -644,6 +644,10 @@ public void Unsubscribe()
if (bo != null)
bo.BindingContextChanged -= _bchandler;
+ // If we are called from a finalizer, WeakReference.SetTarget() can throw InvalidOperationException
+ if (finalizer)
+ return;
+
_source.SetTarget(null);
_listener.SetTarget(null);
}
@@ -668,6 +672,8 @@ class BindingExpressionPart
readonly PropertyChangedEventHandler _changeHandler;
WeakPropertyChangedProxy _listener;
+ ~BindingExpressionPart() => _listener?.Unsubscribe(finalizer: true);
+
public BindingExpressionPart(BindingExpression expression, string content, bool isIndexer = false)
{
_expression = expression;
diff --git a/src/Controls/src/Core/Brush.cs b/src/Controls/src/Core/Brush.cs
index 3cf80d7978c1..d4fc16021c19 100644
--- a/src/Controls/src/Core/Brush.cs
+++ b/src/Controls/src/Core/Brush.cs
@@ -7,11 +7,9 @@ namespace Microsoft.Maui.Controls
[System.ComponentModel.TypeConverter(typeof(BrushTypeConverter))]
public abstract partial class Brush : Element
{
+ static ImmutableBrush defaultBrush;
///
- public static Brush Default
- {
- get { return new SolidColorBrush(null); }
- }
+ public static Brush Default => defaultBrush ??= new(null);
public static implicit operator Brush(Color color) => new SolidColorBrush(color);
diff --git a/src/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellPageContainer.cs b/src/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellPageContainer.cs
index 01402e62d7a1..c58fcf794e9f 100644
--- a/src/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellPageContainer.cs
+++ b/src/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellPageContainer.cs
@@ -54,6 +54,8 @@ protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
aView.Measure(widthMeasureSpec, heightMeasureSpec);
SetMeasuredDimension(aView.MeasuredWidth, aView.MeasuredHeight);
}
+ else
+ SetMeasuredDimension(0, 0);
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/UIContainerCell.cs b/src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/UIContainerCell.cs
index 8eb17591c7c0..37cf75589330 100644
--- a/src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/UIContainerCell.cs
+++ b/src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/UIContainerCell.cs
@@ -25,7 +25,7 @@ internal UIContainerCell(string cellId, View view, Shell shell, object context)
if (_renderer == null)
{
- _renderer = (IPlatformViewHandler)view.ToHandler(shell.FindMauiContext());
+ _renderer = (IPlatformViewHandler)view.ToHandler(view.FindMauiContext() ?? shell.FindMauiContext());
}
ContentView.AddSubview(_renderer.PlatformView);
diff --git a/src/Controls/src/Core/Handlers/Items/ItemsViewHandler.Android.cs b/src/Controls/src/Core/Handlers/Items/ItemsViewHandler.Android.cs
index 95221dbf87ec..f3e189ae058f 100644
--- a/src/Controls/src/Core/Handlers/Items/ItemsViewHandler.Android.cs
+++ b/src/Controls/src/Core/Handlers/Items/ItemsViewHandler.Android.cs
@@ -21,6 +21,13 @@ protected override void ConnectHandler(RecyclerView platformView)
base.ConnectHandler(platformView);
(platformView as IMauiRecyclerView)?.SetUpNewElement(VirtualView);
}
+
+ protected override void DisconnectHandler(RecyclerView platformView)
+ {
+ base.DisconnectHandler(platformView);
+ (platformView as IMauiRecyclerView)?.TearDownOldElement(VirtualView);
+ }
+
protected override RecyclerView CreatePlatformView() =>
new MauiRecyclerView, IItemsViewSource>(Context, GetItemsLayout, CreateAdapter);
diff --git a/src/Controls/src/Core/Handlers/Shell/Windows/ShellView.cs b/src/Controls/src/Core/Handlers/Shell/Windows/ShellView.cs
index a2d73d03b60f..86628e1326e4 100644
--- a/src/Controls/src/Core/Handlers/Shell/Windows/ShellView.cs
+++ b/src/Controls/src/Core/Handlers/Shell/Windows/ShellView.cs
@@ -155,17 +155,25 @@ IEnumerable