Workaround: private void radGridView1_CellFormatting(object sender, Telerik.WinControls.UI.CellFormattingEventArgs e) { GridDataCellElement cell = e.CellElement as GridDataCellElement ; if (cell!=null && cell.SelfReferenceLayout!=null) { foreach (RadElement item in cell.SelfReferenceLayout.StackLayoutElement.Children) { if (!(item is GridTreeExpanderItem)) { item.Visibility = ElementVisibility.Collapsed; } else { item.Visibility = ElementVisibility.Visible; } } } }
Use attached to reproduce. Workaround: DragDropService.AllowAutoScrollColumnsWhileDragging = false; DragDropService.AllowAutoScrollRowsWhileDragging = false;
Use attached to reproduce. Workaround: this.LoadFieldList(hiddenGrid.MasterTemplate); this.FieldList.Add(new Telerik.Data.Expressions.ExpressionItem() { Name = "Test", Description = "Test", Syntax = "Test", Type = Telerik.Data.Expressions.ExpressionItemType.Field, Value = "Test" });
Please refer to the attached sample project. The ResizeColumnsProportionally.gif illustrates the correct behavior of columns resizing. However, if you make a certain column with fixed size, the columns resizing is not proportional any more. The ColumnsWidthNOTAdjustedProportionally.gif demonstrates better the wrong behavior. Workaround: handle the SizeChanged event and adjust the columns' width property programmatically in order to obtain the desired widths.
To reproduce: Public Class RadForm1 Public RadGridView1 As RadGridView Private Sub RadForm1_Load(sender As Object, e As EventArgs) Handles Me.Load CreateGrid() FormatGrid() SetDataSource() End Sub Private Sub CreateGrid() Try RadGridView1 = New RadGridView Me.Controls.Add(RadGridView1) Catch ex As Exception MessageBox.Show(Me, ex.Message) End Try End Sub Private Sub FormatGrid() Dim col As GridViewTextBoxColumn With RadGridView1 col = New GridViewTextBoxColumn With col .FieldName = "FieldID" 'NOTE: Comment out NullValue = "" to prevent the unhandled exception .NullValue = "" End With .Columns.Add(col) End With End Sub Private Sub SetDataSource() Dim table As DataTable = Nothing Dim row As DataRow = Nothing table = New DataTable("GridList") table.Columns.Add("FieldID", GetType(System.Guid)) row = table.NewRow row("FieldID") = Guid.Empty table.Rows.Add(row) RadGridView1.DataSource = table End Sub End Class Workaround: Comment this line NullValue = ""
Use attached to reproduce. Workaround - Set the position at runtime. Me.radGridView1.MasterTemplate.AddNewRowPosition = Telerik.WinControls.UI.SystemRowPosition.Bottom
To reproduce: if you pin a calculator or a hyperlink column you will notice that the cells belonging to these columns remain white. However, the cells from other column types have a light blue/gray fill color for pinned state. Workaround: private void RadGridView1_CellFormatting(object sender, CellFormattingEventArgs e) { if (e.Column.IsPinned) { e.CellElement.BackColor = Color.FromArgb(235, 244, 252); } else { e.CellElement.ResetValue(LightVisualElement.BackColorProperty, ValueResetFlags.Local); } }
To reproduce: please refer to the attached screenshot. Workaround: add the FilterDescriptor programmatically: https://docs.telerik.com/devtools/winforms/gridview/filtering/setting-filters-programmatically-(simple-descriptors)
Excel does not support dates prior to 1/1/1900, however, we could export such dates as simple strings: https://support.office.com/en-us/article/excel-specifications-and-limits-1672b34d-7043-467e-8e27-269d656771c3 How to reproduce: public partial class Form1 : RadForm { public Form1() { InitializeComponent(); this.radGridView1.DataSource = this.GetData(); this.radGridView1.AutoSizeColumnsMode = Telerik.WinControls.UI.GridViewAutoSizeColumnsMode.Fill; } private object GetData() { DataTable dt = new DataTable(); dt.Columns.Add("Id", typeof(int)); dt.Columns.Add("Name", typeof(string)); dt.Columns.Add("Bool", typeof(bool)); dt.Columns.Add("Date", typeof(DateTime)); DateTime date = new DateTime(1850, 1, 1); for (int i = 0; i < 100; i++) { dt.Rows.Add(i, "Name " + i, i % 2 == 0, date.AddYears(i)); } return dt; } FieldInfo fi; private void radButton1_Click(object sender, EventArgs e) { //Old Export using the ExcelML format this.fi = typeof(Telerik.WinControls.UI.Export.ExcelML.CellElement).GetField("_dataElement", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); ExportToExcelML exporter = new ExportToExcelML(this.radGridView1); string fileName = @"..\..\data.xls"; exporter.RunExport(fileName); //New export utilizing the SpreadProcessing libraries GridViewSpreadExport spreadExporter = new GridViewSpreadExport(this.radGridView1); SpreadExportRenderer exportRenderer = new SpreadExportRenderer(); spreadExporter.RunExport(@"..\..\data.xlsx", exportRenderer); } } Workaround: handle the CellFormatting event public partial class Form1 : RadForm { public Form1() { InitializeComponent(); this.radGridView1.DataSource = this.GetData(); this.radGridView1.AutoSizeColumnsMode = Telerik.WinControls.UI.GridViewAutoSizeColumnsMode.Fill; } private object GetData() { DataTable dt = new DataTable(); dt.Columns.Add("Id", typeof(int)); dt.Columns.Add("Name", typeof(string)); dt.Columns.Add("Bool", typeof(bool)); dt.Columns.Add("Date", typeof(DateTime)); DateTime date = new DateTime(1850, 1, 1); for (int i = 0; i < 100; i++) { dt.Rows.Add(i, "Name " + i, i % 2 == 0, date.AddYears(i)); } return dt; } FieldInfo fi; private void radButton1_Click(object sender, EventArgs e) { //Old Export using the ExcelML format this.fi = typeof(Telerik.WinControls.UI.Export.ExcelML.CellElement).GetField("_dataElement", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); ExportToExcelML exporter = new ExportToExcelML(this.radGridView1); exporter.ExcelCellFormatting += Exporter_ExcelCellFormatting; string fileName = @"..\..\data.xls"; exporter.RunExport(fileName); //New export utilizing the SpreadProcessing libraries GridViewSpreadExport spreadExporter = new GridViewSpreadExport(this.radGridView1); spreadExporter.CellFormatting += SpreadExporter_CellFormatting; SpreadExportRenderer exportRenderer = new SpreadExportRenderer(); spreadExporter.RunExport(@"..\..\data.xlsx", exportRenderer); } private void SpreadExporter_CellFormatting(object sender, Telerik.WinControls.Export.CellFormattingEventArgs e) { if (e.GridRowIndex >= 1 && e.GridCellInfo.ColumnInfo is GridViewDateTimeColumn && ((DateTime)e.GridCellInfo.Value).Year < 1900) { Telerik.Windows.Documents.Spreadsheet.Model.CellSelection cell = e.CellSelection as Telerik.Windows.Documents.Spreadsheet.Model.CellSelection; cell.SetValue(e.GridCellInfo.Value.ToString()); } } private void Exporter_ExcelCellFormatting(object sender, Telerik.WinControls.UI.Export.ExcelML.ExcelCellFormattingEventArgs e) { if (e.GridRowIndex > -1 && e.GridCellInfo.ColumnInfo is GridViewDateTimeColumn && ((DateTime)e.GridCellInfo.Value).Year < 1900) { DataElement data = new DataElement(); data.DataItem = e.GridCellInfo.Value.ToString(); this.fi.SetValue(e.ExcelCellElement, data); } } }
Bind the grid to the following DataTable: DataTable dt = new DataTable(); dt.Columns.Add("X.Y"); dt.Columns.Add("X"); dt.Rows.Add("Data X.Y", "Data X"); this.radGridView1.DataSource = dt; You will notice that the second column "X" is missing. Note: if you change the order of adding the columns, both columns will be added.
To reproduce: this.radGridView1.SummaryRowsBottom.Insert(0, summaryRowItem2); this.radGridView1.SummaryRowsBottom.Move(2, 0); Workaround: Remove all items and add them back with a spesific order.
How to reproduce: check the attached project and video
Please refer to the attached sample project and follow the steps illustrated in the gif file. Note: the same behavior is observed with the CellValidating event in the new row. Workaround: use the RowValidating event instead: private void radGridView1_RowValidating(object sender, Telerik.WinControls.UI.RowValidatingEventArgs e) { if (e.Row is Telerik.WinControls.UI.GridViewNewRowInfo && e.Row.Cells["Id"].Value == null) { this.radGridView1.MasterView.TableAddNewRow.CancelAddNewRow(); this.radGridView1.CurrentRow = this.radGridView1.MasterView.TableAddNewRow; } }
NOTE: The CellValidating event is fired multiple times as well when you select a new tab in RadDock. There is a second project attached.
To reproduce: this.radGridView1.Columns.Add("FIRST CELL ID A"); this.radGridView1.Rows.Add("405-55-214-41763"); this.radGridView1.Rows.Add("405-55-214-46682"); this.radGridView1.Rows.Add("405-55-214-46682"); this.radGridView1.AutoSizeColumnsMode = Telerik.WinControls.UI.GridViewAutoSizeColumnsMode.Fill; this.radGridView1.MultiSelect = true; this.radGridView1.SelectionMode = Telerik.WinControls.UI.GridViewSelectionMode.CellSelect; Please refer to the attached gif file illustrating better the text moving. Workaround: private void radGridView1_CellFormatting(object sender, Telerik.WinControls.UI.CellFormattingEventArgs e) { e.CellElement.BorderBottomWidth = 2; e.CellElement.BorderRightWidth = 2; e.CellElement.BorderTopWidth = 2; e.CellElement.BorderLeftWidth = 2; }
The new mode should allow copying of single cells even when having the SelectionMode set to FullRowSelect. The attached project features a possible workaround.
To reproduce: run the attached project and toggle the checkbox in the header cell of the child template. Workaround: use a custom GridCheckBoxHeaderCellElement public partial class RadForm1 : Telerik.WinControls.UI.RadForm { public RadForm1() { InitializeComponent(); this.radGridView1.CreateCell += radGridView1_CreateCell; DataTable dt = new DataTable(); dt.Columns.Add("CategoryId", typeof(int)); dt.Columns.Add("CategoryName", typeof(string)); dt.Columns.Add("ParentCategoryId", typeof(int)); dt.Rows.Add(1, "Category1", 0); dt.Rows.Add(2, "Category2", 0); dt.Rows.Add(3, "Category3", 0); Random rand = new Random(); for (int i = 4; i < 20; i++) { dt.Rows.Add(i, "Category" + i, rand.Next(1, 4)); } this.radGridView1.Relations.AddSelfReference(this.radGridView1.MasterTemplate, "CategoryId", "ParentCategoryId"); this.radGridView1.DataSource = dt; this.radGridView1.AutoSizeColumnsMode = Telerik.WinControls.UI.GridViewAutoSizeColumnsMode.Fill; GridViewTemplate childTemplate = CreateChildTemplate(); GridViewRelation relation = new GridViewRelation( this.radGridView1.MasterTemplate, childTemplate); relation.ChildColumnNames.Add("CategoryId"); relation.ParentColumnNames.Add("CategoryId"); this.radGridView1.Relations.Add(relation); } private void radGridView1_CreateCell(object sender, GridViewCreateCellEventArgs e) { if (e.CellType == typeof(GridCheckBoxHeaderCellElement)) { e.CellElement = new CustomGridCheckBoxHeaderCellElement(e.Column, e.Row); } } private GridViewTemplate CreateChildTemplate() { GridViewTemplate childTemplate = new GridViewTemplate(); childTemplate.AutoGenerateColumns = false; this.radGridView1.Templates.Add(childTemplate); GridViewDecimalColumn decColumn = new GridViewDecimalColumn { Name = "CategoryId", HeaderText = "CategoryId Id", FieldName = "CategoryId", IsVisible = false, MinWidth = 100 }; childTemplate.Columns.Add(decColumn); GridViewTextBoxColumn tbxColumn = new GridViewTextBoxColumn { Name = "RightName", HeaderText = "Right Name", FieldName = "RGT_NAME", ReadOnly = true, MinWidth = 100 }; childTemplate.Columns.Add(tbxColumn); GridViewCheckBoxColumn chkxColumn = new GridViewCheckBoxColumn { Name = "Checkbox", EnableHeaderCheckBox = true, FieldName = "HasAccess", }; childTemplate.Columns.Add(chkxColumn); childTemplate.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill; return childTemplate; } public class CustomGridCheckBoxHeaderCellElement : GridCheckBoxHeaderCellElement { public CustomGridCheckBoxHeaderCellElement(GridViewColumn column, GridRowElement row) : base(column, row) { } public bool SuspendProcessingToggleStateChanged { get { FieldInfo fi = typeof(GridCheckBoxHeaderCellElement).GetField("suspendProcessingToggleStateChanged", BindingFlags.NonPublic | BindingFlags.Instance); return (bool)fi.GetValue(this); } set { FieldInfo fi = typeof(GridCheckBoxHeaderCellElement).GetField("suspendProcessingToggleStateChanged", BindingFlags.NonPublic | BindingFlags.Instance); fi.SetValue(this, value); } } public bool ShouldCheckDataRows { get { FieldInfo fi = typeof(GridCheckBoxHeaderCellElement).GetField("shouldCheckDataRows", BindingFlags.NonPublic | BindingFlags.Instance); return (bool)fi.GetValue(this); } set { FieldInfo fi = typeof(GridCheckBoxHeaderCellElement).GetField("shouldCheckDataRows", BindingFlags.NonPublic | BindingFlags.Instance); fi.SetValue(this, value); } } protected override void checkbox_ToggleStateChanged(object sender, StateChangedEventArgs args) { if (SuspendProcessingToggleStateChanged) { return; } if (this.ViewTemplate != null && !this.ViewTemplate.IsSelfReference && !this.MasterTemplate.IsSelfReference) { this.MasterTemplate.BeginUpdate(); } else { this.TableElement.BeginUpdate(); } object valueState = DBNull.Value; if (args.ToggleState == ToggleState.On) { valueState = true; } else if (args.ToggleState == ToggleState.Off) { valueState = false; } else if (args.ToggleState == ToggleState.Indeterminate) { valueState = null; } RaiseToggleStateEvent(); if (!ShouldCheckDataRows) { if (this.ViewTemplate != null && !this.ViewTemplate.IsSelfReference && !this.MasterTemplate.IsSelfReference) { this.MasterTemplate.EndUpdate(true, new DataViewChangedEventArgs(ViewChangedAction.DataChanged)); } return; } this.GridViewElement.EditorManager.EndEdit(); this.TableElement.BeginUpdate(); this.MasterTemplate.MasterViewInfo.TableSearchRow.SuspendSearch(); List<GridViewRowInfo> list = GetRowsToIterateOver(); foreach (GridViewRowInfo rowInfo in list) { GridViewGroupRowInfo groupRow = rowInfo as GridViewGroupRowInfo; if (groupRow != null) { this.CheckAllCheckBoxInChildRows(groupRow, valueState); } else { rowInfo.Cells[this.ColumnIndex].Value = valueState; } } this.MasterTemplate.MasterViewInfo.TableSearchRow.ResumeSearch(); this.TableElement.EndUpdate(false); if (this.ViewTemplate != null && !this.ViewTemplate.IsSelfReference && !this.MasterTemplate.IsSelfReference) { this.MasterTemplate.EndUpdate(true, new DataViewChangedEventArgs(ViewChangedAction.DataChanged)); } else { this.TableElement.EndUpdate(false); } this.TableElement.Update(GridUINotifyAction.DataChanged); } private void CheckAllCheckBoxInChildRows(GridViewGroupRowInfo row, object state) { List<GridViewRowInfo> list = new List<GridViewRowInfo>(); foreach (GridViewRowInfo rowInfo in row.ChildRows) { list.Add(rowInfo); } foreach (GridViewRowInfo rowInfo in list) { GridViewGroupRowInfo groupInfo = rowInfo as GridViewGroupRowInfo; if (groupInfo != null) { this.CheckAllCheckBoxInChildRows(groupInfo, state); } else { rowInfo.Cells[this.ColumnIndex].Value = state; } } } private List<GridViewRowInfo> GetRowsToIterateOver() { if (this.ViewTemplate != null && this.ViewTemplate.IsSelfReference) { PrintGridTraverser traverser = new PrintGridTraverser(this.ViewInfo); List<GridViewRowInfo> result = new List<GridViewRowInfo>(); while (traverser.MoveNext()) { if (traverser.Current is GridViewDataRowInfo) { result.Add(traverser.Current); } } return result; } return new List<GridViewRowInfo>(this.ViewInfo.Rows); } } }
Currently the time for opening the popup for a column with 100 000 unique items including blank items is about 8s, this can be optimized. How to reproduce: public partial class Form1 : Form { public Form1() { InitializeComponent(); this.radGridView1.EnableFiltering = true; this.radGridView1.ShowHeaderCellButtons = true; this.radGridView1.DataSource = this.GetData(); this.radGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill; this.radGridView1.MouseDown += RadGridView1_MouseDown; this.radGridView1.FilterPopupInitialized += RadGridView1_FilterPopupInitialized; } Stopwatch sw = new Stopwatch(); private void RadGridView1_MouseDown(object sender, MouseEventArgs e) { GridFilterButtonElement btn = this.radGridView1.ElementTree.GetElementAtPoint(e.Location) as GridFilterButtonElement; if (btn != null) { sw.Start(); } } private void RadGridView1_FilterPopupInitialized(object sender, FilterPopupInitializedEventArgs e) { ((RadListFilterPopup)e.FilterPopup).PopupOpened += Form1_PopupOpened; } private void Form1_PopupOpened(object sender, EventArgs args) { sw.Stop(); Console.WriteLine("Total: " + sw.ElapsedMilliseconds); } 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 < 100000; i++) { dt.Rows.Add(i, "Name " + i, DateTime.Now.AddDays(i), i % 2 == 0); } dt.Rows.Add(1, null, DateTime.Now.AddDays(1), false); return dt; } }
How to reproduce: check also the attached video public partial class Form1 : Form { public Form1() { InitializeComponent(); this.radGridView1.DataSource = this.GetData(); this.radGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill; GroupDescriptor descriptor = new GroupDescriptor(); descriptor.GroupNames.Add("Name", ListSortDirection.Ascending); this.radGridView1.GroupDescriptors.Add(descriptor); } private DataTable GetData() { DataTable dt = new DataTable(); dt.Columns.Add("Name", typeof(string)); dt.Columns.Add("Age", typeof(int)); dt.Columns.Add("Date", typeof(DateTime)); dt.Columns.Add("Bool", typeof(bool)); for (int i = 0; i < 3; i++) { for (int j = 0; j < 60; j++) { dt.Rows.Add("Name " + i, i, DateTime.Now.AddDays(i), i % 2 == 0); } } return dt; } private void radButton1_Click(object sender, EventArgs e) { GridPrintStyle style = new GridPrintStyle(); style.FitWidthMode = PrintFitWidthMode.FitPageWidth; this.radGridView1.PrintStyle = style; RadPrintDocument doc = new RadPrintDocument(); doc.HeaderHeight = 30; doc.HeaderFont = new Font("Arial", 12); doc.LeftHeader = "Left Header"; doc.MiddleHeader = "Middle header"; doc.RightHeader = "Right header"; doc.AssociatedObject = this.radGridView1; RadPrintPreviewDialog dialog = new RadPrintPreviewDialog(doc); dialog.Show(); } } Workaround: create a custom GridPrintStyle class public class MyGridPrintStyle : GridPrintStyle { protected override BaseGridPrintRenderer InitializePrintRenderer(RadGridView grid) { BaseGridPrintRenderer rend = base.InitializePrintRenderer(grid); if (rend is TableViewDefinitionPrintRenderer) { return new MyTableViewDefinitionPrintRenderer(grid); } return rend; } } public class MyTableViewDefinitionPrintRenderer : TableViewDefinitionPrintRenderer { public MyTableViewDefinitionPrintRenderer(RadGridView grid) : base(grid) { } protected override void PrintRowWideCell(GridViewRowInfo row, TableViewRowLayout rowLayout, GridPrintSettings settings, int currentX, int currentY, Graphics graphics) { int groupLevel = row.Group != null ? row.Group.Level + 1 : 0; int indentLevel = row.HierarchyLevel + 1 - groupLevel; Size cellSize = this.GetRowSize(row, rowLayout); int cellX = currentX + indentLevel * settings.HierarchyIndent + rowLayout.Owner.CellSpacing; Rectangle cellRect = new Rectangle(cellX, currentY, cellSize.Width - indentLevel * settings.HierarchyIndent, cellSize.Height); CellPrintElement printCell = new CellPrintElement(); if (row is GridViewGroupRowInfo) { if (this.PrintPages.Count > 0 && !settings.PrintHierarchy) { cellRect.Width -= this.PrintPages[this.CurrentPrintPage].Count - 1; } printCell = this.CreateGroupCellPrintElement(row as GridViewGroupRowInfo); if (printCell.Font != settings.GroupRowFont) { if (settings.GroupRowFont != null) { printCell.Font = settings.GroupRowFont; } else { settings.GroupRowFont = printCell.Font; } } } printCell.TextPadding = this.GridView.PrintStyle.CellPadding; printCell.RightToLeft = this.GridView.RightToLeft == RightToLeft.Yes; PrintCellFormattingEventArgs formattEventArgs = new PrintCellFormattingEventArgs(row, null, printCell); this.OnPrintCellFormatting(formattEventArgs); PrintCellPaintEventArgs paintEventArgs = new PrintCellPaintEventArgs(graphics, row, null, cellRect); this.OnPrintCellPaint(paintEventArgs); formattEventArgs.PrintCell.Paint(graphics, paintEventArgs.CellRect); } }