Skip to content

Commit

Permalink
Merge pull request #29 from muak/fix/DisconnectHandler
Browse files Browse the repository at this point in the history
Fix DisconnectHandler
  • Loading branch information
muak committed Jun 7, 2024
2 parents ba9649b + 3899b47 commit e27ee72
Show file tree
Hide file tree
Showing 8 changed files with 141 additions and 28 deletions.
28 changes: 27 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,20 @@ public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.UseMauiApp<App>()
.UseSettingsView() // write this
...
}
```

OR

```cs
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureMauiHandlers(handlers =>
{
handlers.AddSettingsViewHandler(); // write this
Expand All @@ -69,6 +82,19 @@ public static MauiApp CreateMauiApp()
}
```

## Options

MAUI has a fatal flaw in that the DisconnectHandler of the control is not automatically called.
(https://github.com/dotnet/maui/issues/18366)
SettingsView has an option to call DisconnectHandler on PageUnload to clean up.
To enable this, do the following.

```cs
...
.UseSettingsView(true)
...
```

## How to write with xaml

```xml
Expand Down
37 changes: 37 additions & 0 deletions SettingsView/Extensions/HandlerCleanUpHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using System;
using Microsoft.Maui.Handlers;

namespace AiForms.Settings.Extensions;

public static class HandlerCleanUpHelper
{
public static void AddCleanUpEvent(this View view)
{
if (view is not Element element)
{
return;
}

Page parentPage;

void PageUnloaded(object sender, EventArgs e)
{
view.Handler?.DisconnectHandler();
if (parentPage is not null)
{
parentPage.Unloaded -= PageUnloaded;
parentPage = null;
}
}

foreach (var el in element.GetParentsPath())
{
if (el is Page page)
{
parentPage = page;
page.Unloaded += PageUnloaded;
}
}
}
}

18 changes: 18 additions & 0 deletions SettingsView/Handlers/SettingsViewHandler.Android.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using AiForms.Settings.Extensions;
using AiForms.Settings.Platforms.Droid;
using Android.Views;
using AndroidX.RecyclerView.Widget;
Expand Down Expand Up @@ -28,6 +29,23 @@ protected override AiRecyclerView CreatePlatformView()
return new AiRecyclerView(Context, VirtualView);
}

protected override void ConnectHandler(AiRecyclerView platformView)
{
base.ConnectHandler(platformView);

if (SettingsViewConfiguration.ShouldAutoDisconnect)
{
VirtualView.AddCleanUpEvent();
}
}

protected override void DisconnectHandler(AiRecyclerView platformView)
{
base.DisconnectHandler(platformView);

platformView.Dispose();
}

private static void MapSeparatorColor(SettingsViewHandler handler, SettingsView sv)
{
handler.PlatformView.UpdateSeparatorColor();
Expand Down
46 changes: 25 additions & 21 deletions SettingsView/Handlers/SettingsViewHandler.iOS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using Microsoft.Maui.Controls.Compatibility.Platform.iOS;
using Microsoft.Maui.Platform;
using MobileCoreServices;
using AiForms.Settings.Extensions;

namespace AiForms.Settings.Handlers;

Expand Down Expand Up @@ -42,8 +43,6 @@ protected override AiTableView CreatePlatformView()
VirtualView.SectionCollectionChanged += OnSectionCollectionChanged;
VirtualView.SectionPropertyChanged += OnSectionPropertyChanged;
VirtualView.CellPropertyChanged += OnCellPropertyChanged;

VirtualView.ParentChanged += ParentChanged;

_insetTracker = new KeyboardInsetTracker(_tableview, () => PlatformView.Window, insets => PlatformView.ContentInset = PlatformView.ScrollIndicatorInsets = insets, point =>
{
Expand All @@ -55,31 +54,36 @@ protected override AiTableView CreatePlatformView()
_contentSizeObserver = _tableview.AddObserver("contentSize", NSKeyValueObservingOptions.New, OnContentSizeChanged);

return _tableview;
}
void ParentChanged(object sender, EventArgs e)
}

protected override void ConnectHandler(AiTableView platformView)
{
Element elm = VirtualView;

while (elm != null)
{
elm = elm.Parent;
if (elm is Page)
{
break;
}
}
_parentPage = elm as Page;
_parentPage.Appearing += ParentPageAppearing;
VirtualView.ParentChanged -= ParentChanged;
base.ConnectHandler(platformView);

foreach (var el in VirtualView.GetParentsPath())
{
if (el is Page page)
{
_parentPage = page;
_parentPage.Appearing += ParentPageAppearing;
}
}

if (SettingsViewConfiguration.ShouldAutoDisconnect)
{
VirtualView.AddCleanUpEvent();
}
}

protected override void DisconnectHandler(AiTableView platformView)
{
_parentPage.Appearing -= ParentPageAppearing;
_parentPage = null;
if (_parentPage is not null)
{
_parentPage.Appearing -= ParentPageAppearing;
_parentPage = null;
}

_contentSizeObserver.Dispose();
_contentSizeObserver?.Dispose();
_contentSizeObserver = null;

VirtualView.CollectionChanged -= OnCollectionChanged;
Expand Down
18 changes: 18 additions & 0 deletions SettingsView/MauiAppBuilderExtension.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System;
namespace AiForms.Settings;

public static class MauiAppBuilderExtension
{
public static MauiAppBuilder UseSettingsView(this MauiAppBuilder builder, bool shouldCallDisconnectHandlerWhenPageUnloaded = false)
{
builder.ConfigureMauiHandlers(handler =>
{
handler.AddSettingsViewHandler();
});

SettingsViewConfiguration.ShouldAutoDisconnect = shouldCallDisconnectHandlerWhenPageUnloaded;

return builder;
}
}

12 changes: 7 additions & 5 deletions SettingsView/Platforms/Android/Cells/CellBaseView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -611,7 +611,12 @@ protected override void Dispose(bool disposing)
_imageLoader?.Reset();
_imageLoader = null;

if(_cell != null)
if (CellParent != null)
{
CellParent.PropertyChanged -= ParentPropertyChanged;
}

if (_cell != null)
{
_cell.PropertyChanged -= CellPropertyChanged;
if (_cell.Section != null)
Expand All @@ -622,11 +627,8 @@ protected override void Dispose(bool disposing)

//CellRenderer.SetRealCell(_cell, null);
_cell = null;
}

CellParent.PropertyChanged -= ParentPropertyChanged;
}


HintLabel?.Dispose();
HintLabel = null;
TitleLabel?.Dispose();
Expand Down
2 changes: 1 addition & 1 deletion SettingsView/SettingsView.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<Description>This is a flexible TableView specialized in settings for Android / iOS.
There are various cells such as (LabelCell,ButtonCell,CommandCell,SwitchCell,CheckboxCell,RadioCell,PickerCell,EntryCell,NumberPickerCell,TimePickerCell,DatePickerCell,CustomCell)</Description>
<PackageReleaseNotes>
Fix iOS Header/FooterView issue
Fix DisconnectHandler
</PackageReleaseNotes>
<PackageTags>MAUI TableView Cell Setting Configuration Option ListView UITableView RecyclerView ReOrder DragDrop</PackageTags>
</PropertyGroup>
Expand Down
8 changes: 8 additions & 0 deletions SettingsView/SettingsViewConfiguration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using System;
namespace AiForms.Settings;

internal static class SettingsViewConfiguration
{
internal static bool ShouldAutoDisconnect { get; set; }
}

0 comments on commit e27ee72

Please sign in to comment.