浏览代码

Added thumbs

Kenric Nugteren 5 天之前
父节点
当前提交
2c973f2478
共有 1 个文件被更改,包括 153 次插入2 次删除
  1. 153 2
      inabox.wpf/Forms/CalendarControl/CalendarControl.cs

+ 153 - 2
inabox.wpf/Forms/CalendarControl/CalendarControl.cs

@@ -226,6 +226,8 @@ public class CalendarControl : ContentControl
 
     public BindingBase? EndTimeMapping { get; set; }
 
+    public BindingBase? CanAdjustMapping { get; set; }
+
     public IEnumerable? ItemsSource
     {
         get => GetValue(ItemsSourceProperty) as IEnumerable;
@@ -392,8 +394,18 @@ public class CalendarControl : ContentControl
 
     private Border HeaderBorder;
 
+    private ControlTemplate _thumbTemplate;
+
     public CalendarControl()
     {
+        _thumbTemplate = TemplateGenerator.CreateControlTemplate(typeof(Thumb), () =>
+        {
+            return new Border
+            {
+                Background = Colors.Transparent.ToBrush()
+            };
+        });
+
         var grid = new Grid();
         grid.AddRow(GridUnitType.Auto); // Date
         grid.AddRow(GridUnitType.Auto); // Column
@@ -604,10 +616,14 @@ public class CalendarControl : ContentControl
             DependencyProperty.Register(nameof(Date), typeof(DateTime), typeof(Block), new(OnPropertyChangedHandler));
 
         public static readonly DependencyProperty StartTimeProperty =
-            DependencyProperty.Register(nameof(StartTime), typeof(TimeSpan), typeof(Block), new(OnPropertyChangedHandler));
+            DependencyProperty.Register(nameof(StartTime), typeof(TimeSpan), typeof(Block),
+                new FrameworkPropertyMetadata(TimeSpan.Zero, OnPropertyChangedHandler));
         public static readonly DependencyProperty EndTimeProperty =
             DependencyProperty.Register(nameof(EndTime), typeof(TimeSpan), typeof(Block), new(OnPropertyChangedHandler));
 
+        public static readonly DependencyProperty CanAdjustProperty =
+            DependencyProperty.Register(nameof(CanAdjust), typeof(bool), typeof(Block));
+
         public int ColumnIndex { get; set; } = -1;
 
         public int NColumns { get; set; } = -1;
@@ -636,6 +652,12 @@ public class CalendarControl : ContentControl
             set => SetValue(EndTimeProperty, value);
         }
 
+        public bool CanAdjust
+        {
+            get => (bool)GetValue(CanAdjustProperty);
+            set => SetValue(CanAdjustProperty, value);
+        }
+
         private ContentControl _contentControl;
         public ContentControl ContentControl => _contentControl;
 
@@ -646,16 +668,132 @@ public class CalendarControl : ContentControl
             return $"Block({Column}: {StartTime:hh\\:mm} - {EndTime:hh\\:mm})";
         }
 
