To reproduce : public partial class RadForm1 : Telerik.WinControls.UI.RadForm { public RadForm1() { InitializeComponent(); radGridView1.DataSource = GetTable(); } private void radButton1_Click(object sender, EventArgs e) { var exporter = new GridViewPdfExport(radGridView1); exporter.FileExtension = "pdf"; exporter.ShowHeaderAndFooter = true; exporter.LeftFooter = GridViewPdfExport.DatePrintedString; exporter.FitToPageWidth = true; exporter.PageMargins = new Padding(20, 15, 10, 10); exporter.RunExport(@"C:\Users\dkaramfi\Desktop\test123.pdf", new PdfExportRenderer()); } 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("Name1", typeof(string)); table.Columns.Add("Name2", typeof(string)); table.Columns.Add("Name3", typeof(string)); table.Columns.Add("Name4", typeof(string)); table.Rows.Add(50, "Enebrel", "Sam", "Sam1", "Sam2", "Sam4", "Sam4"); table.Rows.Add(25, "Indocin", "David"); table.Rows.Add(50, "Enebrel", "Sam"); table.Rows.Add(10, "Hydralazine", "Christoff"); table.Rows.Add(21, "Combivent", "Janet"); table.Rows.Add(100, "Dilantin", "Melanie"); return table; } } Workaround: Leave the default margins.
To reproduce: Sub New() InitializeComponent() ThemeResolutionService.ApplicationThemeName = "Breeze" Dim dt As New DataTable dt.Columns.Add("Id", GetType(Integer)) dt.Columns.Add("ParentId", GetType(Integer)) dt.Columns.Add("Name", GetType(String)) For index = 1 To 5 dt.Rows.Add(index, 0, "Parent" & index) Next Dim rand As New Random For index = 6 To 25 dt.Rows.Add(index, rand.Next(1, 6), "Parent" & index) Next Me.RadGridView1.Relations.AddSelfReference(Me.RadGridView1.MasterTemplate, "Id", "ParentId") Me.RadGridView1.DataSource = dt Me.RadGridView1.AutoSizeColumnsMode = Telerik.WinControls.UI.GridViewAutoSizeColumnsMode.Fill Me.RadGridView1.AutoSizeRows = True End Sub
To reproduce: private void Form1_Load(object sender, EventArgs e) { this.productsTableAdapter.Fill(this.nwindDataSet.Products); this.categoriesTableAdapter.Fill(this.nwindDataSet.Categories); this.radGridView1.DataSource = this.productsBindingSource; GridViewMultiComboBoxColumn col = new GridViewMultiComboBoxColumn(); col.DataSource = this.categoriesBindingSource; col.MinWidth = 200; col.DisplayMember = "CategoryName"; col.ValueMember = "CategoryID"; this.radGridView1.Columns.Add(col); this.radGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill; this.radGridView1.CellValueChanged += radGridView1_CellValueChanged; } private void radGridView1_CellValueChanged(object sender, GridViewCellEventArgs e) { RadMessageBox.Show("CellValueChanged. Value >> " + e.Value.ToString()); }
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) RadGridView1.AutoGenerateHierarchy = True RadGridView1.DataSource = Me.NwindDataSet RadGridView1.DataMember = "Categories" Me.RadGridView1.MasterTemplate.AutoSizeColumnsMode = Telerik.WinControls.UI.GridViewAutoSizeColumnsMode.Fill Me.RadGridView1.MasterTemplate.Templates(0).AutoSizeColumnsMode = Telerik.WinControls.UI.GridViewAutoSizeColumnsMode.Fill Me.RadGridView1.UseScrollbarsInHierarchy = True End Sub Private Sub RadGridView1_ViewCellFormatting(sender As Object, e As CellFormattingEventArgs) Handles RadGridView1.ViewCellFormatting If e.Row.HierarchyLevel > 0 Then e.CellElement.TableElement.RowHeaderColumnWidth = 100 End If End Sub
To reproduce: private void Form1_Load(object sender, EventArgs e) { this.suppliersTableAdapter.Fill(this.nwindDataSet.Suppliers); this.productsTableAdapter.Fill(this.nwindDataSet.Products); radGridView1.DataSource = nwindDataSet.Suppliers; radGridView1.BestFitColumns(BestFitColumnMode.AllCells); GridViewTemplate template = CreateTemplate(this.productsBindingSource); template.DataSource = nwindDataSet.Products; radGridView1.MasterTemplate.Templates.Add(template); GridViewRelation relation = new GridViewRelation(radGridView1.MasterTemplate); relation.ChildTemplate = template; relation.RelationName = "SuppliersProducts"; relation.ParentColumnNames.Add("SupplierID"); relation.ChildColumnNames.Add("SupplierID"); radGridView1.Relations.Add(relation); } private GridViewTemplate CreateTemplate(BindingSource source) { GridViewTemplate template = new GridViewTemplate(); template.Caption = "TaskTemplate"; template.AllowAddNewRow = false; template.EnableFiltering = true; FilterDescriptor filter = new FilterDescriptor(); filter.PropertyName = "ReorderLevel"; filter.Operator = FilterOperator.IsNotEqualTo; filter.Value = 25; template.FilterDescriptors.Add(filter); template.ShowFilteringRow = false; template.SortDescriptors.Expression = "ProductName ASC, UnitPrice ASC"; template.DataSource = source; template.BestFitColumns(BestFitColumnMode.AllCells); return template; } Workaround: set the filter after the hierarchy setup: private void Form1_Load(object sender, EventArgs e) { this.suppliersTableAdapter.Fill(this.nwindDataSet.Suppliers); this.productsTableAdapter.Fill(this.nwindDataSet.Products); radGridView1.DataSource = nwindDataSet.Suppliers; radGridView1.BestFitColumns(BestFitColumnMode.AllCells); GridViewTemplate template = CreateTemplate(this.productsBindingSource); template.DataSource = nwindDataSet.Products; radGridView1.MasterTemplate.Templates.Add(template); GridViewRelation relation = new GridViewRelation(radGridView1.MasterTemplate); relation.ChildTemplate = template; relation.RelationName = "SuppliersProducts"; relation.ParentColumnNames.Add("SupplierID"); relation.ChildColumnNames.Add("SupplierID"); radGridView1.Relations.Add(relation); FilterDescriptor filter = new FilterDescriptor(); filter.PropertyName = "ReorderLevel"; filter.Operator = FilterOperator.IsNotEqualTo; filter.Value = 25; template.FilterDescriptors.Add(filter); } private GridViewTemplate CreateTemplate(BindingSource source) { GridViewTemplate template = new GridViewTemplate(); template.Caption = "TaskTemplate"; template.AllowAddNewRow = false; template.EnableFiltering = true; template.ShowFilteringRow = false; template.SortDescriptors.Expression = "ProductName ASC, UnitPrice ASC"; template.DataSource = source; template.BestFitColumns(BestFitColumnMode.AllCells); return template; }
Please refer to the attached screenshot and sample video. Workaround: public class CustomGrid : RadGridView { public override string ThemeClassName { get { return typeof(RadGridView).FullName; } } protected override void OnKeyPress(KeyPressEventArgs e) { this.BeginEdit(); if (this.GridViewElement.ActiveEditor is RadDropDownListEditor) { string symbol = e.KeyChar.ToString(); RadDropDownListEditor editor = this.GridViewElement.ActiveEditor as RadDropDownListEditor; RadDropDownListEditorElement element = editor.EditorElement as RadDropDownListEditorElement; if ((element.AutoCompleteMode & AutoCompleteMode.Suggest) == AutoCompleteMode.Suggest) { element.EditableElementText += symbol; element.EditableElement.SelectionStart = 1; element.EditableElement.SelectionLength = 0; } } base.OnKeyPress(e); } }
To reproduce: private void Form1_Load(object sender, EventArgs e) { this.productsTableAdapter.Fill(this.nwindDataSet.Products); this.categoriesTableAdapter.Fill(this.nwindDataSet.Categories); radGridView1.AllowSearchRow = true; radGridView1.DataSource = nwindDataSet.Categories; radGridView1.MasterTemplate.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill; radGridView1.UseScrollbarsInHierarchy = true; GridViewTemplate template = new GridViewTemplate(); template.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill; template.DataSource = nwindDataSet.Products; radGridView1.MasterTemplate.Templates.Add(template); GridViewRelation relation = new GridViewRelation(radGridView1.MasterTemplate); relation.ChildTemplate = template; relation.RelationName = "CategoriesProducts"; relation.ParentColumnNames.Add("CategoryID"); relation.ChildColumnNames.Add("CategoryID"); radGridView1.Relations.Add(relation); } Workaround: private void radGridView1_CurrentRowChanged(object sender, CurrentRowChangedEventArgs e) { if (this.radGridView1.CurrentRow != null) { if (this.radGridView1.CurrentRow.HierarchyLevel > 0) { tableElement.ScrollToRow((GridViewHierarchyRowInfo)(this.radGridView1.CurrentRow).Parent); this.radGridView1.TableElement.EnsureRowVisible((GridViewHierarchyRowInfo)(this.radGridView1.CurrentRow).Parent); tableElement.ScrollToRow(this.radGridView1.CurrentRow); tableElement.EnsureRowVisible(this.radGridView1.CurrentRow); } } }
To reproduce: Search a specific text by focusing the search box programmatically and the using the SendKeys method: private void radButton1_Click(object sender, EventArgs e) { GridSearchCellElement searchCell = radGridView1.TableElement.GetCellElement(radGridView1.MasterView.TableSearchRow, null) as GridSearchCellElement; if (searchCell != null) { searchCell.SearchTextBox.Focus(); searchCell.SearchTextBox.Text = string.Empty; SendKeys.Send("t"); SendKeys.Send("e"); SendKeys.Send("s"); SendKeys.Send("t"); } } Workaround: Repeat the search in the SearchProgressChanged event: radGridView1.MasterView.TableSearchRow.SearchProgressChanged += TextationSearchProgressHandler; protected void TextationSearchProgressHandler(object sender, SearchProgressChangedEventArgs e) { if (e.SearchFinished && null != radGridView1.TableElement) { GridSearchCellElement searchCell = radGridView1.TableElement.GetCellElement(radGridView1.MasterView.TableSearchRow, null) as GridSearchCellElement; if (searchCell != null && searchCell.SearchTextBox.TextBoxItem.Text != e.SearchCriteria) { radGridView1.MasterView.TableSearchRow.Search(searchCell.SearchTextBox.TextBoxItem.Text); } } }
To reproduce: public class Item { public int Id { get; set; } public string Name { get; set; } public DateTime Date { get; set; } public Item(int id, string name, DateTime date) { this.Id = id; this.Name = name; this.Date = date; } } public Form1() { InitializeComponent(); List<Item> items = new List<Item>(); for (int i = 0; i < 10; i++) { items.Add(new Item(i,"Item" + i,DateTime.Now.AddHours(i))); } this.radGridView1.DataSource = items; this.radGridView1.AutoSizeColumnsMode = Telerik.WinControls.UI.GridViewAutoSizeColumnsMode.Fill; } private void Form1_Load(object sender, EventArgs e) { System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-GB"); this.radGridView1.Columns["Date"].ExcelExportFormatString = "M/d/yyyy h:mm tt"; this.radGridView1.Columns["Date"].ExcelExportType = DisplayFormatType.Custom; GridViewSpreadExport spreadExporter = new GridViewSpreadExport(this.radGridView1); spreadExporter.ExportVisualSettings = true; SpreadExportRenderer exportRenderer = new SpreadExportRenderer(); string fileName = @"..\..\exportedFile" + DateTime.Now.ToLongTimeString().Replace(":", "_") + ".xlsx"; spreadExporter.RunExport(fileName, exportRenderer); Process.Start(fileName); }
Workaround: use a custom BaseGridBehavior public Form1() { InitializeComponent(); this.radGridView1.GridBehavior = new MyBaseGridBehavior(); } public class MyBaseGridBehavior : BaseGridBehavior { public override bool ProcessKey(KeyEventArgs keys) { if (keys.Control && this.GridControl.CurrentColumn == null) { return false; } return base.ProcessKey(keys); } }
To reproduce: - Add some rows to a grid. - Sort the rows. - Delete a row. - The current row is not the next row. Workaround: Dim t As Test = RadGridView1.CurrentRow.DataBoundItem Dim index As Integer = Me.RadGridView1.ChildRows.IndexOf(Me.RadGridView1.CurrentRow) datasource.Remove(t) Me.RadGridView1.CurrentRow = Me.RadGridView1.ChildRows(index)
To reproduce: 1. Run the attached application. 2. Click into the cell in Column One and expand the combo box 3. While the combo box is still expanded, right click on any header cell in the grid Step 3 should result in a NullReferenceException Workaround: Friend Class MyGridHeaderCellElement Inherits GridHeaderCellElement Public Sub New(ByVal col As GridViewColumn, ByVal row As GridRowElement) MyBase.New(col, row) End Sub Protected Overrides Sub ShowContextMenu() If Me.ViewTemplate IsNot Nothing Then MyBase.ShowContextMenu() End If End Sub Protected Overrides ReadOnly Property ThemeEffectiveType() As Type Get Return GetType(GridHeaderCellElement) End Get End Property End Class Private Sub radGridView1_CreateCell(ByVal sender As Object, ByVal e As GridViewCreateCellEventArgs) If Object.ReferenceEquals(e.CellType, GetType(GridHeaderCellElement)) Then e.CellType = GetType(MyGridHeaderCellElement) End If End Sub
To reproduce: public Form1() { InitializeComponent(); DataTable dt = new DataTable(); for (int i = 0; i < 5; i++) { dt.Columns.Add("Col"+i); } for (int i = 0; i < 2000; i++) { DataRow row = dt.NewRow(); foreach (DataColumn col in dt.Columns) { row[col.ColumnName] = "Data" + i + "." + dt.Columns.IndexOf(col); } dt.Rows.Add(row); } this.radGridView1.DataSource = dt; this.radGridView1.AutoSizeColumnsMode = Telerik.WinControls.UI.GridViewAutoSizeColumnsMode.Fill; } private void radButton1_Click(object sender, EventArgs e) { RadPrintPreviewDialog dialog = new RadPrintPreviewDialog(); dialog.Document = this.radPrintDocument1; dialog.ShowDialog(); } Workaround: this.radGridView1.AutoSizeRows = true;
To reproduce: Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load Me.RadGridView1.AutoGenerateColumns = False Dim column = New GridViewTextBoxColumn column.Name = "Name" column.FieldName = "ChildItem" column.DataType = GetType(CustomItem) column.DataTypeConverter = New CustomItemTypeConverter() Me.RadGridView1.Columns.Add(column) Me.RadGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill Dim objects = { New CustomContainer With {.ChildItem = New CustomItem With {.Name = "A"}}, New CustomContainer With {.ChildItem = New CustomItem With {.Name = "B"}}, New CustomContainer With {.ChildItem = New CustomItem With {.Name = "C"}} } Me.RadGridView1.DataSource = objects End Sub Private Sub RadGridView_EditorRequired(sender As Object, e As EditorRequiredEventArgs) Handles RadGridView1.EditorRequired e.EditorType = GetType(GridSpinEditor) End Sub Class CustomContainer Public Property ChildItem As CustomItem End Class Class CustomItem Public Property Name As String End Class Class CustomItemTypeConverter Inherits TypeConverter Public Overrides Function CanConvertFrom(context As ITypeDescriptorContext, sourceType As Type) As Boolean If sourceType = GetType(Decimal) Then Return True End If Return MyBase.CanConvertFrom(context, sourceType) End Function Public Overrides Function CanConvertTo(context As ITypeDescriptorContext, destinationType As Type) As Boolean If destinationType = GetType(Decimal) OrElse destinationType = GetType(String) OrElse destinationType = GetType(CustomItem) Then Return True End If Return MyBase.CanConvertTo(context, destinationType) End Function Public Overrides Function ConvertTo(context As ITypeDescriptorContext, culture As System.Globalization.CultureInfo, _ value As Object, destinationType As Type) As Object If TypeOf value Is CustomItem Then Dim customValue = DirectCast(value, CustomItem) If destinationType = GetType(Decimal) Then Return Microsoft.VisualBasic.AscW(customValue.Name.Chars(0)) ElseIf destinationType = GetType(String) Then Return customValue.Name ElseIf destinationType = GetType(CustomItem) Then Return customValue Else Return MyBase.ConvertTo(context, culture, value, destinationType) End If End If Return MyBase.ConvertTo(context, culture, value, destinationType) End Function Public Overrides Function ConvertFrom(context As ITypeDescriptorContext, culture As System.Globalization.CultureInfo, value As Object) As Object If TypeOf value Is Decimal Then Dim decValue = DirectCast(value, Decimal) Dim intValue = CInt(decValue) Dim charValue = Microsoft.VisualBasic.ChrW(intValue) Return New CustomItem With {.Name = New String(charValue, 1)} End If Return MyBase.ConvertFrom(context, culture, value) End Function End Class Workaround: Public Class MyEditor Inherits GridSpinEditor Public Overrides ReadOnly Property IsModified() As Boolean Get If Me.originalValue Is Nothing Then Return (Me.Value IsNot Nothing AndAlso Me.Value <> DBNull.Value) End If If Me.Value Is Nothing Then Return (Me.originalValue IsNot Nothing AndAlso Me.originalValue <> DBNull.Value) End If Dim column As GridViewDataColumn = (DirectCast(Me.OwnerElement, GridDataCellElement)).ColumnInfo If column.DataTypeConverter IsNot Nothing AndAlso column.DataTypeConverter.CanConvertTo(Me.OwnerElement, GetType(Decimal)) Then Return Not column.DataTypeConverter.ConvertTo(Me.OwnerElement, column.FormatInfo, Me.originalValue, GetType(Decimal)).Equals(Convert.ToDecimal(Me.Value)) End If Return Not Convert.ToDecimal(Me.originalValue).Equals(Convert.ToDecimal(Me.Value)) End Get End Property End Class Private Sub RadGridView_EditorRequired(sender As Object, e As EditorRequiredEventArgs) Handles RadGridView1.EditorRequired e.EditorType = GetType(MyEditor) End Sub
All event handlers should be made virtual. All controls should be public or have properties.
To reproduce: private void Form2_Load(object sender, EventArgs e) { this.productsTableAdapter.Fill(this.nwindDataSet.Products); this.categoriesTableAdapter.Fill(this.nwindDataSet.Categories); this.radGridView1.AutoGenerateHierarchy = true; this.radGridView1.DataSource = this.nwindDataSet; this.radGridView1.DataMember = "Categories"; this.radGridView1.MasterTemplate.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill; this.radGridView1.MasterTemplate.Templates.First().AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill; GridViewSummaryItem summaryItem = new GridViewSummaryItem(); summaryItem.Name = "CategoryID"; summaryItem.Aggregate = GridAggregateFunction.Count; GridViewSummaryRowItem summaryRowItem = new GridViewSummaryRowItem(); summaryRowItem.Add(summaryItem); this.radGridView1.SummaryRowsTop.Add(summaryRowItem); GridViewSummaryItem summaryItem2 = new GridViewSummaryItem(); summaryItem2.Name = "UnitPrice"; summaryItem2.Aggregate = GridAggregateFunction.Sum; GridViewSummaryRowItem summaryRowItem2 = new GridViewSummaryRowItem(); summaryRowItem2.Add(summaryItem2); this.radGridView1.MasterTemplate.Templates.First().SummaryRowsTop.Add(summaryRowItem2); } private void SetNumberFormat() { this.radGridView1.Columns["CategoryID"].FormatString = "{0:F4}"; this.radGridView1.SummaryRowsTop[0][0].FormatString = "{0:F4}"; this.radGridView1.MasterTemplate.Templates.First().Columns["UnitPrice"].FormatString = "{0:F4}"; this.radGridView1.MasterTemplate.Templates.First().SummaryRowsTop[0][0].FormatString = "{0:F4}"; } private void radButton1_Click(object sender, EventArgs e) { SetNumberFormat(); } Workaround: Clear and add back the summary rows when a value in the child template is changed. private void radButton1_Click(object sender, EventArgs e) { this.radGridView1.MasterTemplate.Templates.First().SummaryRowsTop.Clear(); GridViewSummaryItem summaryItem2 = new GridViewSummaryItem(); summaryItem2.Name = "UnitPrice"; summaryItem2.Aggregate = GridAggregateFunction.Sum; GridViewSummaryRowItem summaryRowItem2 = new GridViewSummaryRowItem(); summaryRowItem2.Add(summaryItem2); this.radGridView1.MasterTemplate.Templates.First().SummaryRowsTop.Add(summaryRowItem2); SetNumberFormat(); }
Workaround: use custom editor element private void radGridView1_EditorRequired(object sender, EditorRequiredEventArgs e) { if (e.EditorType == typeof(RadMultiColumnComboBoxElement)) { e.EditorType = typeof(MyRadMultiColumnComboBoxElement); } } public class MyRadMultiColumnComboBoxElement : RadMultiColumnComboBoxElement { protected override Type ThemeEffectiveType { get { return typeof(RadMultiColumnComboBoxElement); } } protected override void ProcessKeyDown(object sender, KeyEventArgs e) { base.ProcessKeyDown(sender, e); FieldInfo fi = this.GetType().BaseType.BaseType.GetField("oldTextValue", BindingFlags.Instance | BindingFlags.NonPublic); fi.SetValue(this, this.textBox.Text.Substring(0, this.textBox.SelectionStart)); } }
To reproduce: 1. Add a RadGridView with a GridViewMultiComboBoxColumn. Enable the auto filter functionality for this column and add an appropriate FilterDescriptor to the RadMultiColumnComboBoxElement. 2. Using the keyboard arrows only (no mouse), navigate to the GridViewMultiComboBoxColumn. 3. Type "ba" by using the keyboard. The "b" is lost and only the "a" gets to the filter. I expect the filter to show "ba". Workaround: use custom row behavior public Form1() { InitializeComponent(); //register the custom row behavior BaseGridBehavior gridBehavior = radGridView1.GridBehavior as BaseGridBehavior; gridBehavior.UnregisterBehavior(typeof(GridViewDataRowInfo)); gridBehavior.RegisterBehavior(typeof(GridViewDataRowInfo), new CustomGridDataRowBehavior()); } public class CustomGridDataRowBehavior : GridDataRowBehavior { protected override bool ProcessAlphaNumericKey(KeyPressEventArgs keys) { bool result = base.ProcessAlphaNumericKey(keys); if (this.IsInEditMode && (this.BeginEditMode == RadGridViewBeginEditMode.BeginEditOnKeystroke || this.BeginEditMode == RadGridViewBeginEditMode.BeginEditOnKeystrokeOrF2)) { if (this.GridViewElement.ActiveEditor is RadMultiColumnComboBoxElement) { this.GridViewElement.ActiveEditor.Value = keys.KeyChar; if (this.GridViewElement.IsInEditMode) { RadMultiColumnComboBoxElement mccb = (RadMultiColumnComboBoxElement)this.GridViewElement.ActiveEditor; RadTextBoxItem textBoxItem = mccb.TextBoxElement.TextBoxItem; textBoxItem.Clear(); textBoxItem.Text = keys.KeyChar.ToString(); textBoxItem.SelectionStart = 1; textBoxItem.SelectionLength = 0; } return true; } } return result; } }
To reproduce: public abstract class Base { public abstract string Name { get; } } public class Child : Base { public override string Name { get { return "Child"; } } } public class Child2 : Base { public override string Name { get { return "Child2"; } } } public partial class RadForm1 : Telerik.WinControls.UI.RadForm { public RadForm1() { InitializeComponent(); var list = new List<Base>(); list.Add(new Child()); list.Add(new Child()); list.Add(new Child2()); radGridView1.DataSource = list.ToArray(); } } Workaround: radGridView1.DataSource = list;