Fix the AOT issue with custom binding of IsSelected property through CVS in Mail List.

This commit is contained in:
Burak Kaan Köse
2025-12-28 07:28:20 +01:00
parent 0f6aa66b21
commit f79305f0a6
5 changed files with 70 additions and 5 deletions
@@ -69,7 +69,7 @@ public partial class WinoListView : Microsoft.UI.Xaml.Controls.ListView
&& container.Item != mailItemViewModel) && container.Item != mailItemViewModel)
{ {
container.Item = mailItemViewModel; container.Item = mailItemViewModel;
container.IsSelected = mailItemViewModel.IsSelected; container.IsCustomSelected = mailItemViewModel.IsSelected;
} }
else if (item is ThreadMailItemViewModel threadMailItemViewModel else if (item is ThreadMailItemViewModel threadMailItemViewModel
&& element is WinoThreadMailItemViewModelListViewItem threadContainer && element is WinoThreadMailItemViewModelListViewItem threadContainer
@@ -88,7 +88,7 @@ public partial class WinoListView : Microsoft.UI.Xaml.Controls.ListView
if (item is MailItemViewModel mailItemViewModel && element is WinoMailItemViewModelListViewItem container) if (item is MailItemViewModel mailItemViewModel && element is WinoMailItemViewModelListViewItem container)
{ {
container.Item = null; container.Item = null;
container.IsSelected = false; container.IsCustomSelected = false;
} }
else if (item is ThreadMailItemViewModel threadMailItemViewModel && element is WinoThreadMailItemViewModelListViewItem threadContainer) else if (item is ThreadMailItemViewModel threadMailItemViewModel && element is WinoThreadMailItemViewModelListViewItem threadContainer)
{ {
@@ -49,7 +49,7 @@
HorizontalAlignment="Center" HorizontalAlignment="Center"
Background="{ThemeResource ListViewItemSelectionIndicatorBrush}" Background="{ThemeResource ListViewItemSelectionIndicatorBrush}"
CornerRadius="4" CornerRadius="4"
Visibility="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=Item.IsSelected, Mode=OneWay}" /> Visibility="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=IsCustomSelected, Mode=OneWay}" />
<!-- Expandable Content --> <!-- Expandable Content -->
<ContentPresenter <ContentPresenter
@@ -138,7 +138,7 @@
x:Name="SelectionBackground" x:Name="SelectionBackground"
Grid.ColumnSpan="2" Grid.ColumnSpan="2"
Background="{ThemeResource ListViewItemBackgroundSelected}" Background="{ThemeResource ListViewItemBackgroundSelected}"
Visibility="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=Item.IsSelected, Mode=OneWay}" /> Visibility="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=IsCustomSelected, Mode=OneWay}" />
<Border <Border
x:Name="SelectionIndicator" x:Name="SelectionIndicator"
Width="4" Width="4"
@@ -146,7 +146,7 @@
HorizontalAlignment="Center" HorizontalAlignment="Center"
Background="{ThemeResource ListViewItemSelectionIndicatorBrush}" Background="{ThemeResource ListViewItemSelectionIndicatorBrush}"
CornerRadius="4" CornerRadius="4"
Visibility="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=Item.IsSelected, Mode=OneWay}" /> Visibility="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=IsCustomSelected, Mode=OneWay}" />
<ContentPresenter <ContentPresenter
x:Name="MailContent" x:Name="MailContent"
@@ -1,16 +1,45 @@
using System.ComponentModel;
using System.Diagnostics;
using CommunityToolkit.WinUI; using CommunityToolkit.WinUI;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Controls;
using Wino.Mail.ViewModels.Data; using Wino.Mail.ViewModels.Data;
using WinRT;
namespace Wino.Mail.WinUI.Controls.ListView; namespace Wino.Mail.WinUI.Controls.ListView;
[GeneratedBindableCustomProperty]
public partial class WinoMailItemViewModelListViewItem : ListViewItem public partial class WinoMailItemViewModelListViewItem : ListViewItem
{ {
[GeneratedDependencyProperty] [GeneratedDependencyProperty]
public partial MailItemViewModel? Item { get; set; } public partial MailItemViewModel? Item { get; set; }
[GeneratedDependencyProperty]
public partial bool IsCustomSelected { get; set; }
public WinoMailItemViewModelListViewItem() public WinoMailItemViewModelListViewItem()
{ {
DefaultStyleKey = typeof(WinoMailItemViewModelListViewItem); DefaultStyleKey = typeof(WinoMailItemViewModelListViewItem);
} }
partial void OnItemPropertyChanged(DependencyPropertyChangedEventArgs e)
{
Debug.WriteLine("WinoMailItemViewModelListViewItem item changed");
if (e.OldValue is MailItemViewModel oldMailItemViewModel) UnregisterPropertyChanged(oldMailItemViewModel);
if (e.NewValue is MailItemViewModel newMailItemViewModel) RegisterPropertyChanged(newMailItemViewModel);
}
private void RegisterPropertyChanged(MailItemViewModel model) => model.PropertyChanged += ModelPropertyChanged;
private void UnregisterPropertyChanged(MailItemViewModel model) => model.PropertyChanged -= ModelPropertyChanged;
private void ModelPropertyChanged(object? sender, PropertyChangedEventArgs e)
{
if (sender is not MailItemViewModel mailItemViewModel) return;
if (e.PropertyName == nameof(MailItemViewModel.IsSelected))
{
IsCustomSelected = mailItemViewModel.IsSelected;
}
}
} }
@@ -1,12 +1,17 @@
using System.ComponentModel;
using System.Diagnostics;
using System.Linq; using System.Linq;
using CommunityToolkit.WinUI; using CommunityToolkit.WinUI;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Controls;
using Wino.Controls; using Wino.Controls;
using Wino.Helpers; using Wino.Helpers;
using Wino.Mail.ViewModels.Data; using Wino.Mail.ViewModels.Data;
using WinRT;
namespace Wino.Mail.WinUI.Controls.ListView; namespace Wino.Mail.WinUI.Controls.ListView;
[GeneratedBindableCustomProperty]
public partial class WinoThreadMailItemViewModelListViewItem : ListViewItem public partial class WinoThreadMailItemViewModelListViewItem : ListViewItem
{ {
[GeneratedDependencyProperty] [GeneratedDependencyProperty]
@@ -15,6 +20,8 @@ public partial class WinoThreadMailItemViewModelListViewItem : ListViewItem
[GeneratedDependencyProperty] [GeneratedDependencyProperty]
public partial ThreadMailItemViewModel? Item { get; set; } public partial ThreadMailItemViewModel? Item { get; set; }
[GeneratedDependencyProperty]
public partial bool IsCustomSelected { get; set; }
public WinoThreadMailItemViewModelListViewItem() public WinoThreadMailItemViewModelListViewItem()
{ {
@@ -31,4 +38,25 @@ public partial class WinoThreadMailItemViewModelListViewItem : ListViewItem
} }
public WinoExpander? GetExpander() => WinoVisualTreeHelper.FindDescendants<WinoExpander>(this).FirstOrDefault(); public WinoExpander? GetExpander() => WinoVisualTreeHelper.FindDescendants<WinoExpander>(this).FirstOrDefault();
partial void OnItemPropertyChanged(DependencyPropertyChangedEventArgs e)
{
Debug.WriteLine("WinoMailItemViewModelListViewItem item changed");
if (e.OldValue is ThreadMailItemViewModel oldMailItemViewModel) UnregisterPropertyChanged(oldMailItemViewModel);
if (e.NewValue is ThreadMailItemViewModel newMailItemViewModel) RegisterPropertyChanged(newMailItemViewModel);
}
private void RegisterPropertyChanged(ThreadMailItemViewModel model) => model.PropertyChanged += ModelPropertyChanged;
private void UnregisterPropertyChanged(ThreadMailItemViewModel model) => model.PropertyChanged -= ModelPropertyChanged;
private void ModelPropertyChanged(object? sender, PropertyChangedEventArgs e)
{
if (sender is not ThreadMailItemViewModel mailItemViewModel) return;
if (e.PropertyName == nameof(ThreadMailItemViewModel.IsSelected))
{
IsCustomSelected = mailItemViewModel.IsSelected;
}
}
} }
@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using CommunityToolkit.Mvvm.Collections;
using CommunityToolkit.Mvvm.Messaging; using CommunityToolkit.Mvvm.Messaging;
using CommunityToolkit.WinUI; using CommunityToolkit.WinUI;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
@@ -29,6 +30,13 @@ using Wino.Mail.WinUI.Extensions;
using Wino.MenuFlyouts.Context; using Wino.MenuFlyouts.Context;
using Wino.Messaging.Client.Mails; using Wino.Messaging.Client.Mails;
using Wino.Views.Abstract; using Wino.Views.Abstract;
using WinRT;
// object, IMailListItem
// Register generic types from CommunityToolkit.Mvvm for AOT compatibility when passed across WinRT boundary
[assembly: GeneratedWinRTExposedExternalType(typeof(ObservableGroup<object, IMailListItem>))]
[assembly: GeneratedWinRTExposedExternalType(typeof(ReadOnlyObservableGroup<object, IMailListItem>))]
[assembly: GeneratedWinRTExposedExternalType(typeof(ReadOnlyObservableGroupedCollection<object, IMailListItem>))]
namespace Wino.Views.Mail; namespace Wino.Views.Mail;