To reproduce: please run the sample project and follow the steps illustrated in the attached gif file. This shows how I’m attempting to add children to a root task. Upon adding a child task I am unable to scroll down to see the rest of the pre-existent root tasks until I first collapse and expand any visible root or child task. Workaround: public RadForm2() { InitializeComponent(); this.radGanttView1.ItemAdded += radGanttView1_ItemAdded; } private void radGanttView1_ItemAdded(object sender, Telerik.WinControls.UI.GanttViewItemAddedEventArgs e) { item = e.Item; } GanttViewDataItem item; private void radButton1_Click(object sender, EventArgs e) { this.radGanttView1.GanttViewElement.InvalidateMeasure(true); this.radGanttView1.GanttViewElement.UpdateLayout(); this.radGanttView1.GanttViewElement.GraphicalViewElement.Scroller.ScrollToItem(item); }
To reproduce: run the sample project and try to move a task. Workaround: Timer timer = new Timer(); private void DragDropService_Stopped(object sender, EventArgs e) { timer = new Timer(); timer.Interval = 300; timer.Tick += timer_Tick; } private void timer_Tick(object sender, EventArgs e) { timer.Stop(); data.Tables["Tasks"].Clear(); } Workaround 2: private void radGanttView1_ItemElementCreating(object sender, Telerik.WinControls.UI.GanttViewItemElementCreatingEventArgs e) { if (e.Item.Items.Count == 0 && e.ViewElement is GanttViewGraphicalViewElement) { e.ItemElement = new MyGanttViewTaskItemElement(e.ViewElement as GanttViewGraphicalViewElement); } } public class MyGanttViewTaskItemElement : GanttViewTaskItemElement { public MyGanttViewTaskItemElement(GanttViewGraphicalViewElement ganttViewBaseViewElement) : base(ganttViewBaseViewElement) { } protected override Type ThemeEffectiveType { get { return typeof(GanttViewTaskItemElement); } } public override void Detach() { var obj = this.Data; this.Data.SuspendPropertyNotifications(); base.Detach(); obj.ResumePropertyNotifications(); } public override void Synchronize() { DataSet ds = this.Data.GanttViewElement.DataSource as DataSet; if (ds != null && this.Data != null) { DataRowView rowView = this.Data.DataBoundItem as DataRowView; if (rowView != null && !RowExists(rowView.Row))//!ds.Tables[0].Rows.Contains(rowView.Row)) { return; } } base.Synchronize(); } private bool RowExists(DataRow dataRow) { DataSet ds = this.Data.GanttViewElement.DataSource as DataSet; bool res = false; foreach (DataRow r in ds.Tables[0].Rows) { if (r.Equals(dataRow)) { return true; } } return res; } }
To reproduce: run the sample project and scroll to the end of the view. You will notice that the tasks are not properly aligned. You can increase the GraphicalViewElement.OnePixelTime in order to make the alignment even worse. Workaround: Adjust the GraphicalViewElement.OnePixelTime in order to obtain the correct alignment.
To reproduce: - Set the range to lest than one day. - Set the TimelineRange to DayHalfHours Workaround: Make sure that the range is at least one day.
To reproduce: have a look at the attached gif file and sample project. Workaround: this.radGanttView1.CursorChanged += radGanttView1_CursorChanged; this.radGanttView1.MouseMove += radGanttView1_MouseMove; private void radGanttView1_MouseMove(object sender, MouseEventArgs e) { GanttViewGraphicalViewElement view = this.radGanttView1.ElementTree.GetElementAtPoint(e.Location).FindAncestor<GanttViewGraphicalViewElement>(); Console.WriteLine(this.radGanttView1.ElementTree.GetElementAtPoint(e.Location)); if (view != null) isOverGraphicalView = true; else isOverGraphicalView = false; } bool isOverGraphicalView = false; private void radGanttView1_CursorChanged(object sender, EventArgs e) { if (isOverGraphicalView) { this.radGanttView1.CursorChanged -= radGanttView1_CursorChanged; this.radGanttView1.Cursor = Cursors.Default; this.radGanttView1.CursorChanged += radGanttView1_CursorChanged; } }
Even though you can't modify the tasks you can see the link handles which are usually used for linking different tasks. They shouldn't be displayed when the RadGanttView is in read-only mode. Workaround: handle the GraphicalViewItemFormatting event and manually hide the link handles: private void radGanttView1_GraphicalViewItemFormatting(object sender, GanttViewGraphicalViewItemFormattingEventArgs e) { GanttGraphicalViewBaseItemElement itemElement = e.ItemElement as GanttGraphicalViewBaseItemElement; if (itemElement != null) { Console.WriteLine(itemElement.LeftLinkHandleElement.Visibility); itemElement.LeftLinkHandleElement.Visibility = Telerik.WinControls.ElementVisibility.Collapsed; itemElement.LeftLinkHandleElement.PropertyChanged -= LeftLinkHandleElement_PropertyChanged; itemElement.LeftLinkHandleElement.PropertyChanged += LeftLinkHandleElement_PropertyChanged; itemElement.RightLinkHandleElement.Visibility = Telerik.WinControls.ElementVisibility.Collapsed; itemElement.RightLinkHandleElement.PropertyChanged -= LeftLinkHandleElement_PropertyChanged; itemElement.RightLinkHandleElement.PropertyChanged += LeftLinkHandleElement_PropertyChanged; } } private void LeftLinkHandleElement_PropertyChanged(object sender, PropertyChangedEventArgs e) { GanttViewTaskLinkHandleElement linkHanle = sender as GanttViewTaskLinkHandleElement; if (e.PropertyName == "Visibility" && linkHanle.Visibility == Telerik.WinControls.ElementVisibility.Visible) { linkHanle.Visibility = Telerik.WinControls.ElementVisibility.Collapsed; } }
To reproduce: 1) Open the Demo application >> Settings example. 2) Select a task and activate the editor for it. 3) Delete the task by clicking the button above. It may be necessary to repeat the steps several times. The error is not reproduced immediately.
The spin editor has a default minimum and maximum (0,100) Workaround: private void GanttViewElement_EditorInitialized(object sender, GanttViewItemEditorInitializedEventArgs e) { var editor = e.Editor as BaseSpinEditor; if (editor != null) { editor.MaxValue = int.MaxValue; var value = e.Item[radGanttView1.CurrentColumn]; editor.Value = value; } }
How to reproduce: this.radGanttView1.GanttViewElement.GraphicalViewElement.TimelineRange = Telerik.WinControls.UI.TimeRange.DayQuarterHours; this.radGanttView1.GanttViewElement.GraphicalViewElement.AutomaticTimelineTimeRange = true; this.radGanttView1.GanttViewElement.GraphicalViewElement.OnePixelTime = new TimeSpan(0, 0, 15); Workaround: at the moment the Gantt control does not support an automatic timeline range for day quarter hours. The TimeRange.DayQuarterHours is similar to the half days and they should be handled the same way when in automatic timeline. If possible TimeRange.DayHalfHours this.radGanttView1.GanttViewElement.GraphicalViewElement.TimelineRange = Telerik.WinControls.UI.TimeRange.DayHalfHours;
To reproduce: populate RadGanttView with data and hide some of the columns in a button's Click event: Private Sub RadButton1_Click(sender As Object, e As EventArgs) Handles RadButton1.Click Me.RadGanttView1.GanttViewElement.Columns(0).Visible = False End Sub The column is not hidden until you move the splitter. Workaround: Private Sub RadButton1_Click(sender As Object, e As EventArgs) Handles RadButton1.Click Me.RadGanttView1.GanttViewElement.Columns(0).Visible = False Me.RadGanttView1.GanttViewElement.InvalidateMeasure(True) Me.RadGanttView1.GanttViewElement.UpdateLayout() End Sub
To reproduce: public RadForm1() { InitializeComponent(); DataSet ds = new DataSet(); DataTable dt = new DataTable(); dt.TableName = "Tasks"; dt.Columns.Add("Id"); dt.Columns.Add("ParentID"); dt.Columns.Add("Title"); dt.Columns.Add("Start", typeof(DateTime)); dt.Columns.Add("End", typeof(DateTime)); dt.Rows.Add("1", "", "Item1", new DateTime(2018,03,16), new DateTime(2018,03,20)); dt.Rows.Add("2", "1", "child", new DateTime(2018,03,16), new DateTime(2018,03,17)); dt.Rows.Add("3", "", "Item2", new DateTime(2018,03,16), new DateTime(2018,03,20)); ds.Tables.Add(dt); this.radGanttView1.GanttViewElement.TaskDataMember = "Tasks"; this.radGanttView1.GanttViewElement.ChildMember = "Id"; this.radGanttView1.GanttViewElement.ParentMember = "ParentId"; this.radGanttView1.GanttViewElement.TitleMember = "Title"; this.radGanttView1.GanttViewElement.StartMember = "Start"; this.radGanttView1.GanttViewElement.EndMember = "End"; this.radGanttView1.GanttViewElement.DataSource = ds; this.radGanttView1.Columns.Add("Start"); this.radGanttView1.Columns.Add("End"); this.radGanttView1.GanttViewElement.GraphicalViewElement.TimelineStart = new DateTime(2018,03,10); this.radGanttView1.GanttViewElement.GraphicalViewElement.TimelineEnd = new DateTime(2018,03,31); //"child" item is readonly radGanttView1.Items[0].ReadOnly = true; } Workaround: public class CustomBaseGanttViewBehavior : BaseGanttViewBehavior { protected override void ProcessMouseDownOnTaskElement(GanttGraphicalViewBaseTaskElement element, MouseEventArgs e) { GanttGraphicalViewBaseItemElement taskItem = element.Parent as GanttGraphicalViewBaseItemElement; if (e.Button == MouseButtons.Left && !taskItem.Data.ReadOnly) { base.ProcessMouseDownOnTaskElement(element, e); } } }
How to reproduce: public partial class Form1 : Form { public Form1() { InitializeComponent(); new RadControlSpyForm().Show(); this.radGanttView.GanttViewElement.GraphicalViewElement.OnePixelTime = new TimeSpan(6, 0, 0); this.radGanttView.GanttViewElement.GraphicalViewElement.TimelineRange = TimeRange.YearHalves; this.radGanttView.GanttViewElement.GraphicalViewElement.TimelineStart = new DateTime(2016, 12, 25); this.radGanttView.GanttViewElement.GraphicalViewElement.TimelineEnd = new DateTime(2017, 1, 27); this.AddTasks(); } private void AddTasks() { //Setup data items GanttViewDataItem item1 = new GanttViewDataItem(); item1.Start = new DateTime(2017, 1, 1); item1.End = new DateTime(2017, 1, 20); item1.Progress = 30m; item1.Title = "Summary task.1. title"; GanttViewDataItem subItem11 = new GanttViewDataItem(); subItem11.Start = new DateTime(2017, 1, 1); subItem11.End = new DateTime(2017, 1, 20); subItem11.Progress = 10m; subItem11.Title = "Sub-task.1.1 title"; GanttViewDataItem subItem12 = new GanttViewDataItem(); subItem12.Start = new DateTime(2017, 1, 1); subItem12.End = new DateTime(2017, 1, 20); subItem12.Progress = 20m; subItem12.Title = "Sub-task.1.2 title"; GanttViewDataItem subItem13 = new GanttViewDataItem(); subItem13.Start = new DateTime(2017, 1, 5); subItem13.End = new DateTime(2017, 1, 20); subItem13.Progress = 20m; subItem13.Title = "Sub-task.1.3 title"; //Add subitems item1.Items.Add(subItem11); item1.Items.Add(subItem12); item1.Items.Add(subItem13); this.radGanttView.Items.Add(item1); GanttViewTextViewColumn titleColumn = new GanttViewTextViewColumn("Title"); GanttViewTextViewColumn startColumn = new GanttViewTextViewColumn("Start"); GanttViewTextViewColumn endColumn = new GanttViewTextViewColumn("End"); this.radGanttView.GanttViewElement.Columns.Add(titleColumn); this.radGanttView.GanttViewElement.Columns.Add(startColumn); this.radGanttView.GanttViewElement.Columns.Add(endColumn); } } Workaround: public partial class Form1 : Form { public Form1() { InitializeComponent(); new RadControlSpyForm().Show(); this.radGanttView.GanttViewElement.GraphicalViewElement.OnePixelTime = new TimeSpan(6, 0, 0); this.radGanttView.GanttViewElement.GraphicalViewElement.TimelineRange = TimeRange.YearHalves; this.radGanttView.GanttViewElement.GraphicalViewElement.TimelineBehavior = new CustomTimelineBehavior(); this.radGanttView.GanttViewElement.GraphicalViewElement.TimelineStart = new DateTime(2016, 12, 25); this.radGanttView.GanttViewElement.GraphicalViewElement.TimelineEnd = new DateTime(2017, 1, 27); this.AddTasks(); } private void AddTasks() { //Setup data items GanttViewDataItem item1 = new GanttViewDataItem(); item1.Start = new DateTime(2017, 1, 1); item1.End = new DateTime(2017, 1, 20); item1.Progress = 30m; item1.Title = "Summary task.1. title"; GanttViewDataItem subItem11 = new GanttViewDataItem(); subItem11.Start = new DateTime(2017, 1, 1); subItem11.End = new DateTime(2017, 1, 20); subItem11.Progress = 10m; subItem11.Title = "Sub-task.1.1 title"; GanttViewDataItem subItem12 = new GanttViewDataItem(); subItem12.Start = new DateTime(2017, 1, 1); subItem12.End = new DateTime(2017, 1, 20); subItem12.Progress = 20m; subItem12.Title = "Sub-task.1.2 title"; GanttViewDataItem subItem13 = new GanttViewDataItem(); subItem13.Start = new DateTime(2017, 1, 5); subItem13.End = new DateTime(2017, 1, 20); subItem13.Progress = 20m; subItem13.Title = "Sub-task.1.3 title"; //Add subitems item1.Items.Add(subItem11); item1.Items.Add(subItem12); item1.Items.Add(subItem13); this.radGanttView.Items.Add(item1); GanttViewTextViewColumn titleColumn = new GanttViewTextViewColumn("Title"); GanttViewTextViewColumn startColumn = new GanttViewTextViewColumn("Start"); GanttViewTextViewColumn endColumn = new GanttViewTextViewColumn("End"); this.radGanttView.GanttViewElement.Columns.Add(titleColumn); this.radGanttView.GanttViewElement.Columns.Add(startColumn); this.radGanttView.GanttViewElement.Columns.Add(endColumn); } } public class CustomTimelineBehavior : BaseGanttViewTimelineBehavior { public override DateTime AdjustedTimelineStart { get { if (this.GraphicalViewElement.TimelineRange == TimeRange.YearHalves) { DateTime result = this.GraphicalViewElement.TimelineStart; int halfYearDay = DateTime.IsLeapYear(result.Year) ? 366 / 2 : 365 / 2; if (result.DayOfYear < halfYearDay) { return new DateTime(result.Year, 1, 1); } else { return new DateTime(result.Year, 1, 1).AddDays(halfYearDay); } } return base.AdjustedTimelineStart; } } public override DateTime AdjustedTimelineEnd { get { if (this.GraphicalViewElement.TimelineRange == TimeRange.YearHalves) { DateTime result = this.GraphicalViewElement.TimelineEnd; int halfYearDay = DateTime.IsLeapYear(result.Year) ? 366 / 2 : 365 / 2; if (result.DayOfYear < halfYearDay) { return new DateTime(result.Year, 1, 1).AddDays(halfYearDay + 1); } else { return new DateTime(result.Year, 1, 1).AddYears(1); } } return base.AdjustedTimelineEnd; } } }
Workaround: In the case of DateTime columns one can handle the PrintElementFormating event and change text of the print elements with the required format string private void RadGanttView1_PrintElementFormatting(object sender, Telerik.WinControls.UI.GanttViewPrintElementFormattingEventArgs e) { if (e.PrintContext == GanttViewPrintElementContext.DataCell) { DateTime date; if (e.PrintElement.DrawText && DateTime.TryParse(e.PrintElement.Text, out date)) { e.PrintElement.Text = string.Format("{0:D}", date); } } }
See attached video to reproduce. Workaround: class MyGantt : RadGanttView { protected override RadGanttViewElement CreateGanttViewElement() { return new MyGanttElement(); } } class MyGanttElement : RadGanttViewElement { protected override void InitializeFields() { base.InitializeFields(); ThemeRole = "RadGanttViewElement"; } protected override bool EndEditCore(bool commitChanges) { if (this.ActiveEditor.Value == null) { GanttViewDataItem item = this.SelectedItem as GanttViewDataItem; this.ActiveEditor.Value = item[CurrentColumn]; } return base.EndEditCore(commitChanges); } }
How to reproduce: 1. Run the project 2. Press the radButton1 3. Edit description of the first line (Line whose Identifier is TestProject1) 4. Clicking some other line to end the edit causes the ASSERT to come up
How to reproduce: public partial class RadForm1 : Telerik.WinControls.UI.RadForm { public RadForm1() { InitializeComponent(); this.radGanttView1.GanttViewElement.GraphicalViewElement.TimelineStart = new DateTime(2010, 10, 9); this.radGanttView1.GanttViewElement.GraphicalViewElement.TimelineEnd = new DateTime(2010, 12, 10); //setup data items GanttViewDataItem item1 = new GanttViewDataItem(); item1.Start = new DateTime(2010, 10, 10); item1.End = new DateTime(2010, 10, 15); item1.Progress = 30m; item1.Title = "Summary task.1. title"; GanttViewDataItem subitem11 = new GanttViewDataItem(); subitem11.Start = new DateTime(2010, 10, 10); subitem11.End = new DateTime(2010, 10, 12); subitem11.Progress = 10m; subitem11.Title = "Sub-task.1.1 title"; GanttViewDataItem subitem12 = new GanttViewDataItem(); subitem12.Start = new DateTime(2010, 10, 12); subitem12.End = new DateTime(2010, 10, 15); subitem12.Progress = 20m; subitem12.Title = "Sub-task.1.2 title"; //add subitems item1.Items.Add(subitem11); item1.Items.Add(subitem12); this.radGanttView1.Items.Add(item1); GanttViewDataItem item2 = new GanttViewDataItem(); item2.Start = new DateTime(2010, 10, 12); item2.End = new DateTime(2010, 10, 18); item2.Progress = 40m; item2.Title = "Summary task.2. title"; GanttViewDataItem subitem21 = new GanttViewDataItem(); subitem21.Start = new DateTime(2010, 10, 12); subitem21.End = new DateTime(2010, 10, 13); subitem21.Progress = 10m; subitem21.Title = "Sub-task.2.1 title"; GanttViewDataItem subitem22 = new GanttViewDataItem(); subitem22.Start = new DateTime(2010, 10, 13); subitem22.End = new DateTime(2010, 10, 18); subitem22.Progress = 30m; subitem22.Title = "Sub-task.2.2 title"; GanttViewDataItem subitem23 = new GanttViewDataItem(); subitem23.Start = new DateTime(2010, 10, 18); subitem23.End = new DateTime(2010, 10, 18); subitem23.Title = "Sub-task.2.3 title"; //add subitems item2.Items.Add(subitem21); item2.Items.Add(subitem22); item2.Items.Add(subitem23); this.radGanttView1.Items.Add(item2); //add links between items GanttViewLinkDataItem link1 = new GanttViewLinkDataItem(); link1.StartItem = subitem11; link1.EndItem = subitem12; link1.LinkType = TasksLinkType.FinishToStart; this.radGanttView1.Links.Add(link1); GanttViewLinkDataItem link2 = new GanttViewLinkDataItem(); link2.StartItem = subitem21; link2.EndItem = subitem22; link2.LinkType = TasksLinkType.StartToStart; this.radGanttView1.Links.Add(link2); GanttViewLinkDataItem link3 = new GanttViewLinkDataItem(); link3.StartItem = subitem22; link3.EndItem = subitem23; link3.LinkType = TasksLinkType.FinishToStart; this.radGanttView1.Links.Add(link3); GanttViewTextViewColumn titleColumn = new GanttViewTextViewColumn("Title"); GanttViewTextViewColumn startColumn = new GanttViewTextViewColumn("Start"); GanttViewTextViewColumn endColumn = new GanttViewTextViewColumn("End"); this.radGanttView1.GanttViewElement.Columns.Add(titleColumn); this.radGanttView1.GanttViewElement.Columns.Add(startColumn); this.radGanttView1.GanttViewElement.Columns.Add(endColumn); this.radGanttView1.GanttViewElement.GraphicalViewElement.TimelineStart = new DateTime(2010, 10, 13); } private void radButton1_Click(object sender, EventArgs e) { RadPrintDocument doc = new RadPrintDocument(); doc.Landscape = true; RadPrintPreviewDialog dialog = new RadPrintPreviewDialog(); doc.AssociatedObject = this.radGanttView1; dialog.Document = doc; dialog.ShowDialog(); } } Workaround: create a custom RadGanttView public class MyRadGanttView : RadGanttView { public override string ThemeClassName { get { return typeof(RadGanttView).FullName; } } protected override PointF[] GetElementShape(GanttViewPrintElementContext context, RectangleF rect) { if (shouldPaintStartCap) { return base.GetElementShape(context, rect); } switch (context) { case GanttViewPrintElementContext.SummaryTaskElement: PointF[] summaryPoints = new PointF[5]; summaryPoints[0] = rect.Location; summaryPoints[1] = new PointF(rect.X, rect.Y + rect.Height / 4f); summaryPoints[2] = new PointF(rect.Right - 3, rect.Y + rect.Height / 4f); summaryPoints[3] = new PointF(rect.Right, rect.Y + rect.Height / 2f); summaryPoints[4] = new PointF(rect.Right, rect.Y); return summaryPoints; case GanttViewPrintElementContext.MilestoneElement: PointF[] milestonePoints = new PointF[4]; milestonePoints[0] = new PointF(rect.X, rect.Y); milestonePoints[1] = new PointF(rect.X + rect.Height / 2f, rect.Y + rect.Height / 2f); milestonePoints[2] = new PointF(rect.X, rect.Y + rect.Height); milestonePoints[3] = new PointF(rect.X - rect.Height / 2f, rect.Y + rect.Height / 2f); return milestonePoints; default: return null; } } private bool shouldPaintStartCap; protected override RectangleF GetPrintRectangle(GanttViewDataItem item, int index) { if (index < 0) { return RectangleF.Empty; } float x = (float)((item.Start - this.GanttViewElement.GraphicalViewElement.TimelineBehavior.AdjustedTimelineStart).TotalSeconds / this.GanttViewElement.GraphicalViewElement.OnePixelTime.TotalSeconds); this.shouldPaintStartCap = x > 0 ? true : false; x = Math.Max(x, 0); float y = index * (this.GanttViewElement.ItemHeight + this.GanttViewElement.ItemSpacing) + this.GanttViewElement.HeaderHeight; float width = (float)((item.End - item.Start).TotalSeconds / (float)this.GanttViewElement.GraphicalViewElement.OnePixelTime.TotalSeconds); return new RectangleF(x, y, width, (this.GanttViewElement.ItemHeight + this.GanttViewElement.ItemSpacing)); } }
To reproduce: click (mouse down) on a task but then release the mouse button off the task. It then stays selected even when I click on other tasks. You can repeat this over and over and end up with every task as "selected" as shown in the video. Workaround: AddHandler Me.RadGanttView1.GraphicalViewItemFormatting, AddressOf GraphicalViewItemFormatting Private Sub GraphicalViewItemFormatting(sender As Object, e As GanttViewGraphicalViewItemFormattingEventArgs) Dim taskItem As GanttViewTaskItemElement = TryCast(e.ItemElement, GanttViewTaskItemElement) If taskItem IsNot Nothing AndAlso taskItem.TaskElement.VisualState.Contains(".MouseDown") AndAlso Not taskItem.Selected Then taskItem.TaskElement.IsMouseDown = False End If End Sub
Workaround: handle the RadGanttView.GraphicalViewItemFormatting event: Private Sub GraphicalViewItemFormatting(sender As Object, e As GanttViewGraphicalViewItemFormattingEventArgs) Dim taskItem As GanttViewTaskItemElement = TryCast(e.ItemElement, GanttViewTaskItemElement) If taskItem IsNot Nothing Then taskItem.LeftLinkHandleElement.Opacity = 0 taskItem.RightLinkHandleElement.Opacity = 0 End If End Sub