using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace GanttChart { /// /// 甘特图控件 /// 该部分类主要处理事件 /// public partial class GanttChartView { private bool _IsShiftPress = false; private bool _IsCtrlPress = false; private bool _IsAltPress = false; private bool _IsMouseDown = false; private bool _IsAjustSize = false; private bool _IsDragItem = false; private bool _IsShowTooltip = false; private Point _DragStartLocation = Point.Empty; private Point _DragEndLocation = Point.Empty; private Point _ShowTooltipPoint = Point.Empty; private Rectangle _SelectionRange = Rectangle.Empty; private GanttChartViewItem _DragItem = null; private GanttChartViewItem _ShowTooltipItem = null; public event EventHandler PropertyChanged; public event EventHandler ItemClick; public event EventHandler ItemDoubleClick; public event EventHandler RowSelected; public event EventHandler RangeSelected; /// /// 初始化事件 /// protected void InitEvent() { _VScrollBar.Scroll += new ScrollEventHandler(VScrollBar_Scroll); _HScrollBar.Scroll += new ScrollEventHandler(HScrollBar_Scroll); _ContentControl.Paint += OnContentControlPaint; _ContentControl.MouseDown += OnMouseDown; _ContentControl.MouseUp += OnMouseUp; _ContentControl.MouseMove += OnMouseMove; _ContentControl.MouseClick += OnMouseClick; _ContentControl.MouseDoubleClick += OnMouseDoubleClick; } /// /// 销毁事件 /// protected void DisposeEvent() { } /// /// 键盘按下事件 /// /// protected override void OnKeyDown(KeyEventArgs e) { _IsShiftPress = e.Shift; _IsCtrlPress = e.Control; _IsAltPress = e.Alt; base.OnKeyDown(e); } /// /// 键盘弹起事件 /// /// protected override void OnKeyUp(KeyEventArgs e) { _IsShiftPress = e.Shift; _IsCtrlPress = e.Control; _IsAltPress = e.Alt; base.OnKeyUp(e); } /// /// 鼠标单击事件 /// /// /// protected void OnMouseClick(object sender, MouseEventArgs e) { if (_DragStartLocation != Point.Empty && e.X != _DragStartLocation.X && _DragStartLocation.Y != e.Y) { return; } if (IsHoverRowHeader(e.Location) || IsHoverRow(e.Location)) { _SelectionRow = GetRow(e.Location); Invalidate(); RowSelected?.Invoke(this, new GanttChartRowSelectedEventArgs(_SelectionRow)); } if (IsHoverItem(e.Location)) { _SelectionItem = GetItem(e.Location); Invalidate(); ItemClick?.Invoke(this, new GanttChartItemClickEventArgs(_SelectionItem)); } } /// /// 鼠标双击事件 /// /// /// protected void OnMouseDoubleClick(object sender, MouseEventArgs e) { if (IsHoverItem(e.Location)) { _SelectionItem = GetItem(e.Location); Invalidate(); if(ItemDoubleClick != null) { if (_IsShowTooltip) { _IsShowTooltip = false; _ShowTooltipItem = null; _ShowTooltipPoint = Point.Empty; } ItemDoubleClick(this, new GanttChartItemDoubleClickEventArgs(_SelectionItem)); } } } /// /// 鼠标滚动事件 /// /// protected override void OnMouseWheel(MouseEventArgs e) { if (_IsShowTooltip) { _IsShowTooltip = false; _ShowTooltipItem = null; _ShowTooltipPoint = Point.Empty; } //int i = e.Delta > 0 ? -1 : 1; var scrollbar = _IsShiftPress ? _HScrollBar : (ScrollBar)_VScrollBar; var h = scrollbar.Value - (int)(e.Delta * MouseWheelSensitivity); if (h > scrollbar.Maximum) { h = scrollbar.Maximum; } if (h < scrollbar.Minimum) { h = scrollbar.Minimum; } scrollbar.Value = h; Invalidate(); base.OnMouseWheel(e); } /// /// 鼠标按下事件 /// /// /// protected void OnMouseDown(object sender, MouseEventArgs e) { if (_SelectionRow != null || _SelectionItem != null || _DragItem != null) { _SelectionRow = null; _SelectionItem = null; _DragItem = null; Invalidate(); } _IsMouseDown = e.Button == MouseButtons.Left && true; if (_IsMouseDown) { _SelectionRange = Rectangle.Empty; _SelectionTimeRange = null; _DragStartLocation = e.Location; if (IsHoverDateSplitLine(e.Location) && !IsHoverItem(e.Location)) { _IsAjustSize = true; } else if (IsHoverItem(e.Location)) { _IsDragItem = true; _DragItem = GetItem(e.Location); } } } /// /// 控件创建事件 /// protected override void OnCreateControl() { this.Brushes = new GanttChartBrushes(this); _HScrollBar.Width = this.Width - VScrollWidth; _VScrollBar.Height = this.Height - HScrollHeight; AdjustScrollbar(); base.OnCreateControl(); } /// /// 控件大小变化事件 /// /// protected override void OnSizeChanged(EventArgs e) { _HScrollBar.Width = this.Width - VScrollWidth; _VScrollBar.Height = this.Height - HScrollHeight; AdjustScrollbar(); Invalidate(); base.OnSizeChanged(e); } /// /// 控件绘制事件 /// /// /// private void OnContentControlPaint(object sender, PaintEventArgs e) { int bottom = ColumnHeight + ItemHeight + RowSpacing * 2; if (Rows != null && Rows.Any()) { var last = Rows.Last(); bottom = last.Bottom; } DrawBack(e.Graphics, bottom); e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; DrawHeader(e.Graphics, bottom); DrawColumnHeader(e.Graphics); DrawTimeLine(e.Graphics, bottom); DrawSelectingRectangle(e.Graphics); DrawSelectionRange(e.Graphics); DrawRows(e.Graphics, bottom); DrawItemTooltip(e.Graphics); } /// /// 鼠标弹起事件 /// /// /// protected void OnMouseUp(object sender, MouseEventArgs e) { if (_IsMouseDown) { if (_IsAjustSize) { _IsAjustSize = false; var w = e.X - _DragStartLocation.X + DateWidth; if (w < MinDateWidth) { DateWidth = MinDateWidth; } else { DateWidth = (w / 48 + (w % 48 == 0 ? 0 : 1)) * 48; } if(Rows != null) { Rows.IsChanged = true; } AdjustScrollbar(); Invalidate(); } else if (_IsDragItem) { _IsDragItem = false; //TODO:触发Drag事件 Invalidate(); } else if(!_DragStartLocation.IsEmpty && e.X != _DragStartLocation.X && e.Y != _DragStartLocation.Y && _DragStartLocation.X > RowHeaderWidth && _DragStartLocation.Y > ColumnHeight) { _DragEndLocation = e.Location; var row = GetRow(_DragStartLocation); if (row != null) { var width = Math.Abs(_DragEndLocation.X - _DragStartLocation.X); if (_DragEndLocation.X < RowHeaderWidth) { width -= RowHeaderWidth - _DragEndLocation.X; } else if (_DragEndLocation.X > ((int)(EndDate.Date - StartDate.Date).TotalDays + 1) * DateWidth + RowHeaderWidth - _HScrollBar.Value) { width = ((int)(EndDate.Date - StartDate.Date).TotalDays + 1) * DateWidth + RowHeaderWidth - _HScrollBar.Value - _DragStartLocation.X; } var start = new Point(Math.Min(_DragStartLocation.X, Math.Max(_DragEndLocation.X, RowHeaderWidth)), row.Top + 1); _SelectionRange = new Rectangle(start, new Size(width, row.Bottom - row.Top - 2)); Invalidate(); var mw = DateWidth / 24f / 60f; var ts = StartDate.AddMinutes((int)((_DragStartLocation.X - RowHeaderWidth + _HScrollBar.Value) / mw)); var te = StartDate.AddMinutes((int)((_DragEndLocation.X - RowHeaderWidth + _HScrollBar.Value) / mw)); if (te < ts) { var tt = te; te = ts; ts = tt; } _SelectionTimeRange = new TimeRange { StartTime = ts, EndTime = te }; RangeSelected?.Invoke(this, new GanttChartRangeSelectedEventArgs(ts, te)); } } } _IsMouseDown = false; _DragStartLocation = Point.Empty; _DragEndLocation = Point.Empty; } /// /// 鼠标移动事件 /// /// /// protected void OnMouseMove(object sender, MouseEventArgs e) { if (_IsMouseDown) { if (_IsShowTooltip) { _IsShowTooltip = false; _ShowTooltipItem = null; _ShowTooltipPoint = Point.Empty; Invalidate(); } if (_IsDragItem) { } else if (_DragStartLocation.X > RowHeaderWidth && _DragStartLocation.Y > ColumnHeight) { //TODO: 画选择框 _DragEndLocation = e.Location; Invalidate(); } return; } else if (IsHoverDateSplitLine(e.Location) && !IsHoverItem(e.Location)) { Cursor = Cursors.VSplit; } //else if (IsHoverRowHeader(e)) //{ // Cursor = DefaultCursor; //} else if (IsHoverItem(e.Location)) { Cursor = Cursors.Hand; //TODO:显示Tooltip if (!_IsShowTooltip || GetItem(e.Location) != _ShowTooltipItem) { _IsShowTooltip = true; _ShowTooltipItem = GetItem(e.Location); _ShowTooltipPoint = ComputeTooltipLocation(e.Location); Invalidate(); return; } else { return; } } else { Cursor = DefaultCursor; } if (_IsShowTooltip) { _IsShowTooltip = false; _ShowTooltipItem = null; _ShowTooltipPoint = Point.Empty; Invalidate(); } } /// /// 横向滚动事件 /// /// /// private void HScrollBar_Scroll(object sender, ScrollEventArgs e) { Invalidate(); } /// /// 纵向滚动事件 /// /// /// private void VScrollBar_Scroll(object sender, ScrollEventArgs e) { Invalidate(); } /// /// 属性改变事件 /// /// /// private void OnPropertyChanged(string name, object value) { this.Brushes?.Refresh(); var args = new GanttChartPropertyChangeEventArgs(name, value); PropertyChanged?.Invoke(this, args); if(name == nameof(BlockType)) { Rows.IsChanged = true; } AdjustScrollbar(); Invalidate(); } } }