|
|
@@ -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();
|
|
|
|