To reproduce: run the attached sample project and press the "stream export" button.
Workaround: use the GridViewSpreadExport https://docs.telerik.com/devtools/winforms/gridview/exporting-data/spread-export
Dim spreadExporter As GridViewSpreadExport = New GridViewSpreadExport(RadGridView1)
Dim exportRenderer As New SpreadExportRenderer()
Dim fileName As String = "..\..\Export" & DateTime.Now.ToLongTimeString().Replace(":", "_") + ".xlsx"
spreadExporter.RunExport(fileName, exportRenderer)
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;
}
}