To reproduce: - Bind the grid and reset its data source in the CellValueChanged event handler. - Start the application, click in a cell, delete the contents and right click a header cell. - Exception is thrown. Workaround: class MyGridHeaderCellElement : GridHeaderCellElement { public MyGridHeaderCellElement(GridViewColumn col, GridRowElement row) : base(col, row) { } protected override Type ThemeEffectiveType { get { return typeof(GridHeaderCellElement); } } protected override void ShowContextMenu() { if (this.ViewTemplate != null) { base.ShowContextMenu(); } } } private void RadGridView1_CreateCell(object sender, GridViewCreateCellEventArgs e) { if (e.CellType == typeof(GridHeaderCellElement)) { e.CellType = typeof(MyGridHeaderCellElement); } }
To reproduce: DataTable dt = new DataTable(); public Form1() { InitializeComponent(); dt.Columns.Add("Id"); dt.Columns.Add("Name"); dt.Columns.Add("Type"); for (int i = 0; i < 30; i++) { dt.Rows.Add(i, "Item" + i, "Type" + i % 2); } this.radGridView1.DataSource = dt; this.radGridView1.AutoExpandGroups = true; GroupDescriptor descriptor = new GroupDescriptor(); descriptor.GroupNames.Add("Type", ListSortDirection.Ascending); this.radGridView1.GroupDescriptors.Add(descriptor); } private void button1_Click(object sender, EventArgs e) { dt.Rows.Add(30, "Item30", "Type3"); } Workaround: set the AutoExpandGroups property to false and manually expand the groups when a new row is added.
To reproduce: please refer to the attached gif file demonstrating how to reproduce the issue with the Demo application. Workaround: use the basic filtering.
Add an ExportToXlsx option into the native RadGridView exporting. It has been done for WPF (http://docs.telerik.com/devtools/wpf/controls/radgridview/export/export-xlsx) - why not WinForms. This would avoid the pain of having to implement the export using RadSpreadProcessing.
To reproduce: Open the attached project, select two rows and delete them. Workaround: private void RadGridView1_RowValidating(object sender, Telerik.WinControls.UI.RowValidatingEventArgs e) { if (e.RowIndex != -1) { } }
To reproduce: populate RadGridView with data and use the following code snippet: Me.RadGridView1.TableElement.TableHeaderHeight = 60 RadGridView1.PrintPreview() Workaround: Private Sub RadButton1_Click(sender As Object, e As EventArgs) Handles RadButton1.Click Me.RadGridView1.TableElement.TableHeaderHeight = 60 Dim printStyle As GridPrintStyle = New GridPrintStyle(RadGridView1) Dim renderer As CustomTableViewDefinitionPrintRenderer = New CustomTableViewDefinitionPrintRenderer(RadGridView1) printStyle.PrintRenderer = renderer RadGridView1.PrintStyle = printStyle RadGridView1.PrintPreview() End Sub Public Class CustomTableViewDefinitionPrintRenderer Inherits TableViewDefinitionPrintRenderer Public Sub New(grid As RadGridView) MyBase.New(grid) End Sub Private Function GetRowLayout(row As GridViewRowInfo, fitWidthMode As PrintFitWidthMode, _ hierarchyIndent As Integer, drawArea As Rectangle) As TableViewRowLayout Dim hashKey As Integer = row.ViewTemplate.GetHashCode() + row.HierarchyLevel Dim fi As FieldInfo = GetType(TableViewDefinitionPrintRenderer).GetField("rowLayouts", BindingFlags.NonPublic Or BindingFlags.Instance) Dim rowLayouts As Dictionary(Of Integer, TableViewRowLayout) = fi.GetValue(Me) If rowLayouts.ContainsKey(hashKey) Then Return rowLayouts(hashKey) End If Dim table As GridTableElement = TryCast(row.ViewTemplate.ViewDefinition.CreateViewUIElement(row.ViewInfo), GridTableElement) table.Initialize(Me.GridView.GridViewElement, row.ViewInfo) table.RowHeight = Me.GridView.TableElement.RowHeight table.TableHeaderHeight = Me.GridView.TableElement.TableHeaderHeight Me.GridView.ElementTree.ApplyThemeToElement(table) Dim rowLayout As New TableViewRowLayout() rowLayout.Context = GridLayoutContext.Printer rowLayout.Initialize(table) Dim systemWidth As Integer = 0 For Each c As GridViewColumn In rowLayout.RenderColumns If TypeOf c Is GridViewRowHeaderColumn OrElse TypeOf c Is GridViewIndentColumn Then systemWidth += rowLayout.GetColumnWidth(c) End If Next Me.GridView.BeginUpdate() Dim mode As GridViewAutoSizeColumnsMode = rowLayout.ViewTemplate.AutoSizeColumnsMode If fitWidthMode = PrintFitWidthMode.FitPageWidth Then Dim state As ColumnsState = Me.SaveColumnsState(rowLayout.ViewTemplate) rowLayout.ViewTemplate.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill Dim groupLevel As Integer = If(row.Group IsNot Nothing, row.Group.Level + 1, 0) rowLayout.MeasureRow(New SizeF(drawArea.Width + systemWidth - ((row.HierarchyLevel - groupLevel) * hierarchyIndent), drawArea.Height)) Me.RestoreColumnsState(state) Else rowLayout.ViewTemplate.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.None rowLayout.MeasureRow(New SizeF(Me.GridView.Width, Me.GridView.Height)) End If rowLayout.ViewTemplate.AutoSizeColumnsMode = mode Me.GridView.EndUpdate(False) rowLayouts.Add(hashKey, rowLayout) Return rowLayout End Function Public Overrides Sub DrawPage(traverser As PrintGridTraverser, drawArea As Rectangle, _ graphics As Graphics, settings As GridPrintSettings, pageNumber As Integer) Dim fi As FieldInfo = GetType(TableViewDefinitionPrintRenderer).GetField("currentPage", BindingFlags.Instance Or BindingFlags.NonPublic) Dim currentPage As Integer = fi.GetValue(Me) Dim skipPage As Boolean = currentPage <> pageNumber Dim drawAreaHeight As Integer = drawArea.Height Dim currentX As Integer = drawArea.X Dim currentY As Integer = drawArea.Y Dim rowLayout As TableViewRowLayout = Me.GetRowLayout(Me.GridView.MasterView.TableHeaderRow, _ settings.FitWidthMode, settings.HierarchyIndent, drawArea) rowLayout.IgnoreColumnVisibility = settings.PrintHiddenColumns Dim systemWidth As Integer = 0 For Each c As GridViewColumn In rowLayout.RenderColumns If TypeOf c Is GridViewRowHeaderColumn OrElse TypeOf c Is GridViewIndentColumn Then systemWidth += rowLayout.GetColumnWidth(c) End If Next Dim rowWidth As Integer = CInt(rowLayout.DesiredSize.Width) - systemWidth If settings.FitWidthMode = PrintFitWidthMode.NoFitCentered Then currentX += ((drawArea.Width - rowWidth) / 2) End If Dim fi2 As FieldInfo = GetType(TableViewDefinitionPrintRenderer).GetField("firstPage", _ BindingFlags.Instance Or BindingFlags.NonPublic) Dim firstPage As Integer = fi2.GetValue(Me) If ((Me.GridView.ShowColumnHeaders AndAlso (firstPage AndAlso pageNumber = 1)) OrElse settings.PrintHeaderOnEachPage) _ AndAlso Not settings.PrintHierarchy Then Me.PrintRow(Me.GridView.MasterView.TableHeaderRow, rowLayout, settings, currentX, currentY, graphics, _ drawArea) Dim rowHeight As Integer = Me.GetDataRowHeight(Me.GridView.MasterView.TableHeaderRow, rowLayout) + Me.GridView.TableElement.RowSpacing currentY += rowHeight drawAreaHeight -= rowHeight End If fi2.SetValue(Me, False) Dim skipPageCurrentY As Integer = currentY Dim row As GridViewRowInfo = Nothing If Me.PrintPages.Count > 0 AndAlso Not settings.PrintHierarchy Then row = traverser.Current End If Dim firstRow As Boolean = True While traverser.MoveNext() If Not (TypeOf traverser.Current Is GridViewDataRowInfo OrElse TypeOf traverser.Current Is GridViewGroupRowInfo OrElse _ TypeOf traverser.Current Is GridViewSummaryRowInfo OrElse (TypeOf traverser.Current Is GridViewTableHeaderRowInfo _ AndAlso settings.PrintHierarchy)) Then Continue While End If Dim hierarchyRow As GridViewHierarchyRowInfo = TryCast(traverser.Current, GridViewHierarchyRowInfo) If hierarchyRow IsNot Nothing AndAlso hierarchyRow.Views.Count > 0 Then Select Case settings.ChildViewPrintMode Case ChildViewPrintMode.PrintFirstView hierarchyRow.ActiveView = hierarchyRow.Views(0) Exit Select Case ChildViewPrintMode.PrintCurrentlyActiveView 'Do nothing the view is already selected Exit Select Case ChildViewPrintMode.SelectViewToPrint Dim e As New ChildViewPrintingEventArgs(hierarchyRow.Views.IndexOf(hierarchyRow.ActiveView), hierarchyRow) Me.OnChildViewPrinting(e) hierarchyRow.ActiveView = hierarchyRow.Views(e.ActiveViewIndex) Exit Select End Select End If rowLayout = Me.GetRowLayout(traverser.Current, settings.FitWidthMode, settings.HierarchyIndent, drawArea) Dim rowHeight As Integer = 0 If TypeOf traverser.Current Is GridViewGroupRowInfo Then rowHeight = Me.GetRowSize(traverser.Current, rowLayout).Height Else rowHeight = Me.GetDataRowHeight(traverser.Current, rowLayout) End If If (currentY + rowHeight >= drawArea.Bottom OrElse skipPageCurrentY + rowHeight >= drawArea.Bottom) AndAlso Not firstRow Then traverser.MovePrevious() skipPageCurrentY = currentY skipPage = currentPage <> pageNumber fi.SetValue(Me, currentPage + 1) If skipPage Then Continue While Else Exit While End If End If If TypeOf traverser.Current Is GridViewGroupRowInfo Then If settings.PrintGrouping Then If currentPage = pageNumber Then Me.PrintRowWideCell(traverser.Current, rowLayout, settings, currentX, currentY, graphics) currentY += rowHeight + Me.GridView.TableElement.RowSpacing Else skipPageCurrentY += rowHeight + Me.GridView.TableElement.RowSpacing End If End If Else If TypeOf traverser.Current Is GridViewSummaryRowInfo AndAlso Not settings.PrintSummaries Then Continue While End If If currentPage = pageNumber Then Me.PrintRow(traverser.Current, rowLayout, settings, currentX, currentY, graphics, _ drawArea) currentY += rowHeight + Me.GridView.TableElement.RowSpacing Else skipPageCurrentY += rowHeight + Me.GridView.TableElement.RowSpacing End If End If If drawAreaHeight < rowHeight AndAlso firstRow Then fi.SetValue(Me, currentPage + 1) Exit While End If firstRow = False End While If Me.PrintPages.Count > 0 AndAlso Not settings.PrintHierarchy Then If currentY + Me.GetDataRowHeight(traverser.Current, rowLayout) < drawArea.Bottom OrElse _ skipPageCurrentY + Me.GetDataRowHeight(traverser.Current, rowLayout) < drawArea.Bottom Then fi.SetValue(Me, currentPage + 1) End If Me.CurrentPrintPage += 1 Me.CurrentPrintPage = Me.CurrentPrintPage Mod Me.PrintPages.Count If Me.CurrentPrintPage > 0 Then If row Is Nothing Then traverser.Reset() Else traverser.GoToRow(row) End If End If End If End Sub End Class
WORKAROUND: 1. Create a custom GridTableElement and override the ProcessColumnEvent method. 2. Create a custom TableViewDefinition and override the CreateViewUIElement to return the custom table element. 3. Assign the custom view definition to the grid's ViewDefinition property public class CustomGridTableElement : GridTableElement { protected override GridViewEventResult ProcessColumnEvent(GridViewColumn column, GridViewEvent eventData) { if (eventData.Info.Id == KnownEvents.PropertyChanged) { RadPropertyChangedEventArgs args = eventData.Arguments[0] as RadPropertyChangedEventArgs; if (args.Property == GridViewColumn.IsVisibleProperty) { ViewElement.UpdateRowsWhenColumnsChanged(); if (this.GridViewElement.AutoSizeRows) { foreach (GridViewRowInfo row in this.ViewTemplate.Rows) { row.Height = -1; } this.UpdateLayout(); this.RowScroller.UpdateScrollRange(); } return null; } } return base.ProcessColumnEvent(column, eventData); } protected override Type ThemeEffectiveType { get { return typeof(GridTableElement); } } } public class CustomTableViewDefinition : TableViewDefinition { public override IRowView CreateViewUIElement(GridViewInfo viewInfo) { return new CustomGridTableElement(); } } this.radGridView1.ViewDefinition = new CustomTableViewDefinition();
To reproduce: this.radGridView1.EnableFiltering = true; this.radGridView1.Columns.Add("Test column"); this.radGridView1.AutoSizeColumnsMode = Telerik.WinControls.UI.GridViewAutoSizeColumnsMode.Fill; this.radGridView1.Rows.Add("Test "); Workaround: use custom filtering: this.radGridView1.EnableCustomFiltering = true; this.radGridView1.CustomFiltering += radGridView1_CustomFiltering; private void radGridView1_CustomFiltering(object sender, GridViewCustomFilteringEventArgs e) { if (this.radGridView1.FilterDescriptors.Count > 0) { GridViewCellInfo cell = e.Row.Cells[this.radGridView1.FilterDescriptors[0].PropertyName]; e.Visible = cell.Value.ToString().StartsWith(this.radGridView1.FilterDescriptors[0].Value.ToString()); } }
How to reproduce: public partial class Form1 : Form { public Form1() { InitializeComponent(); this.radGridView1.DataSource = this.GetData(); this.radGridView1.AutoSizeColumnsMode = Telerik.WinControls.UI.GridViewAutoSizeColumnsMode.Fill; this.radGridView1.Columns[0].DisableHTMLRendering = false; this.radGridView1.PrintCellFormatting += radGridView1_PrintCellFormatting; } private void radGridView1_PrintCellFormatting(object sender, Telerik.WinControls.UI.PrintCellFormattingEventArgs e) { e.PrintCell.EnableHtmlTextRendering = true; } private DataTable GetData() { DataTable dt = new DataTable(); dt.Columns.Add("Name", typeof(string)); dt.Columns.Add("Date", typeof(DateTime)); dt.Columns.Add("Bool", typeof(bool)); dt.Columns.Add("Description", typeof(string)); for (int i = 0; i < 10; i++) { for (int j = 0; j < 5; j++) { dt.Rows.Add(@"<html><b>Name " + j, DateTime.Now.AddDays(i), i % 2 == 0 ? true : false, "Description " + i); } } return dt; } private void radButton1_Click(object sender, EventArgs e) { GridPrintStyle style = new GridPrintStyle(); style.FitWidthMode = PrintFitWidthMode.FitPageWidth; style.PrintGrouping = true; style.PrintSummaries = false; style.PrintHeaderOnEachPage = true; style.PrintHiddenColumns = false; style.CellPadding = new Padding(100, 0, 0, 0); this.radGridView1.PrintStyle = style; this.radGridView1.PrintPreview(); } } Workaround: refer to the attached project
To reproduce: follow the steps defined in the following help article: http://docs.telerik.com/devtools/winforms/gridview/hierarchical-grid/tutorial-binding-to-hierarchical-data Then, add a nested template in the second level. After closing the GridViewTemplate Collection Editor, you will notice that the template is not saved. http://screencast.com/t/7VDYiopuUHn Workaround: setup the hierarchy programmatically : http://docs.telerik.com/devtools/winforms/gridview/hierarchical-grid/binding-to-hierarchical-data-programmatically
To reproduce: private void Form1_Load(object sender, EventArgs e) { this.productsTableAdapter.Fill(this.nwindDataSet.Products); this.radGridView1.BestFitColumns(BestFitColumnMode.AllCells); } private void radGridView1_ViewCellFormatting(object sender, Telerik.WinControls.UI.CellFormattingEventArgs e) { if (e.CellElement is GridGroupContentCellElement) { e.CellElement.TextWrap = true; } else { e.CellElement.ResetValue(LightVisualElement.TextWrapProperty, ValueResetFlags.Local); } } Workaround: set the AutoSizeColumnsMode property to GridViewAutoSizeColumnsMode.Fill and use the ViewCellFormatting event to wrap the text: private void radGridView1_ViewCellFormatting(object sender, Telerik.WinControls.UI.CellFormattingEventArgs e) { if (e.CellElement is GridGroupContentCellElement) { e.CellElement.TextWrap = true; } else { e.CellElement.ResetValue(LightVisualElement.TextWrapProperty, ValueResetFlags.Local); } }
Until the new functionality becomes available you can use the workaround solution in the attached project.
To reproduce: run the attached sample project. Workaround: set the AutoSizeRows property to false before exporting and set it back to true after the export is completed.
To reproduce: follow the steps illustrated in the attached gif file.
One should be able to set the maximum row height when the rows are auto sized and the visual styles are exported.
To reproduce: setup the hierarchy at design time: http://docs.telerik.com/devtools/winforms/gridview/hierarchical-grid/tutorial-binding-to-hierarchical-data Please refer to the attached gif file illustrating the exact steps. NOTE: when the "Object does not match target type" error message is displayed, some of the properties are missing, e.g. MaxLength. Workaround: modify the columns' properties at run time.
Please refer to the attached project. Workakround: call the BeginEdit method in the RadGridView.Click event.
To reproduce: make sure only the first row is selected then Shift select row 3. DataTable dt = new DataTable(); dt.Columns.Add("Value", typeof(int)); dt.Columns.Add("Date", typeof(DateTime)); dt.Columns.Add("Description", typeof(string)); for (int index = 0; index < 15; index++) { dt.Rows.Add(new object[] { index % 5, DateTime.Now.AddSeconds(10), "Index = " + index }); } radGridView1.DataSource = dt; radGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill; radGridView1.MultiSelect = true; foreach (GridViewColumn col in this.radGridView1.Columns) { ConditionalFormattingObject obj = new ConditionalFormattingObject("Value", ConditionTypes.Equal, col.Index.ToString(), "", true); obj.RowBackColor = Color.SkyBlue; obj.RowForeColor = Color.Red; obj.TextAlignment = ContentAlignment.MiddleRight; obj.ApplyOnSelectedRows = false; this.radGridView1.Columns[0].ConditionalFormattingObjectList.Add(obj); } Workaround: use the CellFormatting event to apply the desired formatting by using the API for overriding theme settings: http://docs.telerik.com/devtools/winforms/gridview/cells/formatting-cells http://docs.telerik.com/devtools/winforms/telerik-presentation-framework/override-theme-settings-at-run-time
To reproduce: private void Form1_Load(object sender, EventArgs e) { this.productsTableAdapter.Fill(this.nwindDataSet.Products); this.radGridView1.EnableFiltering = true; this.radGridView1.ShowHeaderCellButtons = true; this.radGridView1.ShowFilteringRow = false; this.radGridView1.Columns["UnitPrice"].FormatString = "{0:$#,###0.00;-$#,###0.00;$0.00}"; } Workaround: in order to format the cells, use the CellFormatting event. As to the filter popup, use the following approach: this.radGridView1.FilterPopupInitialized += radGridView1_FilterPopupInitialized; private void radGridView1_FilterPopupInitialized(object sender, Telerik.WinControls.UI.FilterPopupInitializedEventArgs e) { RadListFilterPopup popup = e.FilterPopup as RadListFilterPopup; if (popup != null) { popup.MenuTreeElement.TreeView.NodeFormatting -= TreeView_NodeFormatting; popup.MenuTreeElement.TreeView.NodeFormatting += TreeView_NodeFormatting; } } private void TreeView_NodeFormatting(object sender, TreeNodeFormattingEventArgs e) { decimal price; if (decimal.TryParse(e.Node.Text, out price)) { e.NodeElement.ContentElement.Text = string.Format("{0:$#,###0.00;-$#,###0.00;$0.00}", price); } }
To reproduce: private void radButton1_Click(object sender, EventArgs e) { radGridView1.Rows[0].Cells[0].Value = false; } private void Form1_Load(object sender, EventArgs e) { radGridView1.AllowSearchRow = true; radGridView1.TableElement.SearchHighlightColor = Color.Orange; radGridView1.AutoExpandGroups = true; DataTable dt = new DataTable(); dt.Columns.Add("test", typeof(bool)); dt.Rows.Add(true); dt.Rows.Add(true); dt.Rows.Add(true); dt.Rows.Add(true); dt.Rows.Add(true); dt.Rows.Add(true); dt.Rows.Add(true); dt.Rows.Add(true); dt.Rows.Add(true); dt.Rows.Add(true); dt.Rows.Add(true); dt.Rows.Add(true); dt.Rows.Add(true); dt.Rows.Add(true); dt.Rows.Add(true); dt.Rows.Add(true); dt.Rows.Add(true); dt.Rows.Add(true); dt.Rows.Add(true); dt.Rows.Add(true); dt.Rows.Add(true); dt.Rows.Add(true); dt.Rows.Add(true); dt.Rows.Add(true); dt.Rows.Add(true); radGridView1.DataSource = dt; ((Telerik.WinControls.UI.GridViewCheckBoxColumn) radGridView1.Columns[0]).EnableHeaderCheckBox = true; ((Telerik.WinControls.UI.GridViewCheckBoxColumn) radGridView1.Columns[0]).Width = radGridView1.Width - 50; radGridView1.TableElement.Update(Telerik.WinControls.UI.GridUINotifyAction.Reset); //force header checkbox to check radGridView1.TableElement.ScrollTo(15, 0); } Workaround: private void radButton1_Click(object sender, EventArgs e) { radGridView1.Rows[0].Cells[0].Value = false; radGridView1.TableElement.Update(Telerik.WinControls.UI.GridUINotifyAction.Reset); //force header checkbox to check }