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.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; }
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); } }
How to reproduce: check the attached video public partial class Form1 : Form { public Form1() { InitializeComponent(); this.radGridView1.DataSource = this.GetData(1000); this.radGridView1.AutoExpandGroups = true; this.radGridView1.EnableFiltering = true; this.radGridView1.EnablePaging = true; this.radGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill; } private DataTable GetData(int count) { 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 < count; i++) { dt.Rows.Add(i,"Name " + i, DateTime.Now.AddDays(i), i % 2 == 0 ? true : false); } return dt; } } Workaround: cancel the PageChanging event public partial class Form1 : Form { public Form1() { InitializeComponent(); this.radGridView1.DataSource = this.GetData(1000); this.radGridView1.AutoExpandGroups = true; this.radGridView1.EnableFiltering = true; this.radGridView1.EnablePaging = true; this.radGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill; timer = new Timer(); timer.Interval = 100; timer.Tick += (sender, e) => { timer.Stop(); this.shouldCancel = false; }; this.radGridView1.PageChanging += RadGridView1_PageChanging; this.radGridView1.CurrentRowChanged += RadGridView1_CurrentRowChanged; } private void RadGridView1_CurrentRowChanged(object sender, CurrentRowChangedEventArgs e) { this.shouldCancel = this.ShouldCancelPageChange(e.CurrentRow); timer.Start(); } Timer timer; bool shouldCancel = false; private bool ShouldCancelPageChange(GridViewRowInfo rowInfo) { if (this.radGridView1.TableElement.MasterTemplate != null && this.radGridView1.TableElement.MasterTemplate.EnablePaging) { int pageIndex = this.radGridView1.TableElement.ViewTemplate.DataView.GetItemPage(rowInfo); if (pageIndex == this.radGridView1.TableElement.MasterTemplate.PageIndex) { return true; } } return false; } private void RadGridView1_PageChanging(object sender, Telerik.WinControls.PageChangingEventArgs e) { e.Cancel = this.shouldCancel; } private DataTable GetData(int count) { 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 < count; i++) { dt.Rows.Add(i,"Name " + i, DateTime.Now.AddDays(i), i % 2 == 0 ? true : false); } return dt; } }
To reproduce: please refer to the attached gif file and sample project. Workaround: private void radGridView1_CellEndEdit(object sender, GridViewCellEventArgs e) { RadDropDownListEditor editor = e.ActiveEditor as RadDropDownListEditor; if (editor!=null) { RadDropDownListEditorElement el = editor.EditorElement as RadDropDownListEditorElement; el.AutoCompleteSuggest.DropDownList.ClosePopup(); } }
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 1000 dt.Rows.Add(index, "Item" & index) Next Me.RadGridView1.DataSource = dt End Sub Private Sub RadButton1_Click(sender As Object, e As EventArgs) Handles RadButton1.Click Dim pdfFile As String = "..\..\exportedFile.pdf" Dim pdfExporter As New GridViewPdfExport(Me.RadGridView1) pdfExporter.ShowHeaderAndFooter = True pdfExporter.FitToPageWidth = True AddHandler pdfExporter.PdfExported, AddressOf pdfExporter_PdfExported Dim renderer As New PdfExportRenderer() pdfExporter.RunExport(pdfFile, renderer) Process.Start(pdfFile) End Sub Private Sub pdfExporter_PdfExported(sender As Object, e As System.EventArgs) Dim pdfFile As String = "..\..\exportedFile.pdf" Dim document As RadFixedDocument Dim provider As Telerik.Windows.Documents.Fixed.FormatProviders.Pdf.PdfFormatProvider = New Telerik.Windows.Documents.Fixed.FormatProviders.Pdf.PdfFormatProvider() Using stream As Stream = File.OpenRead(pdfFile) document = provider.Import(stream) '<==== Error Found For Each page As RadFixedPage In document.Pages Dim editor As FixedContentEditor = New FixedContentEditor(page) editor.Position.Translate(page.Size.Width / 2, page.Size.Height - 50) Dim pageNum As Integer = document.Pages.IndexOf(page) + 1 editor.DrawText(pageNum + " of " + document.Pages.Count) Next End Using Using output As Stream = File.OpenWrite(pdfFile) provider.Export(document, output) '<==== Error Found End Using Process.Start(pdfFile) End Sub Workaround: use the PdfExportRenderer.PdfExporting event where you have access to the document and you can make any customizations to it: Dim pdfFile As String = "..\..\exportedFile.pdf" Dim pdfExporter As New GridViewPdfExport(Me.RadGridView1) pdfExporter.ShowHeaderAndFooter = True pdfExporter.FitToPageWidth = True Dim renderer As New PdfExportRenderer() AddHandler renderer.PdfExporting, AddressOf PdfExporting pdfExporter.RunExport(pdfFile, renderer) Private Sub PdfExporting(sender As Object, e As PdfExportingEventArgs) Dim document As RadFixedDocument = e.Document Dim provider As Telerik.Windows.Documents.Fixed.FormatProviders.Pdf.PdfFormatProvider = New Telerik.Windows.Documents.Fixed.FormatProviders.Pdf.PdfFormatProvider() For Each page As RadFixedPage In document.Pages Dim editor As FixedContentEditor = New FixedContentEditor(page) editor.Position.Translate(page.Size.Width / 2, page.Size.Height - 50) Dim pageNum As Integer = document.Pages.IndexOf(page) + 1 editor.DrawText(pageNum & " of " & document.Pages.Count) Next End Sub
Use attached to reproduce. Workaround: class MyGridCheckBoxHeaderCellElement : GridCheckBoxHeaderCellElement { public MyGridCheckBoxHeaderCellElement(GridRowElement row, GridViewColumn col) : base(col, row) { } bool suspenUpdate = false; protected override void checkbox_ToggleStateChanged(object sender, StateChangedEventArgs args) { suspenUpdate = true; base.checkbox_ToggleStateChanged(sender, args); suspenUpdate = false; } protected override void SetCheckBoxState() { if (!suspenUpdate) { base.SetCheckBoxState(); } } } private void RadGridView1_CreateCell(object sender, GridViewCreateCellEventArgs e) { if (e.Column != null&& e.CellType == typeof(GridCheckBoxHeaderCellElement)) { e.CellElement = new MyGridCheckBoxHeaderCellElement(e.Row, e.Column); } }
In self-reference if you bind the grid to a record having is ParentId the same as its Id, the grid will try to create a row which is parented by itself. This is not valid input data and we should throw a proper exception, otherwise the application will freeze. How to reproduce: public partial class Form2 : Form { private BindingList<DataObject> data; public Form2() { InitializeComponent(); this.radGridView1.AutoGenerateHierarchy = true; this.data = new BindingList<DataObject>(); int count = 10; for (int i = 0; i < count; i++) { DataObject p = new DataObject(); p.Id = i; p.Name = "Parent " + i; this.data.Add(p); for (int j = 0; j < count; j++) { DataObject c = new DataObject(); c.Id = count + j + i * count; c.Name = "Child " + i; c.ParentId = i; this.data.Add(c); } } this.radButton1.Click += RadButton1_Click; } private void RadButton1_Click(object sender, EventArgs e) { if (this.radGridView1.Relations.Count > 0) { this.radGridView1.Relations.Clear(); } this.radGridView1.DataSource = this.data; this.radGridView1.Relations.AddSelfReference(this.radGridView1.MasterTemplate, "Id", "ParentId"); } } public class DataObject { public int Id { get; set; } public string Name { get; set; } public int ParentId { get; set; } } Workaround: set the ParentId of the parent records int count = 10; for (int i = 0; i < count; i++) { DataObject p = new DataObject(); p.Id = i; p.Name = "Parent " + i; p.ParentId = -1; this.data.Add(p); for (int j = 0; j < count; j++) { DataObject c = new DataObject(); c.Id = count + j + i * count; c.Name = "Child " + i; c.ParentId = i; this.data.Add(c); } }
How to reproduce: check the code snippet below and the attached video. public partial class Form1 : Form { public Form1() { InitializeComponent(); this.SetupGrid(); this.radGridView1.Dock = DockStyle.Fill; this.radGridView1.UseScrollbarsInHierarchy = true; } private void SetupGrid() { BindingList<Teacher> teachers = new BindingList<Teacher>(); BindingList<Student> students = new BindingList<Student>(); for (int i = 1; i <= 2; i++) { teachers.Add(new Teacher { TeacherId = i, TeacherFirstName = "FirstName " + i, TeacherLastName = "FirstName " + i, }); for (int j = 1; j <= 3; j++) { students.Add(new Student { SudentId = j, TeacherId = i, SudentFirstName = "Student " + j, SudentLastName = "LastName " + j, }); } } this.radGridView1.Templates.Clear(); this.radGridView1.DataSource = null; this.radGridView1.DataSource = teachers; this.radGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill; GridViewTemplate template = new GridViewTemplate(); template.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill; template.DataSource = students; this.radGridView1.MasterTemplate.Templates.Add(template); GridViewRelation relation = new GridViewRelation(radGridView1.MasterTemplate); relation.ChildTemplate = template; relation.RelationName = "TeacherStudents"; relation.ParentColumnNames.Add("TeacherId"); relation.ChildColumnNames.Add("TeacherId"); this.radGridView1.Relations.Add(relation); this.radGridView1.ChildViewExpanded += RadGridView1_ChildViewExpanded1; } private void RadGridView1_ChildViewExpanded1(object sender, ChildViewExpandedEventArgs e) { } private void radButton1_Click(object sender, EventArgs e) { this.radGridView1.SaveLayout("..\\..\\save.xml"); } private void radButton2_Click(object sender, EventArgs e) { this.radGridView1.LoadLayout("..\\..\\save.xml"); } } public class Teacher { public int TeacherId { get; set; } public string TeacherFirstName { get; set; } public string TeacherLastName { get; set; } } public class Student { public int SudentId { get; set; } public int TeacherId { get; set; } public string SudentFirstName { get; set; } public string SudentLastName { get; set; } } Workaround: prevent the child templates from serializing public class MyRadGridView : RadGridView { public override string ThemeClassName { get { return typeof(RadGridView).FullName; } } public override void SaveLayout(string fileName) { MyGridViewLayoutSerializer ser = new MyGridViewLayoutSerializer(this.XmlSerializationInfo); using (XmlTextWriter writer = new XmlTextWriter(fileName, Encoding.UTF8)) { writer.Formatting = Formatting.Indented; writer.WriteStartElement("RadGridView"); ser.WriteObjectElement(writer, this); } } } public class MyGridViewLayoutSerializer : GridViewLayoutSerializer { public MyGridViewLayoutSerializer(ComponentXmlSerializationInfo componentSerializationInfo) : base(componentSerializationInfo) { } protected override bool ShouldSerializeValue(object component, PropertyDescriptor property, PropertySerializationMetadata overwriteMetadata) { if (property.Name == "Templates") { return false; } return base.ShouldSerializeValue(component, property, overwriteMetadata); } }
How to reproduce: public partial class Form1 : Form { public Form1() { InitializeComponent(); this.radGridView1.DataSource = this.GetData(); this.radGridView1.EditorRequired += RadGridView1_EditorRequired; } private void RadGridView1_EditorRequired(object sender, EditorRequiredEventArgs e) { if (this.radGridView1.CurrentColumn.Index == 0) { e.Editor = new RadTimePickerElement(); } } private DataTable GetData() { DataTable dt = new DataTable(); dt.Columns.Add("Date", typeof(DateTime)); for (int i = 0; i < 20; i++) { DataRow r = dt.NewRow(); dt.Rows.Add(r); } return dt; } } Workaround: the scenario is not completely valid as when handling the EditorRequiredEvent one should use the GridTimePickerEditor 1. Use the column`s EditorType property: ((GridViewDateTimeColumn)this.radGridView1.Columns["Date"]).EditorType = GridViewDateTimeEditorType.TimePicker 2. Alternatively, handle the event this way: private void RadGridView1_EditorRequired(object sender, EditorRequiredEventArgs e) { if (this.radGridView1.CurrentColumn.Index == 0) { e.Editor = new GridTimePickerEditor(); } }
Use attached to reproduce. - Check the filter box - Uncheck the header checkbox. - The cells are still visible and you cannot click on the data check boxes.
Use attached to reproduce. Workaround: class MyDataCellElement : GridDataCellElement { public MyDataCellElement(GridViewColumn col, GridRowElement row) : base(col,row) { } protected override List<CharacterRange> GetSearchHighlightRanges() { // return base.GetSearchHighlightRanges(); List<CharacterRange> ranges = new List<CharacterRange>(); if (this.ColumnInfo == null || !this.RowInfo.SearchCache.Contains(this.ColumnInfo)) { return ranges; } string criteria = this.RowInfo.SearchCache[this.ColumnInfo] as string; int index = -1; CompareOptions options; if (this.MasterTemplate.MasterViewInfo.TableSearchRow.CaseSensitive) { options = CompareOptions.Ordinal; } else { options = this.MasterTemplate.MasterViewInfo.TableSearchRow.CompareOptions; } do { if (index + 1 >= this.Text.Length) { break; } index = this.MasterTemplate.MasterViewInfo.TableSearchRow.Culture.CompareInfo.IndexOf(this.Text, criteria, index + 1, options); if (index >= 0) { var str = this.Text.Substring(index, criteria.Length); int symbolCount = 0; foreach (char ch in str) { if (!Char.IsLetterOrDigit(ch)) { symbolCount++; } } ranges.Add(new CharacterRange(index, criteria.Length + symbolCount)); } } while (index >= 0 && ranges.Count < 32); return ranges; } } private void MasterTemplate_CreateCell(object sender, GridViewCreateCellEventArgs e) { if (e.CellType == typeof(GridDataCellElement)) { e.CellElement = new MyDataCellElement(e.Column, e.Row); } }
To reproduce: run the attached sample project and click the new row. Workaround: don't call the Begin/EndUpdate methods in the CurrentRowChanged event.
How to reproduce: check the attached project Workaround: create a custom RadListFilterPopup public class MyRadListFilterPopup : RadListFilterPopup { public MyRadListFilterPopup(GridViewDataColumn dataColumn, bool groupedDateValues) : base(dataColumn, groupedDateValues) { } protected override void OnButtonOkClick(EventArgs e) { FilterOperator filterOperator = FilterOperator.IsEqualTo; IRadListFilterElement listFilterElement = (IRadListFilterElement)typeof(RadListFilterPopup).GetField("listFilterElement", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(this); RadListFilterDistinctValuesTable selectedValues = listFilterElement.SelectedValues; switch (listFilterElement.SelectedMode) { case ListFilterSelectedMode.All: filterOperator = FilterOperator.None; break; case ListFilterSelectedMode.Null: filterOperator = FilterOperator.IsNull; break; case ListFilterSelectedMode.NotNull: filterOperator = FilterOperator.IsNotNull; break; } if (filterOperator != FilterOperator.IsEqualTo) { SetFilterOperator(filterOperator); this.ClosePopup(RadPopupCloseReason.CloseCalled); } else { CompositeFilterDescriptor compositeFilterDescriptor = new CompositeFilterDescriptor(); compositeFilterDescriptor.PropertyName = this.DataColumn.Name; RadListFilterDistinctValuesTable distinctValues = this.GetDistinctValuesTable(); string blanksKey = RadGridLocalizationProvider.CurrentProvider.GetLocalizedString(RadGridStringId.FilterMenuBlanks); bool blanks = selectedValues.Contains(blanksKey); if (selectedValues.Count > distinctValues.Count / 2 && !blanks) { compositeFilterDescriptor.LogicalOperator = FilterLogicalOperator.And; foreach (DictionaryEntry entry in distinctValues) { string key = (string)entry.Key; if (string.IsNullOrEmpty(key)) { key = blanksKey; } if (!selectedValues.Contains(key)) { foreach (object value in (ArrayList)entry.Value) { FilterDescriptor descriptor; if (value == DBNull.Value) { descriptor = new FilterDescriptor(this.DataColumn.Name, FilterOperator.IsNotEqualTo, null); } else if (this.DataColumn is GridViewDateTimeColumn || this.DataColumn.DataType == typeof(DateTime) || this.DataColumn.DataType == typeof(DateTime?)) { descriptor = new DateFilterDescriptor(this.DataColumn.Name, FilterOperator.IsNotEqualTo, (DateTime?)value, false); } else { descriptor = new FilterDescriptor(this.DataColumn.Name, FilterOperator.IsNotEqualTo, value); } compositeFilterDescriptor.FilterDescriptors.Add(descriptor); } } } } else { compositeFilterDescriptor.LogicalOperator = FilterLogicalOperator.Or; foreach (DictionaryEntry entry in selectedValues) { foreach (object value in (ArrayList)entry.Value) { FilterDescriptor descriptor; if (value == DBNull.Value) { descriptor = new FilterDescriptor(this.DataColumn.Name, FilterOperator.IsNotEqualTo, null); } else if (this.DataColumn is GridViewDateTimeColumn || this.DataColumn.DataType == typeof(DateTime) || this.DataColumn.DataType == typeof(DateTime?)) { descriptor = new DateFilterDescriptor(this.DataColumn.Name, FilterOperator.IsEqualTo, (DateTime?)value, false); } else { descriptor = new FilterDescriptor(this.DataColumn.Name, FilterOperator.IsEqualTo, value); } compositeFilterDescriptor.FilterDescriptors.Add(descriptor); } } } this.FilterDescriptor = compositeFilterDescriptor; OnFilterConfirmed(); } } }
To reproduce: 1. Add a GridViewCheckBoxColumn with EnableHeaderCheckBox property set to true. 2. Use the TypeConverter demonstrated in the following help article: http://docs.telerik.com/devtools/winforms/gridview/columns/converting-data-types When you run the application and try to toggle the check box in the header cell, a FormatException occurs. Workaround: modify the TypeConverter: public class ToggleStateConverter : TypeConverter { public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { return destinationType == typeof(ToggleState); } public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { char charValue = (char)value; switch (charValue) { case 'Y': return ToggleState.On; case 'N': return ToggleState.Off; case 'M': return ToggleState.Indeterminate; } return base.ConvertTo(context, culture, value, destinationType); } public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) { return sourceType == typeof(ToggleState) || sourceType == typeof(bool); } public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { ToggleState state; bool boolValue; if (value is ToggleState) { state = (ToggleState)value ; switch (state) { case ToggleState.On: return 'Y'; case ToggleState.Off: return 'N'; case ToggleState.Indeterminate: return 'M'; } } else if (value is bool) { boolValue = (bool)value; switch (boolValue) { case true: return 'Y'; case false: return 'N'; default: return 'M'; } } return base.ConvertFrom(context, culture, value); } }
Currently, DisplayFormatType.GeneralDate, DisplayFormatType.ShortDate, DisplayFormatType.MediumDate all return culture's DateTimeFormat.ShortDatePattern. Workaround: GridViewDateTimeColumn columnDateTime = this.radGridView1.Columns["Date"] as GridViewDateTimeColumn; columnDateTime.ExcelExportType = DisplayFormatType.Custom; columnDateTime.ExcelExportFormatString = "dd/MM/yyyy hh:mm:ss";
To reproduce: bind the grid to a DataTable where one of the columns doesn't allow null values. Try to add a new record by using the new row in the grid. Even though you specify default values in the DefaultValuesNeeded event, the error still occurs. Please refer to the attached sample project and gif file. Workaround: handle the RadGridView.DataError event: private void RadGridView1_DataError(object sender, Telerik.WinControls.UI.GridViewDataErrorEventArgs e) { if (e.Exception.ToString().Contains("does not allow nulls")) { e.Cancel = true; } }