Skip to content

Commit

Permalink
fix: fix appointments by cell
Browse files Browse the repository at this point in the history
  • Loading branch information
Stéphane ANDRE (E104915) committed Sep 4, 2024
1 parent 0b9d807 commit 02b7fd2
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 98 deletions.
13 changes: 1 addition & 12 deletions src/MyNet.Wpf/Controls/CalendarBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1203,7 +1203,7 @@ protected virtual void BuildCore(CancellationToken cancellationToken)
_displayDates.Set(dates.Select(x =>
{
cancellationToken.ThrowIfCancellationRequested();
var item = new CalendarItem(this, x.date, IntervalUnit);
var item = new CalendarItem(this, x.date, IntervalUnit, _appointments);
Grid.SetRow(item, x.row);
Grid.SetColumn(item, x.column);
item.AddHandler(MouseDownEvent, new MouseButtonEventHandler(Cell_MouseDown), true);
Expand Down Expand Up @@ -1867,17 +1867,6 @@ private async Task UpdateAppointmentsAsync(CancellationToken cancellationToken)
cancellationToken.ThrowIfCancellationRequested();
await SynchronizeAppointmentAsync(item, cancellationToken).ConfigureAwait(false);
}

if (Dispatcher.Invoke(() => AppointmentsDisplayMode == AppointmentsDisplayMode.Cell))
{
var calendarItems = GetCalendarItems().ToList();
foreach (var item in calendarItems)
{
cancellationToken.ThrowIfCancellationRequested();
Dispatcher.Invoke(() => item.UpdateAppointments(cancellationToken), DispatcherPriority.Input, cancellationToken);
await Task.Delay(1.Milliseconds(), cancellationToken).ConfigureAwait(false);
}
}
}
catch (OperationCanceledException)
{
Expand Down
174 changes: 88 additions & 86 deletions src/MyNet.Wpf/Controls/CalendarItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,16 @@
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using System.Threading;
using System.Reactive.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using DynamicData;
using DynamicData.Binding;
using MyNet.Observable;
using MyNet.Observable.Collections;
using MyNet.UI.Collections;
using MyNet.UI.Threading;
using MyNet.Utilities;
using MyNet.Utilities.DateTimes;
using MyNet.Utilities.Units;
Expand All @@ -27,7 +31,8 @@ public class CalendarItem : Control
{
private const string PartAddButton = "PART_AddButton";

private readonly ExtendedCollection<IAppointment> _appointments = new(WpfScheduler.Current);
private readonly ReadOnlyObservableCollection<IAppointment> _appointments;
private readonly IDisposable _disposable;

public DateTime Date { get; internal set; }

Expand All @@ -52,11 +57,8 @@ static CalendarItem()
EventManager.RegisterClassHandler(typeof(CalendarItem), MouseLeaveEvent, new RoutedEventHandler(OnVisualStateChanged));
}

public CalendarItem(CalendarBase owner, DateTime date, TimeUnit unit)
public CalendarItem(CalendarBase owner, DateTime date, TimeUnit unit, ObservableCollection<CalendarAppointment> appointments)
{
_appointments.SortingProperties.Add(nameof(IAppointment.StartDate));

SetValue(AppointmentsPropertyKey, _appointments.Items);
Owner = owner;
Unit = unit;
var d = DependencyPropertyDescriptor.FromProperty(IsKeyboardFocusedProperty, typeof(CalendarItem));
Expand All @@ -69,8 +71,21 @@ public CalendarItem(CalendarBase owner, DateTime date, TimeUnit unit)
d2.AddValueChanged(this, OnVisualStatePropertyChanged);

SetDate(date);

_disposable = appointments.ToObservableChangeSet()
.Transform(x => (IAppointment)x.DataContext)
.AutoRefresh(x => x.StartDate)
.AutoRefresh(x => Date)
.Filter(x => Owner.AppointmentsDisplayMode == AppointmentsDisplayMode.Cell && IsMatch(x))
.Sort(SortExpressionComparer<IAppointment>.Ascending(x => x.StartDate))
.ObserveOn(Scheduler.UI)
.Bind(out _appointments)
.Subscribe();
SetValue(AppointmentsPropertyKey, _appointments);
}

~CalendarItem() => _disposable.Dispose();

public void SetDate(DateTime date)
{
Date = date;
Expand All @@ -91,8 +106,6 @@ public void SetDate(DateTime date)
SetValue(IsFirstOfWeekPropertyKey, Date.IsFirstDayOfWeek(Owner.FirstDayOfWeek));
SetValue(IsWeekendPropertyKey, Date.IsWeekend());
}

_appointments.Clear();
}

#region AddCommand
Expand Down Expand Up @@ -384,84 +397,73 @@ protected virtual void UpdateVisualState(bool useTransitions)
: VisualStateManager.GoToState(this, "Unselected", useTransitions);
}

