Use the attached project to reproduce. The video shows what steps you need to take.
To reproduce: please refer to the attached sample project and gif file. Workaround: private void radGridView1_CellEditorInitialized(object sender, GridViewCellEventArgs e) { RadDateTimeEditor editor = e.ActiveEditor as RadDateTimeEditor; if (editor != null) { RadDateTimeEditorElement el = editor.EditorElement as RadDateTimeEditorElement; if (el != null) { el.TextBoxElement.TextBoxItem.GotFocus -= TextBoxItem_GotFocus; el.TextBoxElement.TextBoxItem.GotFocus += TextBoxItem_GotFocus; } } } private void TextBoxItem_GotFocus(object sender, EventArgs e) { RadTextBoxItem tb = sender as RadTextBoxItem; if (tb != null) { tb.SelectionLength = 0; } }
To reproduce: public RadForm1() { InitializeComponent(); this.radGridView1.MasterTemplate.Columns.Add(new GridViewDecimalColumn("ParentId")); this.radGridView1.MasterTemplate.Columns.Add(new GridViewTextBoxColumn("ParentName")); this.radGridView1.MasterTemplate.Rows.Add(1, "Item" + 1); this.radGridView1.MasterTemplate.Rows.Add(2, "Item" + 2); this.radGridView1.MasterTemplate.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill; for (int i = 0; i < 10; i++) { GridViewTemplate template = new GridViewTemplate(); template.AllowAddNewRow = false; template.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill; template.Caption = "Tab" + i; template.Columns.Add(new GridViewDecimalColumn("Id")); template.Columns.Add(new GridViewTextBoxColumn("Name")); this.radGridView1.MasterTemplate.Templates.Add(template); template.HierarchyDataProvider = new GridViewEventDataProvider(template); } this.radGridView1.RowSourceNeeded += radGridView1_RowSourceNeeded; } private void radGridView1_RowSourceNeeded(object sender, GridViewRowSourceNeededEventArgs e) { for (int i = 0; i < 10; i++) { GridViewRowInfo row = e.Template.Rows.NewRow(); row.Cells["Id"].Value = e.ParentRow.Cells["ParentId"].Value; row.Cells["name"].Value = "child row" + i; e.SourceCollection.Add(row); } } private void radGridView1_ViewCellFormatting(object sender, CellFormattingEventArgs e) { GridDetailViewCellElement cell = e.CellElement as GridDetailViewCellElement; if (cell != null) { RadPageViewStripElement strip = cell.PageViewElement as RadPageViewStripElement; strip.StripButtons = StripViewButtons.LeftScroll | StripViewButtons.RightScroll; } } If you have just one row on the master level, the strip buttons don't navigate the tabs. Workaround: add a dummy row that is hidden: private void radGridView1_RowFormatting(object sender, RowFormattingEventArgs e) { if (e.RowElement.RowInfo == this.radGridView1.Rows.Last()) { e.RowElement.RowInfo.Height = 1; e.RowElement.RowInfo.MinHeight = 1; e.RowElement.RowInfo.MaxHeight = 1; } else { e.RowElement.RowInfo.Height = 25; e.RowElement.RowInfo.MinHeight = 25; e.RowElement.RowInfo.MaxHeight = 25; } }
To reproduce: Sub New() InitializeComponent() Dim dt As New DataTable dt.Columns.Add("Id", GetType(Integer)) dt.Columns.Add("Name", GetType(String)) For index = 1 To 200000 dt.Rows.Add(index, "Item" & index) Next Me.RadGridView1.DataSource = dt Me.RadGridView1.MultiSelect = True Me.RadGridView1.SelectionMode = Telerik.WinControls.UI.GridViewSelectionMode.CellSelect End Sub Private Sub RadButton1_Click(sender As Object, e As EventArgs) Handles RadButton1.Click Dim sw As New Stopwatch sw.Start() Dim mi As MethodInfo = GetType(GridViewSelectedCellsCollection).GetMethod("BeginUpdate", BindingFlags.Instance Or BindingFlags.NonPublic) mi.Invoke(Me.RadGridView1.MasterTemplate.SelectedCells, Nothing) For Each row As GridViewDataRowInfo In Me.RadGridView1.Rows row.Cells("Name").IsSelected = True Next Dim mi2 As MethodInfo = GetType(GridViewSelectedCellsCollection).GetMethod("EndUpdate", BindingFlags.Instance Or BindingFlags.NonPublic) mi2.Invoke(Me.RadGridView1.MasterTemplate.SelectedCells, New Object() {True}) sw.Stop() RadMessageBox.Show(sw.ElapsedMilliseconds) End Sub
To reproduce: DataTable table; public RadForm1() { InitializeComponent(); table = GetTable(); radGridView1.DataSource = table; } private void radButton1_Click(object sender, EventArgs e) { var changes = table.GetChanges(); if (changes == null) { Console.WriteLine("No Changes"); } else { Console.WriteLine("Saved"); foreach (DataRow item in changes.Rows) { Console.WriteLine(item.RowState.ToString()); } } table.AcceptChanges(); } static DataTable GetTable() { DataTable table = new DataTable(); table.Columns.Add("Dosage", typeof(int)); table.Columns.Add("Drug", typeof(string)); table.Columns.Add("Name", typeof(string)); table.Columns.Add("Date", typeof(DateTime)); table.Rows.Add(25, "Indocin", "David", DateTime.Now); table.Rows.Add(50, "Enebrel", "Sam", DateTime.Now); table.Rows.Add(10, "Hydralazine", "Christoff", DateTime.Now); table.Rows.Add(21, "Combivent", "Janet", DateTime.Now); table.Rows.Add(100, "Dilantin", "Melanie", DateTime.Now); table.AcceptChanges(); return table; } Workaround: (this.radGridView1.CurrentRow.DataBoundItem as IEditableObject).EndEdit();
To reproduce: use the following code snippet, save the layout and load it afterwards. You will notice that only the master and the first child template are successfully loaded. public Form1() { InitializeComponent(); DataTable dt = new DataTable(); dt.Columns.Add("Id", typeof(int)); dt.Columns.Add("Name", typeof(string)); for (int i = 0; i < 5; i++) { dt.Rows.Add(i, "Parent" + i); } this.radGridView1.MasterTemplate.DataSource = dt; this.radGridView1.MasterTemplate.AutoSizeColumnsMode = Telerik.WinControls.UI.GridViewAutoSizeColumnsMode.Fill; //child level 1 GridViewTemplate template = new GridViewTemplate(); template.DataSource = GetData(5, 20, 0, 5); template.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill; radGridView1.MasterTemplate.Templates.Add(template); GridViewRelation relation = new GridViewRelation(radGridView1.MasterTemplate); relation.ChildTemplate = template; relation.RelationName = "ParentChild"; relation.ParentColumnNames.Add("Id"); relation.ChildColumnNames.Add("ParentId"); radGridView1.Relations.Add(relation); //child level 2 GridViewTemplate template2 = new GridViewTemplate(); template2.DataSource = GetData(20, 40, 5, 20); template2.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill; template.Templates.Add(template2); GridViewRelation relation2 = new GridViewRelation(template); relation2.ChildTemplate = template2; relation2.RelationName = "ParentChild"; relation2.ParentColumnNames.Add("Id"); relation2.ChildColumnNames.Add("ParentId"); radGridView1.Relations.Add(relation2); //child level 3 GridViewTemplate template3 = new GridViewTemplate(); template3.DataSource = GetData(40, 100, 20, 40); template3.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill; template2.Templates.Add(template3); GridViewRelation relation3 = new GridViewRelation(template2); relation3.ChildTemplate = template3; relation3.RelationName = "ParentChild"; relation3.ParentColumnNames.Add("Id"); relation3.ChildColumnNames.Add("ParentId"); radGridView1.Relations.Add(relation3); //child level 4 GridViewTemplate template4 = new GridViewTemplate(); template4.DataSource = GetData(100, 200, 40, 100); template4.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill; template3.Templates.Add(template4); GridViewRelation relation4 = new GridViewRelation(template3); relation4.ChildTemplate = template4; relation4.RelationName = "ParentChild"; relation4.ParentColumnNames.Add("Id"); relation4.ChildColumnNames.Add("ParentId"); radGridView1.Relations.Add(relation4); } private object GetData(int from, int to, int parentFrom, int parentTo) { DataTable dt = new DataTable(); dt.Columns.Add("Id", typeof(int)); dt.Columns.Add("Name", typeof(string)); dt.Columns.Add("ParentId", typeof(int)); Random rand = new Random(); for (int i = from; i < to; i++) { dt.Rows.Add(i, "Child" + i, rand.Next(parentFrom, parentTo)); } return dt; } private void radButton1_Click(object sender, EventArgs e) { string s = "default.xml"; SaveFileDialog dialog = new SaveFileDialog(); dialog.Filter = "xml files (*.xml)|*.xml|All files (*.*)|*.*"; dialog.Title = "Select a xml file"; if (dialog.ShowDialog() == DialogResult.OK) { s = dialog.FileName; } this.radGridView1.SaveLayout(s); } private void radButton2_Click(object sender, EventArgs e) { string s = "default.xml"; OpenFileDialog dialog = new OpenFileDialog(); dialog.Filter = "xml files (*.xml)|*.xml|All files (*.*)|*.*"; dialog.Title = "Select a xml file"; if (dialog.ShowDialog() == DialogResult.OK) { s = dialog.FileName; } this.radGridView1.LoadLayout(s); } Workaround: grid templates for the inner levels are recreated after loading the layout. Their DataSource is null and the existing relations points to the old templates. Clear the relations and setup them again with the new child template instances.
Workaround: public partial class Form1 : Form { public Form1() { InitializeComponent(); this.radGridView1.DataSource = this.GetData(); this.radGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill; ((GridViewDateTimeColumn)this.radGridView1.Columns["Date"]).FormatString = "{0: yyyy-MM-dd hh:mm:ss.fff tt}"; } private DataTable GetData() { DataTable dt = new DataTable(); dt.Columns.Add("Id", typeof(int)); dt.Columns.Add("Name", typeof(string)); dt.Columns.Add("Date", typeof(DateTime)); dt.Columns.Add("Bool", typeof(bool)); for (int i = 0; i < 100; i++) { dt.Rows.Add(i, "Name " + i, DateTime.Now.AddDays(i), i % 2 == 0); } return dt; } } public class MyRadGridView : RadGridView { public override string ThemeClassName { get { return typeof(RadGridView).FullName; } } protected override RadGridViewElement CreateGridViewElement() { return new MyRadGridViewElement(); } } public class MyRadGridViewElement : RadGridViewElement { protected override Type ThemeEffectiveType { get { return typeof(MyRadGridViewElement); } } protected override MasterGridViewTemplate CreateTemplate() { return new MyMasterGridViewTemplate(); } } public class MyMasterGridViewTemplate : MasterGridViewTemplate { public override void Copy() { base.Copy(); GridViewCellInfo[] cells = null; if (this.SelectionMode == GridViewSelectionMode.CellSelect) { cells = new GridViewCellInfo[this.SelectedCells.Count]; this.SelectedCells.CopyTo(cells, 0); } else if (this.SelectionMode == GridViewSelectionMode.FullRowSelect) { GridViewDataRowInfo row = this.SelectedRows[0] as GridViewDataRowInfo; if (this.SelectedRows.Count == 1 && row.ViewTemplate.CurrentColumn != null) { cells = new GridViewCellInfo[row.Cells.Count]; for (int i = 0; i < row.Cells.Count; i++) { cells[i] = row.Cells[i]; } } } if (Clipboard.GetData(DataFormats.Text) != null) { string data = Clipboard.GetData(DataFormats.Text).ToString(); if (data != string.Empty && cells != null) { var values = data.Split(new char[] { '\t' }, StringSplitOptions.RemoveEmptyEntries); StringBuilder sb = new StringBuilder(); foreach (string value in values) { DateTime date; if (DateTime.TryParse(value, out date)) { string baseFormat = "yyyy-MM-dd HH:mm tt"; foreach (var cell in cells) { if (cell.ColumnInfo is GridViewDateTimeColumn && ((DateTime)cell.Value).ToString(baseFormat) == date.ToString(baseFormat)) { sb.Append(string.Format(((GridViewDateTimeColumn)cell.ColumnInfo).FormatString, cell.Value) + "\t"); break; } } } else { sb.Append(value + "\t"); } } Clipboard.Clear(); Clipboard.SetData(DataFormats.Text, sb.ToString()); } } } }
To reproduce: public Form1() { InitializeComponent(); for (int i = 0; i < 10; i++) { this.radGridView1.Columns.Add("column " + i); } int charsCount = 5; for (int i = 0; i < 20; i++) { this.radGridView1.Rows.Add(new string('0', charsCount), new string('1', charsCount), new string('2', charsCount), new string('3', charsCount), new string('4', charsCount), new string('5', charsCount), new string('6', charsCount), new string('7', charsCount), new string('8', charsCount), new string('9', charsCount)); } HtmlViewDefinition view = new HtmlViewDefinition(); view.RowTemplate.Rows.Add(new RowDefinition()); view.RowTemplate.Rows.Add(new RowDefinition()); view.RowTemplate.Rows.Add(new RowDefinition()); view.RowTemplate.Rows[0].Cells.Add(new CellDefinition("Column 0", 0, 1, 1)); view.RowTemplate.Rows[0].Cells.Add(new CellDefinition("Column 1", 0, 1, 3)); view.RowTemplate.Rows[0].Cells.Add(new CellDefinition("Column 2", 0, 1, 1)); view.RowTemplate.Rows[0].Cells.Add(new CellDefinition("Column 3", 0, 1, 1)); view.RowTemplate.Rows[0].Cells.Add(new CellDefinition("Column 7", 0, 1, 1)); view.RowTemplate.Rows[1].Cells.Add(new CellDefinition("Column 4", 0, 1, 2)); view.RowTemplate.Rows[1].Cells.Add(new CellDefinition("Column 5", 0, 2, 1)); view.RowTemplate.Rows[1].Cells.Add(new CellDefinition("Column 8", 0, 1, 1)); view.RowTemplate.Rows[2].Cells.Add(new CellDefinition("Column 6", 0, 2, 1)); view.RowTemplate.Rows[2].Cells.Add(new CellDefinition("Column 9", 0, 1, 1)); this.radGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill; this.radGridView1.ViewDefinition = view; } Workaround: private void radGridView1_SizeChanged(object sender, EventArgs e) { this.radGridView1.MasterTemplate.Refresh(); }
Please refer to the attached screenshot. Workaround: public Form1() { InitializeComponent(); DataTable dt = new DataTable(); dt.Columns.Add("Id"); dt.Columns.Add("Name"); for (int i = 0; i < 5; i++) { dt.Rows.Add(i, "Item" + i); } this.radGridView1.DataSource = dt; this.radGridView1.AutoSizeColumnsMode = Telerik.WinControls.UI.GridViewAutoSizeColumnsMode.Fill; this.radGridView1.AllowSearchRow = true; this.radGridView1.SearchRowPosition = Telerik.WinControls.UI.SystemRowPosition.Bottom; this.radGridView1.ViewDefinition = new CustomTableViewDefition(); } public class CustomTableViewDefition : TableViewDefinition { public override IRowView CreateViewUIElement(GridViewInfo viewInfo) { return new CustomTableElement(); } } public class CustomTableElement : GridTableElement { protected override RowsContainerElement CreateViewElement() { return new CustomRowsContainerElement(); } } public class CustomRowsContainerElement : RowsContainerElement { protected override SizeF ArrangeOverride(SizeF finalSize) { float y = 0; this.TopPinnedRows.Arrange(new RectangleF(0, y, finalSize.Width, this.TopPinnedRows.DesiredSize.Height)); y += this.TopPinnedRows.DesiredSize.Height + ElementSpacing; this.ScrollableRows.Arrange(new RectangleF(0, y, finalSize.Width, this.ScrollableRows.DesiredSize.Height)); y += this.ScrollableRows.DesiredSize.Height + ElementSpacing; this.BottomPinnedRows.Arrange(new RectangleF(0, finalSize.Height - this.BottomPinnedRows.DesiredSize.Height, finalSize.Width, this.BottomPinnedRows.DesiredSize.Height)); return finalSize; } }
Repeat the master template headers right after the end of an expanded detail template. The purpose is clarity for the end user.
The issue can be reproduced with the .40 version of the assemblies and in a scenario in which the grid is added as a RadMenuHostItem to the Items collection of a drop-down button. Workaround: set the BindingContext of the grid to equal that of the form: public Form1() { InitializeComponent(); radGridView1.BindingContext = this.BindingContext; }
To reproduce: 1. Use the following code: public Form1() { InitializeComponent(); this.radGridView1.EnableFiltering = true; GridViewDecimalColumn col = new GridViewDecimalColumn(); col.Name = "Calculated Column"; col.HeaderText = "Order value"; radGridView1.Columns.Add(col); radGridView1.Columns["Calculated Column"].Expression = "Freight/Sum(Freight)"; } private void Form1_Load(object sender, EventArgs e) { this.ordersTableAdapter.Fill(this.nwindDataSet.Orders); this.radGridView1.DataSource = this.ordersBindingSource; this.radGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill; GridViewSummaryItem summaryItem = new GridViewSummaryItem(); summaryItem.Name = "Freight"; summaryItem.Aggregate = GridAggregateFunction.Sum ; GridViewSummaryRowItem summaryRowItem = new GridViewSummaryRowItem(); summaryRowItem.Add(summaryItem); this.radGridView1.SummaryRowsTop.Add(summaryRowItem); this.radGridView1.SummaryRowsBottom.Add(summaryRowItem); } 2. Filter the grid by EmployeeID for example. You will notice that the summary item for Freight is recalculated considering the filtered rows. However, the calculated column doesn't update its values.
To reproduce: - Select several rows and cells in excel and copy them. - Paste in the self-reference grid. - Only the first row is copied. Workaround: private void RadGridView1_Pasting(object sender, GridViewClipboardEventArgs e) { e.Cancel = true; List<List<string>> rows = this.GetTextData(); PrintGridTraverser traverser = new PrintGridTraverser(this.radGridView1.MasterView); while (traverser.Current != this.radGridView1.CurrentRow) { traverser.MoveNext(); } traverser.MovePrevious(); int rowIndex = 0; int colIndex = this.radGridView1.CurrentColumn.Index; while (traverser.MoveNext() && rowIndex < rows.Count) { for (int i = colIndex; i < this.radGridView1.Columns.Count && i - colIndex < rows[rowIndex].Count; i++) { traverser.Current.Cells[i].Value = rows[rowIndex][i - colIndex]; } rowIndex++; } }
How to reproduce: check the attached video as well public partial class Form1 : Form { public Form1() { InitializeComponent(); this.radGridView1.DataSource = this.GetData(); } private DataTable GetData() { DataTable dt = new DataTable(); dt.Columns.Add("Id", typeof(int)); dt.Columns.Add("Name", typeof(string)); dt.Columns.Add("Date", typeof(DateTime)); dt.Columns.Add("Bool", typeof(bool)); for (int i = 0; i < 10; i++) { dt.Rows.Add(i, "Name " + i, DateTime.Now.AddDays(i), i % 2 == 0); } return dt; } private void radButton1_Click(object sender, EventArgs e) { this.radGridView1.TableElement.ScrollToRow(0); this.radGridView1.Focus(); } } Workaround: call the method if the row is not selected private void radButton1_Click(object sender, EventArgs e) { if (!this.radGridView1.Rows[0].IsSelected) { this.radGridView1.TableElement.ScrollToRow(0); } this.radGridView1.Focus(); }
To reproduce: Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load Me.ProductsTableAdapter.Fill(Me.NwindDataSet.Products) Me.CategoriesTableAdapter.Fill(Me.NwindDataSet.Categories) Me.ProductsTableAdapter.Fill(Me.NwindDataSet.Products) Me.CategoriesTableAdapter.Fill(Me.NwindDataSet.Categories) RadGridView1.AutoGenerateHierarchy = True RadGridView1.DataSource = Me.NwindDataSet RadGridView1.DataMember = "Categories" End Sub Private Sub RadButton1_Click(sender As Object, e As EventArgs) Handles RadButton1.Click Dim style As New GridPrintStyle() style.PrintHierarchy = True style.HierarchyIndent = 20 style.ChildViewPrintMode = ChildViewPrintMode.SelectViewToPrint Me.RadGridView1.PrintStyle = style Me.RadGridView1.PrintPreview() End Sub Please refer to the attached gif file. Workaround: Private Sub RadButton1_Click(sender As Object, e As EventArgs) Handles RadButton1.Click Me.RadGridView1.PrintSettingsDialogFactory = New CustomGridViewPrintSettingsDialogFactory() Dim style As New GridPrintStyle() style.PrintHierarchy = True style.HierarchyIndent = 20 style.ChildViewPrintMode = ChildViewPrintMode.SelectViewToPrint Me.RadGridView1.PrintStyle = style Me.RadGridView1.PrintPreview() End Sub Public Class CustomGridViewPrintSettingsDialog Inherits GridViewPrintSettingsDialog Sub New(document As RadPrintDocument) MyBase.New(document) End Sub Protected Overrides Sub LoadSettings() MyBase.LoadSettings() Dim gridView As RadGridView = TryCast(Me.PrintDocument.AssociatedObject, RadGridView) Me.printStyleSettingControl.PrintStyle.PrintHierarchy =gridView.PrintStyle.PrintHierarchy End Sub End Class Public Class CustomGridViewPrintSettingsDialogFactory Implements IPrintSettingsDialogFactory Public Function CreateDialog(document As RadPrintDocument) As Form Implements IPrintSettingsDialogFactory.CreateDialog Return New CustomGridViewPrintSettingsDialog(document) End Function End Class
To reproduce: public Form1() { InitializeComponent(); this.radGridView1.Columns.Add("Name"); this.radGridView1.Columns.Add("ID"); this.radGridView1.RowsChanged += radGridView1_RowsChanged; } private void radGridView1_RowsChanged(object sender, GridViewCollectionChangedEventArgs e) { Console.WriteLine(e.Action); if (e.Action == Telerik.WinControls.Data.NotifyCollectionChangedAction.Add) { GridViewRowInfo row = e.NewItems[0] as GridViewRowInfo; row.Cells["ID"].Value = this.radGridView1.Rows.Count; } } private void radButton1_Click(object sender, EventArgs e) { this.radGridView1.Rows.Add("Item" + this.radGridView1.Rows.Count); } Note: the first firing of the RowsChanged event used to be with Action=Add.