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
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)); } }
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); } }
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); } } }
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); } } }
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: 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; } }
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); }
Hi,
why is the datatype of the ChildMember/ParentMember item limited to Int32? This is a problem when displaying tasks or events from tables with string or UUID idents. It would be a more flexible control if the type could be any type. Should not be a big deal to change this or is it?
Thank you und kind regards
Karsten
The latest release of WinForms causes a fatal exception when adding an item to a BindingList that is used in a RadGridView and a RadGanttView.
The first time an item is added there is not issue.
The second time an item is added, the following exception occurs.
System.NullReferenceException: Object reference not set to an instance of an object.
at Telerik.WinControls.UI.GanttViewBindingProvider.GanttTaskList.IndexOf(Object key)
at Telerik.WinControls.UI.GanttViewBindingProvider.GanttTaskList.get_Item(Object key)
at Telerik.WinControls.UI.GanttViewBindingProvider.AddTaskByCM(CurrencyManager cm, Int32 index)
at System.ComponentModel.ListChangedEventHandler.Invoke(Object sender, ListChangedEventArgs e)
at System.Windows.Forms.CurrencyManager.OnListChanged(ListChangedEventArgs e)
at System.Windows.Forms.CurrencyManager.List_ListChanged(Object sender, ListChangedEventArgs e)
at System.ComponentModel.BindingList`1.OnListChanged(ListChangedEventArgs e)
at System.ComponentModel.BindingList`1.FireListChanged(ListChangedType type, Int32 index)
at MissileWarningThreatPlanner.EventWindow.EventList.GenMissileEventWorker_RunWorkerCompleted(Object sender, RunWorkerCompletedEventArgs e) in C:\Shape Source\VS\MissileWarningThreatPlanner - VS2010\MissileWarningThreatPlanner\EventWindow\EventList.cs:line 5329
at System.ComponentModel.BackgroundWorker.OnRunWorkerCompleted(RunWorkerCompletedEventArgs e)
This is code that has not been modified for quite some time. There has been no issue until the latest release.
I do not have time to try to create a simple example to try to reproduce the error at this time. I will if possible.
For now, we are forced to revert to a previous version.
Ken...
Please refer to the attached sample project and run it. Select a random item and press the button. You will obtain the error. If no selection is available, the item is removed as expected.
Workaround: use Begin/EndUpdate block while deleting a record from the DataTable:
Please run the attached sample project. Select one of the child tasks and click the button. The new task is expected to be inserted at the selected item's position. However, it is appended at the bottom as it is demonstrated in the gif file.
Workaround: rebind RadGanttView after inserting a new row to the DataTable:
Private Sub RadButton1_Click(sender As Object, e As EventArgs) Handles RadButton1.Click
Please refer to the attached gif file.
Steps :Add formatting or a painting event allowing customization of the links in the control
Steps to reproduce: 1. Add a RadGanttView to a form. 2. Fill it with data. 3. Scroll up/down. Under some circumstances there is a chance that some of the items will have a wrong layout. After clicking anywhere on the graphical view the items will be placed properly.
Steps to reproduce: 1. Add a gantt view to a form. 2. Bind it to a data source with 3000 items 3. Scroll the gantt view up and down. You will notice that the memory consumption by the project increases and the performance of the gantt view decreases.
For example the HandleMouseMove event can not be overridden in order to allow dragging on the Y coordinate. Also some internal methods should be exposed.