+        private bool _thumbReversed = false;
+        private Thumb _topThumb;
+        private Thumb _bottomThumb;
+        private TimeSpan _thumbStart;
+        private TimeSpan _thumbFinish;
+
+        private CalendarControl _parent;
+
         public Block(CalendarControl parent, object content)
         {
+            _parent = parent;
+
+            var grid = new Grid();
+            var topRow = grid.AddRow(GridUnitType.Auto);
+            grid.AddRow(GridUnitType.Star);
+            grid.AddRow(GridUnitType.Auto);
+
             _contentControl = new ContentControl
             {
                 Content = content
             };
             _contentControl.Bind(ContentControl.ContentTemplateProperty, parent, x => x.ItemTemplate);
-            Child = _contentControl;
+
+            grid.AddChild(_contentControl, 0, 0, rowSpan: 3);
+
+            _topThumb = new Thumb
+            {
+                Height = 5,
+                Cursor = Cursors.SizeNS,
+                Template = _parent._thumbTemplate
+            };
+            _topThumb.Bind(Thumb.VisibilityProperty, this, x => x.CanAdjust, converter: new WPF.BooleanToVisibilityConverter(Visibility.Visible, Visibility.Collapsed));
+            _bottomThumb = new Thumb
+            {
+                Height = 5,
+                Cursor = Cursors.SizeNS,
+                Template = _parent._thumbTemplate
+            };
+            _bottomThumb.Bind(Thumb.VisibilityProperty, this, x => x.CanAdjust, converter: new WPF.BooleanToVisibilityConverter(Visibility.Visible, Visibility.Collapsed));
+
+            _topThumb.DragStarted += Thumb_DragStarted;
+            _topThumb.DragDelta += TopThumb_DragDelta;
+            _topThumb.DragCompleted += Thumb_DragCompleted;
+
+            _bottomThumb.DragStarted += Thumb_DragStarted;
+            _bottomThumb.DragDelta += BottomThumb_DragDelta;
+            _bottomThumb.DragCompleted += Thumb_DragCompleted;
+
+            grid.AddChild(_topThumb, 0, 0);
+            grid.AddChild(_bottomThumb, 2, 0);
+
+            Child = grid;
+        }
+
+        private void ReverseThumb()
+        {
+            _thumbReversed = !_thumbReversed;
+            if (_thumbReversed)
+            {
+                Grid.SetRow(_topThumb, 2);
+                Grid.SetRow(_bottomThumb, 0);
+            }
+            else
+            {
+                Grid.SetRow(_topThumb, 0);
+                Grid.SetRow(_bottomThumb, 2);
+            }
+        }
+        private void MoveThumb(bool isTop, double amount)
+        {
+            if (_thumbReversed)
+            {
+                isTop = !isTop;
+            }
+
+            if (isTop)
+            {
+                _thumbStart += _parent.RowInterval * (amount / _parent._rowHeight);
+                if(_thumbStart > _thumbFinish)
+                {
+                    (_thumbStart, _thumbFinish) = (_thumbFinish, _thumbStart);
+                    ReverseThumb();
+                }
+            }
+            else
+            {
+                _thumbFinish += _parent.RowInterval * (amount / _parent._rowHeight);
+                if(_thumbStart > _thumbFinish)
+                {
+                    (_thumbStart, _thumbFinish) = (_thumbFinish, _thumbStart);
+                    ReverseThumb();
+                }
+            }
+
+            var topY = _parent.GetRow(_thumbStart) * _parent._rowHeight;
+            var bottomY = _parent.GetRow(_thumbFinish) * _parent._rowHeight;
+
+            Canvas.SetTop(this, topY);
+            Height = bottomY - topY;
+        }
+
+        private void Thumb_DragStarted(object sender, DragStartedEventArgs e)
+        {
+            _thumbStart = StartTime;
+            _thumbFinish = EndTime;
+
+            _thumbReversed = false;
         }
 
+        private void TopThumb_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
+        {
+            MoveThumb(true, e.VerticalChange);
+        }
+
+        private void Thumb_DragCompleted(object sender, System.Windows.Controls.Primitives.DragCompletedEventArgs e)
+        {
+            StartTime = _thumbStart;
+            EndTime = _thumbFinish;
+        }
+
+        private void BottomThumb_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
+        {
+            MoveThumb(false, e.VerticalChange);
+        }
+
+
         public event PropertyChangedEventHandler? PropertyChanged;
 
         private static void OnPropertyChangedHandler(DependencyObject d, DependencyPropertyChangedEventArgs e)
@@ -699,6 +837,7 @@ public class CalendarControl : ContentControl
         var dateBinding = DateMapping;
         var startBinding = StartTimeMapping;
         var endBinding = EndTimeMapping;
+        var canAdjust = CanAdjustMapping;
         if(columnBinding is null || dateBinding is null || startBinding is null || endBinding is null)
         {
             return false;
@@ -718,6 +857,18 @@ public class CalendarControl : ContentControl
             block.SetBinding(Block.StartTimeProperty, startBinding);
             block.SetBinding(Block.EndTimeProperty, endBinding);
             block.SetBinding(Block.DateProperty, dateBinding);
+            if((startBinding as Binding)?.Mode == BindingMode.TwoWay
+                && (endBinding as Binding)?.Mode == BindingMode.TwoWay)
+            {
+                if(canAdjust is not null)
+                {
+                    block.SetBinding(Block.CanAdjustProperty, canAdjust);
+                }
+                else
+                {
+                    block.CanAdjust = true;
+                }
+            }
             block.DataContext = item;
             block.Background = Colors.Transparent.ToBrush();