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
}
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());
}