internal virtual void UpdateAppointments(CancellationToken cancellationToken)
{
if (Owner != null && Owner.Appointments != null)
{
var appointments = Owner.Appointments.OfType<IAppointment>().ToList();
appointments.ForEach(x =>
{
cancellationToken.ThrowIfCancellationRequested();
SynchronizeAppointment(x);

if (x is INotifyPropertyChanged npc)
{
npc.PropertyChanged -= OnItemPropertyChangedCallback;
npc.PropertyChanged += OnItemPropertyChangedCallback;
}
});

if (appointments is INotifyCollectionChanged ncc)
{
ncc.CollectionChanged -= OnOwnerAppointmentsCollectionChangedCallback;
ncc.CollectionChanged += OnOwnerAppointmentsCollectionChangedCallback;
}
}
else
{
_appointments.Clear();
}
}

private void OnOwnerAppointmentsCollectionChangedCallback(object? sender, NotifyCollectionChangedEventArgs e)
{
if (e.NewItems != null)
{
foreach (var item in e.NewItems)
{
if (item is INotifyPropertyChanged npc)
{
npc.PropertyChanged -= OnItemPropertyChangedCallback;
npc.PropertyChanged += OnItemPropertyChangedCallback;
}
}

e.NewItems.OfType<IAppointment>().ForEach(SynchronizeAppointment);
}

if (e.OldItems != null)
{
foreach (var item in e.OldItems)
{
if (item is INotifyPropertyChanged npc)
npc.PropertyChanged -= OnItemPropertyChangedCallback;
}

_appointments.RemoveMany(e.OldItems.OfType<IAppointment>());
}
}

private void OnItemPropertyChangedCallback(object? sender, PropertyChangedEventArgs e)
{
if (sender is IAppointment appointment && e.PropertyName is (nameof(IAppointment.StartDate)) or (nameof(IAppointment.EndDate)))
{
SynchronizeAppointment(appointment);
}
}

private void SynchronizeAppointment(IAppointment appointment)
{
var isMatch = Dispatcher.Invoke(() => IsMatch(appointment));
if (isMatch)
{
if (!_appointments.Contains(appointment))
_appointments.Add(appointment);
}
else
{
_appointments.Remove(appointment);
}
}
//internal virtual void UpdateAppointments(ObservableCollection<CalendarAppointment> appointments)
//{
// appointments.ForEach(x =>
// {
// if (x.DataContext is not IAppointment appointment) return;

// SynchronizeAppointment(appointment);

// appointment.PropertyChanged -= OnItemPropertyChangedCallback;
// appointment.PropertyChanged += OnItemPropertyChangedCallback;
// });

// appointments.CollectionChanged -= OnOwnerAppointmentsCollectionChangedCallback;
// appointments.CollectionChanged += OnOwnerAppointmentsCollectionChangedCallback;
//}

//private void OnOwnerAppointmentsCollectionChangedCallback(object? sender, NotifyCollectionChangedEventArgs e)
//{
// if (e.NewItems != null)
// {
// foreach (var item in e.NewItems)
// {
// if (item is INotifyPropertyChanged npc)
// {
// npc.PropertyChanged -= OnItemPropertyChangedCallback;
// npc.PropertyChanged += OnItemPropertyChangedCallback;
// }
// }

// e.NewItems.OfType<IAppointment>().ForEach(SynchronizeAppointment);
// }

// if (e.OldItems != null)
// {
// foreach (var item in e.OldItems)
// {
// if (item is INotifyPropertyChanged npc)
// npc.PropertyChanged -= OnItemPropertyChangedCallback;
// }

// _appointments.RemoveMany(e.OldItems.OfType<IAppointment>());
// }
//}

//private void OnItemPropertyChangedCallback(object? sender, PropertyChangedEventArgs e)
//{
// if (sender is IAppointment appointment && e.PropertyName is (nameof(IAppointment.StartDate)) or (nameof(IAppointment.EndDate)))
// {
// SynchronizeAppointment(appointment);
// }
//}

//private void SynchronizeAppointment(IAppointment appointment)
//{
// Dispatcher.Invoke(() =>
// {
// if (IsMatch(appointment))
// {
// if (!_appointments.Contains(appointment))
// _appointments.Add(appointment);
// }
// else
// {
// _appointments.Remove(appointment);
// }
// });
//}

protected bool IsMatch(IAppointment appointment) => Period.Start < appointment.StartDate && Period.End > appointment.EndDate
|| appointment.StartDate < Period.Start && appointment.EndDate > Period.End
Expand Down

0 comments on commit 02b7fd2

Please sign in to comment.