diff --git a/Directory.Packages.props b/Directory.Packages.props index 1eac7046..28a2ef2a 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -45,6 +45,7 @@ + diff --git a/Wino.Calendar.ViewModels/CalendarAppShellViewModel.cs b/Wino.Calendar.ViewModels/CalendarAppShellViewModel.cs index e0c69066..580f2c88 100644 --- a/Wino.Calendar.ViewModels/CalendarAppShellViewModel.cs +++ b/Wino.Calendar.ViewModels/CalendarAppShellViewModel.cs @@ -150,7 +150,7 @@ public partial class CalendarAppShellViewModel : CalendarBaseViewModel, private async Task InitializeAccountCalendarsAsync() { - await Dispatcher.ExecuteOnUIThread(() => AccountCalendarStateService.ClearGroupedAccountCalendar()); + await Dispatcher.ExecuteOnUIThread(() => AccountCalendarStateService.ClearGroupedAccountCalendars()); var accounts = await _accountService.GetAccountsAsync().ConfigureAwait(false); diff --git a/Wino.Calendar.ViewModels/CalendarPageViewModel.cs b/Wino.Calendar.ViewModels/CalendarPageViewModel.cs index b58fc99b..a1b6e348 100644 --- a/Wino.Calendar.ViewModels/CalendarPageViewModel.cs +++ b/Wino.Calendar.ViewModels/CalendarPageViewModel.cs @@ -611,8 +611,6 @@ public partial class CalendarPageViewModel : CalendarBaseViewModel, } } - - private async Task InitializeCalendarEventsForDayRangeAsync(DayRangeRenderModel dayRangeRenderModel) { // Clear all events first for all days. @@ -626,9 +624,8 @@ public partial class CalendarPageViewModel : CalendarBaseViewModel, // Initialization is done for all calendars, regardless whether they are actively selected or not. // This is because the filtering is cached internally of the calendar items in CalendarEventCollection. - var allCalendars = AccountCalendarStateService.GroupedAccountCalendars.SelectMany(a => a.AccountCalendars); - foreach (var calendarViewModel in allCalendars) + foreach (var calendarViewModel in AccountCalendarStateService.AllCalendars) { // Check all the events for the given date range and calendar. // Then find the day representation for all the events returned, and add to the collection. diff --git a/Wino.Calendar.ViewModels/Data/GroupedAccountCalendarViewModel.cs b/Wino.Calendar.ViewModels/Data/GroupedAccountCalendarViewModel.cs index 28b05f6a..cf5df346 100644 --- a/Wino.Calendar.ViewModels/Data/GroupedAccountCalendarViewModel.cs +++ b/Wino.Calendar.ViewModels/Data/GroupedAccountCalendarViewModel.cs @@ -69,10 +69,10 @@ public partial class GroupedAccountCalendarViewModel : ObservableObject } [ObservableProperty] - private bool _isExpanded = true; + public partial bool IsExpanded { get; set; } = true; [ObservableProperty] - private bool? isCheckedState = true; + public partial bool? IsCheckedState { get; set; } = true; private bool _isExternalPropChangeBlocked = false; diff --git a/Wino.Calendar.ViewModels/Interfaces/IAccountCalendarStateService.cs b/Wino.Calendar.ViewModels/Interfaces/IAccountCalendarStateService.cs index c0d4dd61..014ede02 100644 --- a/Wino.Calendar.ViewModels/Interfaces/IAccountCalendarStateService.cs +++ b/Wino.Calendar.ViewModels/Interfaces/IAccountCalendarStateService.cs @@ -15,7 +15,7 @@ public interface IAccountCalendarStateService : INotifyPropertyChanged public void AddGroupedAccountCalendar(GroupedAccountCalendarViewModel groupedAccountCalendar); public void RemoveGroupedAccountCalendar(GroupedAccountCalendarViewModel groupedAccountCalendar); - public void ClearGroupedAccountCalendar(); + public void ClearGroupedAccountCalendars(); public void AddAccountCalendar(AccountCalendarViewModel accountCalendar); public void RemoveAccountCalendar(AccountCalendarViewModel accountCalendar); @@ -24,5 +24,5 @@ public interface IAccountCalendarStateService : INotifyPropertyChanged /// Enumeration of currently selected calendars. /// IEnumerable ActiveCalendars { get; } - // IEnumerable> GroupedAccountCalendarsEnumerable { get; } + IEnumerable AllCalendars { get; } } diff --git a/Wino.Mail.WinUI/Controls/Calendar/CustomCalendarFlipView.cs b/Wino.Mail.WinUI/Controls/Calendar/CustomCalendarFlipView.cs index d52dd761..b564e833 100644 --- a/Wino.Mail.WinUI/Controls/Calendar/CustomCalendarFlipView.cs +++ b/Wino.Mail.WinUI/Controls/Calendar/CustomCalendarFlipView.cs @@ -1,5 +1,8 @@ -using Microsoft.UI.Xaml.Automation.Peers; +using System.Linq; +using Microsoft.UI.Xaml; +using Microsoft.UI.Xaml.Automation.Peers; using Microsoft.UI.Xaml.Controls; +using Wino.Mail.WinUI.Controls.CalendarFlipView; namespace Wino.Calendar.Controls; @@ -11,21 +14,37 @@ public partial class CustomCalendarFlipView : FlipView private const string PART_PreviousButton = "PreviousButtonHorizontal"; private const string PART_NextButton = "NextButtonHorizontal"; - private Button PreviousButton; - private Button NextButton; + private Button? PreviousButton; + private Button? NextButton; protected override void OnApplyTemplate() { base.OnApplyTemplate(); - PreviousButton = GetTemplateChild(PART_PreviousButton) as Button; - NextButton = GetTemplateChild(PART_NextButton) as Button; + PreviousButton = (Button)GetTemplateChild(PART_PreviousButton); + NextButton = (Button)GetTemplateChild(PART_NextButton); // Hide navigation buttons PreviousButton.Opacity = NextButton.Opacity = 0; PreviousButton.IsHitTestVisible = NextButton.IsHitTestVisible = false; + + this.SelectionChanged += FlipViewSelectionChanged; } + private void FlipViewSelectionChanged(object sender, SelectionChangedEventArgs e) => OnSelectedItemChanged(e.RemovedItems.FirstOrDefault(), e.AddedItems.FirstOrDefault()); + + protected virtual void OnSelectedItemChanged(object oldValue, object newValue) { } + + protected override void PrepareContainerForItemOverride(DependencyObject element, object item) + { + base.PrepareContainerForItemOverride(element, item); + OnContainerPrepared(element, item); + } + + protected virtual void OnContainerPrepared(DependencyObject element, object item) { } + + protected override DependencyObject GetContainerForItemOverride() => new WinoCalendarFlyoutItem(); + public void GoPreviousFlip() { var backPeer = new ButtonAutomationPeer(PreviousButton); diff --git a/Wino.Mail.WinUI/Controls/Calendar/WinoCalendarControl.cs b/Wino.Mail.WinUI/Controls/Calendar/WinoCalendarControl.cs index 0889205b..d5d01f4e 100644 --- a/Wino.Mail.WinUI/Controls/Calendar/WinoCalendarControl.cs +++ b/Wino.Mail.WinUI/Controls/Calendar/WinoCalendarControl.cs @@ -187,8 +187,6 @@ public partial class WinoCalendarControl : Control canvas.SelectedDateTime = null; canvas.TimelineCellSelected -= ActiveTimelineCellSelected; canvas.TimelineCellUnselected -= ActiveTimelineCellUnselected; - - canvas.Dispose(); } private void RegisterCanvas(WinoDayTimelineCanvas canvas) diff --git a/Wino.Mail.WinUI/Controls/Calendar/WinoCalendarFlipView.cs b/Wino.Mail.WinUI/Controls/Calendar/WinoCalendarFlipView.cs index de9ba8ad..9bef5b1b 100644 --- a/Wino.Mail.WinUI/Controls/Calendar/WinoCalendarFlipView.cs +++ b/Wino.Mail.WinUI/Controls/Calendar/WinoCalendarFlipView.cs @@ -20,9 +20,9 @@ public partial class WinoCalendarFlipView : CustomCalendarFlipView /// Gets or sets the active canvas that is currently displayed in the flip view. /// Each day-range of flip view item has a canvas that displays the day timeline. /// - public WinoDayTimelineCanvas ActiveCanvas + public WinoDayTimelineCanvas? ActiveCanvas { - get { return (WinoDayTimelineCanvas)GetValue(ActiveCanvasProperty); } + get { return (WinoDayTimelineCanvas?)GetValue(ActiveCanvasProperty); } set { SetValue(ActiveCanvasProperty, value); } } @@ -31,9 +31,9 @@ public partial class WinoCalendarFlipView : CustomCalendarFlipView /// It's the vertical scroll that scrolls the timeline only, not the header part that belongs /// to parent FlipView control. /// - public ScrollViewer ActiveVerticalScrollViewer + public ScrollViewer? ActiveVerticalScrollViewer { - get { return (ScrollViewer)GetValue(ActiveVerticalScrollViewerProperty); } + get { return (ScrollViewer?)GetValue(ActiveVerticalScrollViewerProperty); } set { SetValue(ActiveVerticalScrollViewerProperty, value); } } @@ -45,7 +45,6 @@ public partial class WinoCalendarFlipView : CustomCalendarFlipView public WinoCalendarFlipView() { - RegisterPropertyChangedCallback(SelectedIndexProperty, new DependencyPropertyChangedCallback(OnSelectedIndexUpdated)); RegisterPropertyChangedCallback(ItemsSourceProperty, new DependencyPropertyChangedCallback(OnItemsSourceChanged)); } @@ -57,15 +56,6 @@ public partial class WinoCalendarFlipView : CustomCalendarFlipView } } - private static void OnSelectedIndexUpdated(DependencyObject d, DependencyProperty e) - { - if (d is WinoCalendarFlipView flipView) - { - flipView.UpdateActiveCanvas(); - flipView.UpdateActiveScrollViewer(); - } - } - private void RegisterItemsSourceChange() { if (GetItemsSource() is INotifyCollectionChanged notifyCollectionChanged) @@ -74,61 +64,51 @@ public partial class WinoCalendarFlipView : CustomCalendarFlipView } } + protected override void OnSelectedItemChanged(object oldValue, object newValue) + { + base.OnSelectedItemChanged(oldValue, newValue); + + UpdateActiveElements(); + } + + protected override void OnContainerPrepared(DependencyObject element, object item) + { + base.OnContainerPrepared(element, item); + + // Check if this is the currently selected item's container + var index = IndexFromContainer(element); + if (index >= 0 && index == SelectedIndex) + { + // Container for selected item is now ready, update active elements + UpdateActiveElements(); + } + } + private void ItemsSourceUpdated(object sender, NotifyCollectionChangedEventArgs e) { IsIdle = e.Action == NotifyCollectionChangedAction.Reset || e.Action == NotifyCollectionChangedAction.Replace; } - private async Task GetCurrentFlipViewItem() - { - // TODO: Refactor this mechanism by listening to PrepareContainerForItemOverride and Loaded events together. - while (ContainerFromIndex(SelectedIndex) == null) - { - await Task.Delay(100); - } - - return ContainerFromIndex(SelectedIndex) as FlipViewItem; - } - - private void UpdateActiveScrollViewer() + private void UpdateActiveElements() { if (SelectedIndex < 0) - ActiveVerticalScrollViewer = null; - else { - GetCurrentFlipViewItem().ContinueWith(task => - { - if (task.IsCompletedSuccessfully) - { - var flipViewItem = task.Result; - - _ = DispatcherQueue.TryEnqueue(() => - { - ActiveVerticalScrollViewer = flipViewItem.FindDescendant(); - }); - } - }); - } - } - - public void UpdateActiveCanvas() - { - if (SelectedIndex < 0) ActiveCanvas = null; + ActiveVerticalScrollViewer = null; + return; + } + + // Get container from index - respects virtualization + if (ContainerFromIndex(SelectedIndex) is FlipViewItem container) + { + ActiveCanvas = container.FindDescendant(); + ActiveVerticalScrollViewer = container.FindDescendant(); + } else { - GetCurrentFlipViewItem().ContinueWith(task => - { - if (task.IsCompletedSuccessfully) - { - var flipViewItem = task.Result; - - _ = DispatcherQueue.TryEnqueue(() => - { - ActiveCanvas = flipViewItem.FindDescendant(); - }); - } - }); + // Container not ready yet - will be updated when OnContainerPrepared is called + ActiveCanvas = null; + ActiveVerticalScrollViewer = null; } } diff --git a/Wino.Mail.WinUI/Controls/Calendar/WinoDayTimelineCanvas.cs b/Wino.Mail.WinUI/Controls/Calendar/WinoDayTimelineCanvas.cs index f2566fb3..b318388e 100644 --- a/Wino.Mail.WinUI/Controls/Calendar/WinoDayTimelineCanvas.cs +++ b/Wino.Mail.WinUI/Controls/Calendar/WinoDayTimelineCanvas.cs @@ -2,13 +2,13 @@ using System.Diagnostics; using System.Linq; using CommunityToolkit.WinUI; -using Microsoft.Graphics.Canvas.Geometry; -using Microsoft.Graphics.Canvas.UI.Xaml; using Microsoft.UI.Input; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Input; using Microsoft.UI.Xaml.Media; +using SkiaSharp; +using SkiaSharp.Views.Windows; using Windows.Foundation; using Wino.Calendar.Args; using Wino.Core.Domain.Models.Calendar; @@ -21,7 +21,7 @@ public partial class WinoDayTimelineCanvas : Control, IDisposable public event EventHandler TimelineCellUnselected; private const string PART_InternalCanvas = nameof(PART_InternalCanvas); - private CanvasControl Canvas; + private SKXamlCanvas Canvas; public static readonly DependencyProperty RenderOptionsProperty = DependencyProperty.Register(nameof(RenderOptions), typeof(CalendarRenderOptions), typeof(WinoDayTimelineCanvas), new PropertyMetadata(null, new PropertyChangedCallback(OnRenderingPropertiesChanged))); public static readonly DependencyProperty SeperatorColorProperty = DependencyProperty.Register(nameof(SeperatorColor), typeof(SolidColorBrush), typeof(WinoDayTimelineCanvas), new PropertyMetadata(null, new PropertyChangedCallback(OnRenderingPropertiesChanged))); @@ -77,11 +77,13 @@ public partial class WinoDayTimelineCanvas : Control, IDisposable { base.OnApplyTemplate(); - Canvas = GetTemplateChild(PART_InternalCanvas) as CanvasControl; + Canvas = GetTemplateChild(PART_InternalCanvas) as SKXamlCanvas; - // TODO: These will leak. Dispose them properly when needed. - Canvas.Draw += OnCanvasDraw; - Canvas.PointerPressed += OnCanvasPointerPressed; + if (Canvas != null) + { + Canvas.PaintSurface += OnCanvasPaintSurface; + Canvas.PointerPressed += OnCanvasPointerPressed; + } ForceDraw(); } @@ -179,21 +181,23 @@ public partial class WinoDayTimelineCanvas : Control, IDisposable { return RenderOptions != null && Canvas != null - && Canvas.ReadyToDraw && WorkingHourCellBackgroundColor != null && SeperatorColor != null && HalfHourSeperatorColor != null && SelectedCellBackgroundBrush != null; } - private void OnCanvasDraw(CanvasControl sender, CanvasDrawEventArgs args) + private void OnCanvasPaintSurface(object sender, SKPaintSurfaceEventArgs e) { if (!CanDrawTimeline()) return; + var canvas = e.Surface.Canvas; + canvas.Clear(SKColors.Transparent); + int hours = 24; - double canvasWidth = Canvas.ActualWidth; - double canvasHeight = Canvas.ActualHeight; + double canvasWidth = e.Info.Width; + double canvasHeight = e.Info.Height; if (canvasWidth == 0 || canvasHeight == 0) return; @@ -205,9 +209,33 @@ public partial class WinoDayTimelineCanvas : Control, IDisposable double rectHeight = RenderOptions.CalendarSettings.HourHeight; // Define stroke and fill colors - var strokeColor = SeperatorColor.Color; + var strokeColor = ToSKColor(SeperatorColor.Color); float strokeThickness = 0.5f; + // Create paints for drawing + using var strokePaint = new SKPaint + { + Color = strokeColor, + StrokeWidth = strokeThickness, + Style = SKPaintStyle.Stroke, + IsAntialias = true + }; + + using var fillPaint = new SKPaint + { + Style = SKPaintStyle.Fill, + IsAntialias = true + }; + + using var dashedPaint = new SKPaint + { + Color = ToSKColor(HalfHourSeperatorColor.Color), + StrokeWidth = strokeThickness, + Style = SKPaintStyle.Stroke, + PathEffect = SKPathEffect.CreateDash([2f, 2f], 0), + IsAntialias = true + }; + for (int day = 0; day < RenderOptions.TotalDayCount; day++) { var currentDay = RenderOptions.DateRange.StartDate.AddDays(day); @@ -222,32 +250,31 @@ public partial class WinoDayTimelineCanvas : Control, IDisposable var representingDateTime = currentDay.AddHours(hour); // Calculate the position and size of the rectangle - double x = day * rectWidth; - double y = hour * rectHeight; + float x = (float)(day * rectWidth); + float y = (float)(hour * rectHeight); + float width = (float)rectWidth; + float height = (float)rectHeight; - var rectangle = new Rect(x, y, rectWidth, rectHeight); + var rectangle = new SKRect(x, y, x + width, y + height); // Draw the rectangle border. // This is the main rectangle. - args.DrawingSession.DrawRectangle(rectangle, strokeColor, strokeThickness); + canvas.DrawRect(rectangle, strokePaint); // Fill another rectangle with the working hour background color // This rectangle must be placed with -1 margin to prevent invisible borders of the main rectangle. if (isWorkingDay && renderTime >= RenderOptions.CalendarSettings.WorkingHourStart && renderTime <= RenderOptions.CalendarSettings.WorkingHourEnd) { - var backgroundRectangle = new Rect(x + 1, y + 1, rectWidth - 1, rectHeight - 1); + var backgroundRectangle = new SKRect(x + 1, y + 1, x + width - 1, y + height - 1); - args.DrawingSession.DrawRectangle(backgroundRectangle, strokeColor, strokeThickness); - args.DrawingSession.FillRectangle(backgroundRectangle, WorkingHourCellBackgroundColor.Color); + canvas.DrawRect(backgroundRectangle, strokePaint); + fillPaint.Color = ToSKColor(WorkingHourCellBackgroundColor.Color); + canvas.DrawRect(backgroundRectangle, fillPaint); } // Draw a line in the center of the rectangle for representing half hours. - double lineY = y + rectHeight / 2; - - args.DrawingSession.DrawLine((float)x, (float)lineY, (float)(x + rectWidth), (float)lineY, HalfHourSeperatorColor.Color, strokeThickness, new CanvasStrokeStyle() - { - DashStyle = CanvasDashStyle.Dot - }); + float lineY = y + height / 2; + canvas.DrawLine(x, lineY, x + width, lineY, dashedPaint); } // Draw selected item background color for the date if possible. @@ -265,20 +292,30 @@ public partial class WinoDayTimelineCanvas : Control, IDisposable selectedY += rectHeight / 2; } - var selectedRectangle = new Rect(day * rectWidth, selectedY, rectWidth, selectionRectHeight); - args.DrawingSession.FillRectangle(selectedRectangle, SelectedCellBackgroundBrush.Color); + var selectedRectangle = new SKRect( + (float)(day * rectWidth), + (float)selectedY, + (float)(day * rectWidth + rectWidth), + (float)(selectedY + selectionRectHeight)); + + fillPaint.Color = ToSKColor(SelectedCellBackgroundBrush.Color); + canvas.DrawRect(selectedRectangle, fillPaint); } } } } + private static SKColor ToSKColor(Windows.UI.Color color) + { + return new SKColor(color.R, color.G, color.B, color.A); + } + public void Dispose() { if (Canvas == null) return; - Canvas.Draw -= OnCanvasDraw; + Canvas.PaintSurface -= OnCanvasPaintSurface; Canvas.PointerPressed -= OnCanvasPointerPressed; - Canvas.RemoveFromVisualTree(); Canvas = null; } diff --git a/Wino.Mail.WinUI/Controls/CalendarFlipView/WinoCalendarFlyoutItem.cs b/Wino.Mail.WinUI/Controls/CalendarFlipView/WinoCalendarFlyoutItem.cs new file mode 100644 index 00000000..86dc16a5 --- /dev/null +++ b/Wino.Mail.WinUI/Controls/CalendarFlipView/WinoCalendarFlyoutItem.cs @@ -0,0 +1,11 @@ +using Microsoft.UI.Xaml.Controls; + +namespace Wino.Mail.WinUI.Controls.CalendarFlipView; + +public partial class WinoCalendarFlyoutItem : FlipViewItem +{ + public WinoCalendarFlyoutItem() + { + DefaultStyleKey = typeof(WinoCalendarFlyoutItem); + } +} diff --git a/Wino.Mail.WinUI/Controls/ListView/WinoMailItemViewModelListViewItem.cs b/Wino.Mail.WinUI/Controls/ListView/WinoMailItemViewModelListViewItem.cs index 9f7b710c..93edf839 100644 --- a/Wino.Mail.WinUI/Controls/ListView/WinoMailItemViewModelListViewItem.cs +++ b/Wino.Mail.WinUI/Controls/ListView/WinoMailItemViewModelListViewItem.cs @@ -24,6 +24,7 @@ public partial class WinoMailItemViewModelListViewItem : ListViewItem partial void OnItemPropertyChanged(DependencyPropertyChangedEventArgs e) { + // TODO: This slows down. Optimize later. Debug.WriteLine("WinoMailItemViewModelListViewItem item changed"); if (e.OldValue is MailItemViewModel oldMailItemViewModel) UnregisterPropertyChanged(oldMailItemViewModel); diff --git a/Wino.Mail.WinUI/Services/AccountCalendarStateService.cs b/Wino.Mail.WinUI/Services/AccountCalendarStateService.cs index 50f1e119..1ae0bdfa 100644 --- a/Wino.Mail.WinUI/Services/AccountCalendarStateService.cs +++ b/Wino.Mail.WinUI/Services/AccountCalendarStateService.cs @@ -5,6 +5,7 @@ using System.Linq; using CommunityToolkit.Mvvm.ComponentModel; using Wino.Calendar.ViewModels.Data; using Wino.Calendar.ViewModels.Interfaces; +using Wino.Core.Domain.Entities.Shared; namespace Wino.Mail.WinUI.Services; @@ -14,44 +15,43 @@ namespace Wino.Mail.WinUI.Services; /// public partial class AccountCalendarStateService : ObservableObject, IAccountCalendarStateService { - public event EventHandler CollectiveAccountGroupSelectionStateChanged; - public event EventHandler AccountCalendarSelectionStateChanged; + public event EventHandler? CollectiveAccountGroupSelectionStateChanged; + public event EventHandler? AccountCalendarSelectionStateChanged; + + private readonly ObservableCollection _internalGroupedAccountCalendars; [ObservableProperty] public partial ReadOnlyObservableCollection GroupedAccountCalendars { get; set; } - private ObservableCollection _internalGroupedAccountCalendars = new ObservableCollection(); - public IEnumerable ActiveCalendars { get { - return GroupedAccountCalendars - .SelectMany(a => a.AccountCalendars) - .Where(b => b.IsChecked); + return _internalGroupedAccountCalendars + .SelectMany(a => a.AccountCalendars) + .Where(b => b.IsChecked); } } - //public IEnumerable> GroupedAccountCalendarsEnumerable - //{ - // get - // { - // return GroupedAccountCalendars - // .Select(a => a.AccountCalendars) - // .SelectMany(b => b) - // .GroupBy(c => c.Account); - // } - //} + public IEnumerable AllCalendars + { + get + { + return _internalGroupedAccountCalendars + .SelectMany(a => a.AccountCalendars); + } + } public AccountCalendarStateService() { + _internalGroupedAccountCalendars = new ObservableCollection(); GroupedAccountCalendars = new ReadOnlyObservableCollection(_internalGroupedAccountCalendars); } - private void SingleGroupCalendarCollectiveStateChanged(object sender, EventArgs e) - => CollectiveAccountGroupSelectionStateChanged?.Invoke(this, sender as GroupedAccountCalendarViewModel); + private void SingleGroupCalendarCollectiveStateChanged(object? sender, EventArgs e) + => CollectiveAccountGroupSelectionStateChanged?.Invoke(this, sender as GroupedAccountCalendarViewModel ?? throw new InvalidOperationException("Sender must be GroupedAccountCalendarViewModel")); - private void SingleCalendarSelectionStateChanged(object sender, AccountCalendarViewModel e) + private void SingleCalendarSelectionStateChanged(object? sender, AccountCalendarViewModel e) => AccountCalendarSelectionStateChanged?.Invoke(this, e); public void AddGroupedAccountCalendar(GroupedAccountCalendarViewModel groupedAccountCalendar) @@ -70,7 +70,7 @@ public partial class AccountCalendarStateService : ObservableObject, IAccountCal _internalGroupedAccountCalendars.Remove(groupedAccountCalendar); } - public void ClearGroupedAccountCalendar() + public void ClearGroupedAccountCalendars() { while (_internalGroupedAccountCalendars.Any()) { diff --git a/Wino.Mail.WinUI/Styles/WinoDayTimelineCanvas.xaml b/Wino.Mail.WinUI/Styles/WinoDayTimelineCanvas.xaml index 96257f2f..eb48c8ef 100644 --- a/Wino.Mail.WinUI/Styles/WinoDayTimelineCanvas.xaml +++ b/Wino.Mail.WinUI/Styles/WinoDayTimelineCanvas.xaml @@ -1,8 +1,8 @@  + xmlns:controls="using:Wino.Calendar.Controls" + xmlns:skia="using:SkiaSharp.Views.Windows">