To reproduce:
1. Bind RadGridView to a collection of business objects where one of the properties is Nullable<DateTime>.
2. Leave one of the items with an empty date (null value).
3. Copy the entire row and try to paste in one of the grid rows. The FormatException is thrown.
Sub New()
InitializeComponent()
Dim items As New List(Of Item)
items.Add(New Item(1, DateTime.Now.AddDays(2), "Item1"))
items.Add(New Item(2, Nothing, "Item2"))
items.Add(New Item(3, DateTime.Now.AddDays(4), "Item3"))
items.Add(New Item(4, DateTime.Now.AddDays(5), "Item4"))
Me.RadGridView1.DataSource = items
Me.RadGridView1.AutoSizeColumnsMode = Telerik.WinControls.UI.GridViewAutoSizeColumnsMode.Fill
End Sub
Public Class Item
Private _id As Integer
Private _createdOn As Nullable(Of DateTime)
Private _title As String
Public Sub New(id As Integer, createdOn As Nullable(Of DateTime), title As String)
Me._id = id
Me._createdOn = createdOn
Me._title = title
End Sub
Public Property Id() As Integer
Get
Return _id
End Get
Set(ByVal value As Integer)
_id = value
End Set
End Property
Public Property CreatedOn() As Nullable(Of DateTime)
Get
Return _createdOn
End Get
Set(ByVal value As Nullable(Of DateTime))
_createdOn = value
End Set
End Property
Public Property Title() As String
Get
Return _title
End Get
Set(ByVal value As String)
_title = value
End Set
End Property
End Class
Workaround: use a TypeConverter
Sub New()
InitializeComponent()
Dim items As New List(Of Item)
items.Add(New Item(1, DateTime.Now.AddDays(2), "Item1"))
items.Add(New Item(2, Nothing, "Item2"))
items.Add(New Item(3, DateTime.Now.AddDays(4), "Item3"))
items.Add(New Item(4, DateTime.Now.AddDays(5), "Item4"))
Me.RadGridView1.DataSource = items
Me.RadGridView1.AutoSizeColumnsMode = Telerik.WinControls.UI.GridViewAutoSizeColumnsMode.Fill
DirectCast(Me.RadGridView1.Columns(1), GridViewDateTimeColumn).DataTypeConverter=New NullableDateTimeConverter()
End Sub
Public Class NullableDateTimeConverter
Inherits TypeConverter
Public Overrides Function CanConvertFrom(ByVal context As ITypeDescriptorContext, ByVal sourceType As Type) As Boolean
Return sourceType.Equals(GetType(String))
End Function
Public Overrides Function ConvertFrom(ByVal context As ITypeDescriptorContext, ByVal culture As CultureInfo, ByVal value As Object) As Object
Dim parsedDate As DateTime
If DateTime.TryParse(value.ToString(), parsedDate) Then
Return parsedDate
End If
Return Nothing
End Function
End Class
Public Class Item
Private _id As Integer
Private _createdOn As Nullable(Of DateTime)
Private _title As String
Public Sub New(id As Integer, createdOn As Nullable(Of DateTime), title As String)
Me._id = id
Me._createdOn = createdOn
Me._title = title
End Sub
Public Property Id() As Integer
Get
Return _id
End Get
Set(ByVal value As Integer)
_id = value
End Set
End Property
Public Property CreatedOn() As Nullable(Of DateTime)
Get
Return _createdOn
End Get
Set(ByVal value As Nullable(Of DateTime))
_createdOn = value
End Set
End Property
Public Property Title() As String
Get
Return _title
End Get
Set(ByVal value As String)
_title = value
End Set
End Property
End Class
To reproduce: use DataAccess to connect to Northwind.Customer table:
public Form1()
{
InitializeComponent();
EntitiesModel1 context = new EntitiesModel1();
var query = (from c in context.Customers where c.CustomerID.Contains("f") select c).ToList();
this.radGridView1.DataSource = query;
SortDescriptor descriptor = new SortDescriptor();
descriptor.PropertyName = "CustomerID";
descriptor.Direction = ListSortDirection.Ascending;
this.radGridView1.MasterTemplate.SortDescriptors.Add(descriptor);
this.radGridView1.CurrentRow = this.radGridView1.Rows.Last();
}
Run the project and press the Delete key several times.
Workaround: use BindingSource as RadGridView.DataSource:
BindingSource bs = new BindingSource();
bs.DataSource = query;
this.radGridView1.DataSource = bs;
To reproduce:
Sub New()
InitializeComponent()
Dim dt As New DataTable()
dt.Columns.Add("Name", GetType(String))
dt.Columns.Add("Price", GetType(Decimal))
dt.Columns.Add("Id", GetType(Integer))
dt.Columns.Add("ActivatedOn", GetType(DateTime))
For i As Integer = 0 To 4
dt.Rows.Add("Item" & i, i * 0.25, i, DateTime.Now.AddHours(i))
Next
Me.RadGridView1.DataSource = dt
Me.RadGridView1.Columns("Id").[ReadOnly] = True
Me.RadGridView1.AutoSizeColumnsMode = Telerik.WinControls.UI.GridViewAutoSizeColumnsMode.Fill
AddHandler Me.RadGridView1.DefaultValuesNeeded, AddressOf radGridView1_DefaultValuesNeeded
Me.RadGridView1.NewRowEnterKeyMode = RadGridViewNewRowEnterKeyMode.EnterMovesToLastAddedRow
End Sub
Private Sub radGridView1_DefaultValuesNeeded(sender As Object, e As GridViewRowEventArgs)
e.Row.Cells("Id").Value = Me.radGridView1.Rows.Count
e.Row.Cells("ActivatedOn").Value = DateTime.Now
End Sub
Select the read-only cell inside the new row and press Enter. You will notice that two duplicated rows are added.
Workaround: handle the RadGridView.PreviewKeyDown event and change the current column to one that is not read-only
AddHandler Me.RadGridView1.PreviewKeyDown, AddressOf GridPreviewKeyDown
Private Sub GridPreviewKeyDown(sender As Object, e As PreviewKeyDownEventArgs)
If e.KeyCode = Keys.Enter Then
Me.RadGridView1.CurrentColumn = Me.RadGridView1.Columns(0)
Me.RadGridView1.BeginEdit()
End If
End Sub
Example : if we have 5 rows in the grid and if we copy 10 rows from excel and paste in first row, only first 5 records gets pasted and remaining 5 would be ignored.
To reproduce:
public Form1()
{
InitializeComponent();
List<Item> items = new List<Item>();
for (int i = 1; i <= 10; i++)
{
items.Add(new Item(i, "Product" + i, 0.25m * i, i));
}
this.radGridView1.DataSource = items;
GridViewDecimalColumn col = new GridViewDecimalColumn("Calculated Column");
col.Expression = "Quantity*Price/100";
this.radGridView1.Columns.Add(col);
this.radGridView1.AutoSizeColumnsMode = Telerik.WinControls.UI.GridViewAutoSizeColumnsMode.Fill;
}
public class Item
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
public int Quantity { get; set; }
public Item(int id, string name, decimal price, int quantity)
{
this.Id = id;
this.Name = name;
this.Price = price;
this.Quantity = quantity;
}
}
MemoryStream s = new MemoryStream();
private void radButton1_Click(object sender, EventArgs e)
{
s = new MemoryStream();
this.radGridView1.SaveLayout(s);
}
private void radButton2_Click(object sender, EventArgs e)
{
this.radGridView1.LoadLayout(s);
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
s.Close();
}
Workaround: before loading the layout, clear the columns
How to reproduce:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.radGridView1.DataSource = this.GetData();
this.Load += Form1_Load;
}
private void Form1_Load(object sender, EventArgs e)
{
this.radGridView1.SynchronizeCurrentRowInSplitMode = true;
this.radGridView1.SplitMode = Telerik.WinControls.UI.RadGridViewSplitMode.Vertical;
}
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 < 100; i++)
{
dt.Rows.Add("Name " + i, i, DateTime.Now.AddMinutes(i), i % 2 == 0 ? true : false);
}
return dt;
}
}
Workaround:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.radGridView1.DataSource = this.GetData();
this.radGridView1.ViewDefinition = new SplitViewDefintion();
this.Load += Form1_Load;
}
private void Form1_Load(object sender, EventArgs e)
{
this.radGridView1.SynchronizeCurrentRowInSplitMode = true;
this.radGridView1.SplitMode = Telerik.WinControls.UI.RadGridViewSplitMode.Vertical;
}
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 < 100; i++)
{
dt.Rows.Add("Name " + i, i, DateTime.Now.AddMinutes(i), i % 2 == 0 ? true : false);
}
return dt;
}
}
public class SplitViewDefintion : TableViewDefinition
{
public override IRowView CreateViewUIElement(GridViewInfo viewInfo)
{
return new MyGridTableElement();
}
}
public class MyGridTableElement : GridTableElement
{
protected override RadScrollBarElement CreateScrollBarElement()
{
return new MyRadScrollbarElement();
}
}
public class MyRadScrollbarElement : RadScrollBarElement
{
protected override Type ThemeEffectiveType
{
get
{
return typeof(RadScrollBarElement);
}
}
protected override void OnMouseDown(MouseEventArgs e)
{
if (Cursor.Current == Cursors.SizeWE || Cursor.Current == Cursors.SizeNS)
{
return;
}
base.OnMouseDown(e);
}
}
Currently, in order to display the "Deleter Row" context menu item, you should set both properties, AllowEditRow and AllowDeleteRow, to true. However, if you use the Delete key, it will remove the row if only the AllowDeleteRow property is set to true.
To reproduce:
DataTable dt = new DataTable();
dt.Columns.Add("Id", typeof(int));
dt.Columns.Add("Name", typeof(string));
dt.Rows.Add(1, new string('G', 32001));
this.radGridView1.DataSource = dt;
this.radGridView1.PrintPreview();
Workaround: this.radGridView1.PrintCellFormatting+=radGridView1_PrintCellFormatting;
private void radGridView1_PrintCellFormatting(object sender, PrintCellFormattingEventArgs e)
{
e.PrintCell.Text = e.PrintCell.Text.Substring(0,Math.Min(e.PrintCell.Text.Length, 32000));
}
To reproduce: change the value for a GridCheckBoxCellElement. The editor is not active. However, if you click again over the current cell, the editor will be activated.
Workaround: use a custom row behavior to close the editor:
//register the custom row behavior
BaseGridBehavior gridBehavior = sourceRadGridView.GridBehavior as BaseGridBehavior;
gridBehavior.UnregisterBehavior(typeof(GridViewDataRowInfo));
gridBehavior.RegisterBehavior(typeof(GridViewDataRowInfo), new CustomGridDataRowBehavior());
public class CustomGridDataRowBehavior : GridDataRowBehavior
{
public override bool OnMouseUp(MouseEventArgs e)
{
bool result = base.OnMouseUp(e);
if (this.MasterTemplate.CurrentColumn is GridViewCheckBoxColumn )
{
this.GridViewElement.EndEdit();
}
return result;
}
}
To reproduce: 1. Perform searching in the grid. 2. Group by a random column. 3. Navigating with next/previous buttons do not navigate the results in the displayed order. Workaround: set the EnablePaging property to false.
To reproduce:
public Form1()
{
InitializeComponent();
this.radGridView1.Columns.Add("Col1");
this.radGridView1.Rows.Add("word \u00AD word");
this.radGridView1.Rows.Add("word - word");
}
Workaround: replace "\u00AD" with "-"
private void radGridView1_CellFormatting(object sender, Telerik.WinControls.UI.CellFormattingEventArgs e)
{
e.CellElement.Text = e.CellElement.Text.Replace("\u00AD", "-");
}
To reproduce:
private void Form1_Load(object sender, EventArgs e)
{
this.productsTableAdapter.Fill(this.nwindDataSet.Products);
this.radGridView1.DataSource = this.productsBindingSource;
GridViewSummaryItem summaryItem = new GridViewSummaryItem();
summaryItem.Name = "UnitPrice";
summaryItem.Aggregate = GridAggregateFunction.Count;
GridViewSummaryRowItem summaryRowItem = new GridViewSummaryRowItem();
summaryRowItem.Add(summaryItem);
this.radGridView1.SummaryRowsTop.Add(summaryRowItem);
GroupDescriptor descriptor1 = new GroupDescriptor();
descriptor1.GroupNames.Add("CategoryID", ListSortDirection.Ascending);
this.radGridView1.GroupDescriptors.Add(descriptor1);
GroupDescriptor descriptor11 = new GroupDescriptor();
descriptor11.GroupNames.Add("SupplierID", ListSortDirection.Ascending);
this.radGridView1.GroupDescriptors.Add(descriptor11);
GroupDescriptor descriptor2 = new GroupDescriptor();
descriptor2.GroupNames.Add("QuantityPerUnit", ListSortDirection.Ascending);
descriptor2.GroupNames.Add("UnitsInStock", ListSortDirection.Ascending);
this.radGridView1.GroupDescriptors.Add(descriptor2);
GroupDescriptor descriptor3 = new GroupDescriptor();
descriptor3.GroupNames.Add("UnitsOnOrder", ListSortDirection.Ascending);
descriptor3.GroupNames.Add("ReorderLevel", ListSortDirection.Descending);
this.radGridView1.GroupDescriptors.Add(descriptor3);
GroupDescriptor descriptor4 = new GroupDescriptor();
descriptor4.GroupNames.Add("Discontinued", ListSortDirection.Ascending);
this.radGridView1.GroupDescriptors.Add(descriptor4);
}
private void radButton1_Click(object sender, EventArgs e)
{
GridViewSpreadExport spreadExporter = new GridViewSpreadExport(this.radGridView1);
SpreadExportRenderer exportRenderer = new SpreadExportRenderer();
string filePath = @"..\..\exported" + DateTime.Now.ToShortTimeString().Replace(":", "_") + ".xlsx";
spreadExporter.ExportGroupedColumns = true;
spreadExporter.ExportChildRowsGrouped = true;
spreadExporter.HiddenColumnOption = Telerik.WinControls.UI.Export.HiddenOption.DoNotExport;
spreadExporter.ExportVisualSettings = true;
spreadExporter.SummariesExportOption = Telerik.WinControls.UI.Export.SummariesOption.ExportAll;
spreadExporter.RunExport(filePath, exportRenderer);
Process.Start(filePath);
}
Workaround: set the ExportChildRowsGrouped property to false.
To reproduce:
1. Use the following code:
private void Form1_Load(object sender, EventArgs e)
{
this.customersTableAdapter.Fill(this.nwindDataSet.Customers);
this.radGridView1.DataSource = customersBindingSource;
this.radGridView1.AutoSizeColumnsMode = Telerik.WinControls.UI.GridViewAutoSizeColumnsMode.Fill;
this.radGridView1.CellEndEdit += radGridView1_CellEndEdit;
this.radGridView1.AutoSizeRows = true;
SortDescriptor descriptor = new SortDescriptor();
descriptor.PropertyName = "Country";
descriptor.Direction = ListSortDirection.Ascending;
this.radGridView1.MasterTemplate.SortDescriptors.Add(descriptor);
}
void radGridView1_CellEndEdit(object sender, Telerik.WinControls.UI.GridViewCellEventArgs e)
{
int selectedRowIndex = this.radGridView1.ChildRows.IndexOf(this.radGridView1.CurrentRow);
this.radGridView1.TableElement.ScrollToRow(selectedRowIndex);
}
2. Modify cell value in the sorted column. After the editor value is confirmed by pressing Enter, you scroll to the current column. However, you do not observe the expected behavior.
Workaround: set the AutoSizeRows property to false.
To reproduce: - Remove the new row from the grid. - Start the application and delete all rows. - When the last row is deleted the SelectionChanged does not fire. Workaround: - Use the UserDeletedRow event instead.
Workaround: use a GridPrintStyle and define a HierarchyIndent = 0
private void PrintGrid()
{
GridPrintStyle style = new GridPrintStyle();
style.HierarchyIndent = 0;
this.radGridView1.PrintStyle = style;
this.radGridView1.PrintPreview();
}
To reproduce:
private void RadForm1_Load(object sender, EventArgs e)
{
DataTable dt = new DataTable();
dt.Columns.Add("col1", typeof(bool));
dt.Columns.Add("col2", typeof(bool));
dt.Rows.Add(0, 1);
dt.Rows.Add(0, 1);
dt.Rows.Add(0, 1);
RadGridView1.DataSource = dt;
((Telerik.WinControls.UI.GridViewCheckBoxColumn)RadGridView1.Columns(0)).EnableHeaderCheckBox = true;
((Telerik.WinControls.UI.GridViewCheckBoxColumn)RadGridView1.Columns(1)).EnableHeaderCheckBox = true;
RadGridView1.HeaderCellToggleStateChanged += radGridView1_HeaderCellToggleStateChanged;
}
- Start the application and click in the second row in the first column.
Workaraound:
public class MyGridCheckBoxHeaderCellElement : GridCheckBoxHeaderCellElement
{
public MyGridCheckBoxHeaderCellElement(GridViewDataColumn col, GridRowElement row)
: base(col, row)
{ }
protected override void SetCheckBoxState(ToggleState state)
{
if (this.ColumnInfo.Name != this.GridViewElement.CurrentCell.ColumnInfo.Name)
{
return;
}
base.SetCheckBoxState(state);
}
}
To reproduce:
1. Perform searching in the grid.
2. Sort by a random column.
3. Navigating with next/previous buttons do not navigate the results in the displayed order. Please refer to the attached gif file.
Workaround: clear the cache of the search row after sorting is changed:
private void radGridView1_SortChanged(object sender, Telerik.WinControls.UI.GridViewCollectionChangedEventArgs e)
{
string searchCriteria = this.radGridView1.MasterView.TableSearchRow.SearchCriteria;
FieldInfo fi = typeof(GridViewSearchRowInfo).GetField("cache",
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
Hashtable cache = fi.GetValue(this.radGridView1.MasterView.TableSearchRow) as Hashtable;
cache.Clear();
this.radGridView1.MasterView.TableSearchRow.Search(searchCriteria);
}