소스 검색

avalonia: CalendarView can now have its columns set manually

Kenric Nugteren 3 달 전
부모
커밋
e9203f3e08
1개의 변경된 파일50개의 추가작업 그리고 5개의 파일을 삭제
  1. 50 5
      InABox.Avalonia/Components/CalendarView/CalendarView.axaml.cs

+ 50 - 5
InABox.Avalonia/Components/CalendarView/CalendarView.axaml.cs

@@ -52,6 +52,9 @@ public partial class CalendarView : UserControl
     public static readonly StyledProperty<IDataTemplate?> HeaderTemplateProperty = 
         AvaloniaProperty.Register<CalendarView, IDataTemplate?>(nameof(HeaderTemplate));
 
+    public static readonly StyledProperty<IEnumerable?> ColumnsProperty = 
+        AvaloniaProperty.Register<CalendarView, IEnumerable?>(nameof(Columns));
+
     public double MinimumColumnWidth
     {
         get => GetValue(MinimumColumnWidthProperty);
@@ -113,6 +116,12 @@ public partial class CalendarView : UserControl
         set => SetValue(HeaderTemplateProperty, value);
     }
 
+    public IEnumerable? Columns
+    {
+        get => GetValue(ColumnsProperty);
+        set => SetValue(ColumnsProperty, value);
+    }
+
     public event EventHandler<CalendarBlockEventArgs>? EmptyBlockClicked;
     public event EventHandler<CalendarBlockEventArgs>? EmptyBlockHeld;
 
@@ -122,6 +131,25 @@ public partial class CalendarView : UserControl
         RowHeightProperty.Changed.AddClassHandler<CalendarView>(Render_Changed);
         MinimumColumnWidthProperty.Changed.AddClassHandler<CalendarView>(Render_Changed);
         RowIntervalProperty.Changed.AddClassHandler<CalendarView>(Render_Changed);
+        ColumnsProperty.Changed.AddClassHandler<CalendarView>(Columns_Changed);
+    }
+
+    private static void Columns_Changed(CalendarView view, AvaloniaPropertyChangedEventArgs args)
+    {
+        if(args.OldValue is INotifyCollectionChanged oldNotify)
+        {
+            oldNotify.CollectionChanged -= view.ColumnsCollection_Changed;
+        }
+        view.Render(itemsChanged: true);
+        if(args.NewValue is INotifyCollectionChanged notify)
+        {
+            notify.CollectionChanged += view.ColumnsCollection_Changed;
+        }
+    }
+
+    private void ColumnsCollection_Changed(object? sender, NotifyCollectionChangedEventArgs e)
+    {
+        Render(itemsChanged: true);
     }
 
     private static void Render_Changed(CalendarView view, AvaloniaPropertyChangedEventArgs args)
@@ -231,6 +259,19 @@ public partial class CalendarView : UserControl
         _blocks.Clear();
 
         _columns.Clear();
+        var autoGenerateColumns = true;
+        if(Columns is not null)
+        {
+            autoGenerateColumns = false;
+            foreach(var column in Columns)
+            {
+                if(!_blocks.TryAdd(column, new()))
+                {
+                    throw new Exception($"Duplicate column {column} in Calendar");
+                }
+                _columns.Add(column);
+            }
+        }
         foreach(var item in ItemsSource)
         {
             var block = new Block
@@ -242,11 +283,6 @@ public partial class CalendarView : UserControl
                 [!Block.ContentTemplateProperty] = this[!ItemTemplateProperty],
                 Content = item
             };
-            _oldSubscriptions.Add(block.GetObservable(Block.ColumnProperty).Skip(1).Subscribe(x => Render(itemsChanged: true)));
-            _oldSubscriptions.Add(block.GetObservable(Block.StartTimeProperty).Skip(1).Subscribe(x => UpdateBlock(block)));
-            _oldSubscriptions.Add(block.GetObservable(Block.EndTimeProperty).Skip(1).Subscribe(x => UpdateBlock(block)));
-            block.PointerPressed += Block_PointerPressed;
-            block.PointerReleased += Block_PointerReleased;
             block.Background = new SolidColorBrush(Colors.Transparent);
 
             var column = block.Column;
@@ -256,10 +292,19 @@ public partial class CalendarView : UserControl
             }
             if(!_blocks.TryGetValue(column, out var columnBlocks))
             {
+                if (!autoGenerateColumns) continue;
+
                 columnBlocks = new();
                 _blocks.Add(column, columnBlocks);
                 _columns.Add(column);
             }
+
+            _oldSubscriptions.Add(block.GetObservable(Block.ColumnProperty).Skip(1).Subscribe(x => Render(itemsChanged: true)));
+            _oldSubscriptions.Add(block.GetObservable(Block.StartTimeProperty).Skip(1).Subscribe(x => UpdateBlock(block)));
+            _oldSubscriptions.Add(block.GetObservable(Block.EndTimeProperty).Skip(1).Subscribe(x => UpdateBlock(block)));
+            block.PointerPressed += Block_PointerPressed;
+            block.PointerReleased += Block_PointerReleased;
+
             columnBlocks.Blocks.Add(block);
         }
     }