ADD. RadPivotGrid - add ability to filter by more than one condition - composite filters
Currently the only way to recognize something changed as accurate as possible is to use StatusChanged on the DataProvider, but that does not tell apart from a structure change or just a click on the Update button… it would be nice to have such events available (onUpdate, onFieldListModified etc)
Until the feature gets implemented use custom PivotGridPrintStyle: Public Class MyPivotGridPrintStyle Inherits PivotGridPrintStyle Const MIN_SPACE As Integer = 1 Public Overrides Sub DrawPage(drawArea As Rectangle, graphics As Graphics, pageNumber As Integer) If Me.PivotGrid.ColumnHeaderHeight > MIN_SPACE Then MyBase.DrawPage(drawArea, graphics, pageNumber) Else Dim x As Integer = drawArea.X Dim y As Integer = drawArea.Y Dim scale As SizeF = DirectCast(Me.GetType().BaseType.GetMethod("GetScaleFactors", BindingFlags.Instance Or BindingFlags.NonPublic).Invoke(Me, New Object() {drawArea}), SizeF) Dim startColumn As Integer = DirectCast(Me.GetType().BaseType.GetMethod("GetStartColumn", BindingFlags.Instance Or BindingFlags.NonPublic).Invoke(Me, New Object() {pageNumber, drawArea, scale.Width}), Integer) Dim endColumn As Integer = DirectCast(Me.GetType().BaseType.GetMethod("GetEndColumn", BindingFlags.Instance Or BindingFlags.NonPublic).Invoke(Me, New Object() {startColumn, drawArea, scale.Width}), Integer) Dim startRow As Integer = DirectCast(Me.GetType().BaseType.GetMethod("GetStartRow", BindingFlags.Instance Or BindingFlags.NonPublic).Invoke(Me, New Object() {pageNumber, drawArea, scale.Height}), Integer) Dim endRow As Integer = DirectCast(Me.GetType().BaseType.GetMethod("GetEndRow", BindingFlags.Instance Or BindingFlags.NonPublic).Invoke(Me, New Object() {startRow, drawArea, scale.Height}), Integer) If Me.PivotGrid.ColumnHeaderHeight <= MIN_SPACE Then startRow += 1 End If For i As Integer = startRow To endRow x = drawArea.X Dim maxHeight As Integer = 0 For j As Integer = startColumn To endColumn Dim columnWidths = DirectCast(Me.GetType().BaseType.GetField("columnWidths", BindingFlags.Instance Or BindingFlags.NonPublic).GetValue(Me), List(Of Integer)) Dim rowHeights = DirectCast(Me.GetType().BaseType.GetField("rowHeights", BindingFlags.Instance Or BindingFlags.NonPublic).GetValue(Me), List(Of Integer)) Dim elementRect As New Rectangle(x, y, columnWidths(j), rowHeights(i)) Dim printElement As RadPrintElement = Me.GetPrintElementForCell(i, j) printElement.ScaleTransform = scale Dim transformedRect As RectangleF = printElement.GetTransformedBounds(elementRect) Me.PrintElement(printElement, drawArea, elementRect, graphics) x += CInt(Math.Floor(transformedRect.Width)) maxHeight = Math.Max(maxHeight, CInt(Math.Floor(transformedRect.Height))) Next y += maxHeight Next End If End Sub End Class
How to reproduce check the attached project and video Workaround: handle the UpdateCompleted event and explicitly set the properties to true public LocalDataSourceSerializerForm() { InitializeComponent(); this.radPivotGrid1.AutoExpandColumnHeaders = false; this.radPivotGrid1.AutoExpandRowHeaders = false; this.radPivotGrid1.UpdateCompleted += radPivotGrid1_UpdateCompleted; } private void radPivotGrid1_UpdateCompleted(object sender, EventArgs e) { this.radPivotGrid1.AutoExpandColumnHeaders = true; this.radPivotGrid1.AutoExpandRowHeaders = true; }
You save 2 config, one with Report filter (1), one without (2), if you load first (1), if puts report filter correctly, but if you load then (2) - report filter still as on (1). Also, if you load config with ShowFilterArea=true - it stays visible if you load another config with ShowFilterArea=true Hello Alex, While investigating the reported behavior I managed to isolate an issue in the Save/Load API of RadPivotGrid regarding the ShowFilterArea property. The default value of this property is not serialized, however this can be altered by adding a serialization meta data to the XmlSerializationInfo instance of the pivot. In this scenario the engine did not respect the added new data. Here is the feedback item and you can subscribe to it: http://feedback.telerik.com/Project/154/Feedback/Details/196273-fix-radpivotgrid-the-saveloadlayout-string-overload-does-not-use-the-radpivotg. The item is already in development and a permanent fix will be available with our next release. Regarding the empty filter descriptions, in order to serialize them one should work with a DataProviderSerializer class. Currently our engine does not save the empty filters and we will consider modifying it so that even if the collection is empty it also be serialized. I am attaching to this post a sample project with which you would be able to achieve both of your tasks. Please note that the serialization API of the LocalDataSourceProvider uses the DataContract and you would need to use our .NET 4.0 assemblies. I hope this helps. In case you need additional assistance please write here or open a support ticket. Regards, Hristo
Workaround: private void PrintPivotGrid() { MyPivotGridPrintStyle style = new MyPivotGridPrintStyle(); style.LayoutType = PivotLayout.Tabular; this.radPivotGrid1.PrintStyle = style; this.radPivotGrid1.PrintPreview(); } public class MyPivotGridPrintStyle : PivotGridPrintStyle { public override void Initialize() { base.Initialize(); FieldInfo fiColumnWidths = this.GetType().BaseType.GetField("columnWidths", BindingFlags.Instance | BindingFlags.NonPublic); List<int> columnWidths = (List<int>)fiColumnWidths.GetValue(this); RadPivotGridElement pivotGrid = (RadPivotGridElement)this.GetType().BaseType.GetField("pivotGrid", BindingFlags.Instance | BindingFlags.NonPublic) .GetValue(this); for (int i = 0; i < pivotGrid.RowDescriptorsArea.Children.Count; i++) { RadElement descriptor = pivotGrid.RowDescriptorsArea.Children[i]; columnWidths[i] = descriptor.Size.Width; } } }
How to reproduce: var data = this.dbContext.Orders.Where(o => o.OrderID > 10500).Select(o => new { Id = o.OrderID, OrderDate = o.OrderDate, ShipDate = o.ShippedDate, Freight = o.Freight }).ToArray(); this.localDataProvider = new LocalDataSourceProvider() {ItemsSource = data}; Workaround: 1. Instead of ToArray call ToList var data = this.dbContext.Orders.Where(o => o.OrderID > 10500).Select(o => new { Id = o.OrderID, OrderDate = o.OrderDate, ShipDate = o.ShippedDate, Freight = o.Freight }).ToList(); this.localDataProvider = new LocalDataSourceProvider() {ItemsSource = data}; 2. Call the ToArray method but do not create anonymous objects. var data = this.dbContext.Orders.Where(o => o.OrderID > 10500).Select(o => new PivotModel { Id = o.OrderID, OrderDate = o.OrderDate, ShipDate = o.ShippedDate, Freight = o.Freight }).ToArray(); this.localDataProvider = new LocalDataSourceProvider() {ItemsSource = data}; public class PivotModel { public int Id { get; set; } public DateTime? OrderDate { get; set; } public DateTime? ShipDate { get; set; } public decimal? Freight { get; set; } }
How to reproduce: check the attached video Workaround: private void button1_Click(object sender, EventArgs e) { this.radPivotFieldList1.DragDropService.PreviewDragDrop += DragDropService_PreviewDragDrop; } IGroupDescription cache; string group; private void DragDropService_PreviewDragDrop(object sender, Telerik.WinControls.RadDropEventArgs e) { TreeNodeElement nodeElement = e.DragInstance as TreeNodeElement; if (nodeElement != null) { IField field = nodeElement.Data.DataBoundItem as IField; string draggedItem = field.FieldInfo.Name; IGroupDescription rowDesc = this.radPivotGrid1.RowGroupDescriptions.Where(i => i.GetUniqueName() == draggedItem).FirstOrDefault(); if (rowDesc != null) { cache = (IGroupDescription)rowDesc.Clone(); group = "Row"; } IGroupDescription colDesc = this.radPivotGrid1.ColumnGroupDescriptions.Where(i => i.GetUniqueName() == draggedItem).FirstOrDefault(); if (colDesc != null) { cache = (IGroupDescription)colDesc.Clone(); group = "Column"; } if (cache != null) { this.radPivotGrid1.UpdateCompleted += radPivotGrid1_UpdateCompleted; } } } private void radPivotGrid1_UpdateCompleted(object sender, EventArgs e) { this.radPivotGrid1.UpdateCompleted -= radPivotGrid1_UpdateCompleted; switch (group) { case "Row": this.radPivotGrid1.RowGroupDescriptions.Add(cache); break; case "Column": this.radPivotGrid1.ColumnGroupDescriptions.Add(cache); break; default: break; } cache = null; }
Workaround: private IList<PivotGroupNode> collapsedRowsNodes; private void customMenuItem_Click(object sender, EventArgs e) { PivotGridSpreadExport spreadExport = new PivotGridSpreadExport(pivotGrid); spreadExport.ExportCompleted += spreadExport_ExportCompleted; spreadExport.ExportFlatData = true; this.collapsedRowsNodes = new List<PivotGroupNode>(); PivotGridGroupTraverser rowTraverser = (PivotGridGroupTraverser)this.pivotGrid.PivotGridElement.RowScroller.Traverser.GetEnumerator(); while (rowTraverser.MoveNext()) { PivotGroupNode current = rowTraverser.Current; if (!current.Expanded) { this.collapsedRowsNodes.Add(current); current.Expanded = true; } } spreadExport.RunExport(@"..\..\export.xlsx", new SpreadExportRenderer()); } private void spreadExport_ExportCompleted(object sender, EventArgs e) { foreach (PivotGroupNode node in this.collapsedRowsNodes) { node.Expanded = false; } }
Include a way for the developers to set the height of the header in code
What I would like is to be able to export to a named sheet and keep the other sheets in file. For example:
"Sheet 1" (with new values), "Sheet2" (with old values)
Using your current naming convention, the Option might be named FileExportMode.CreateOrOverrideSheet
To reproduce: Resize some of the columns in PivotGrid and then export it with PivotExporttoExcelML. All columns in exported file have the same width. Workaround: Use PivotGridSpreadExport.
IMPROVE. RadPivotGrid - expose a method for accessing cell values
Workaround: public Form1() { InitializeComponent(); this.radPivotGrid1.GroupDescriptorElementCreating += radPivotGrid1_GroupDescriptorElementCreating; } private void radPivotGrid1_GroupDescriptorElementCreating(object sender, Telerik.WinControls.UI.GroupDescriptorElementCreatingEventArgs e) { FieldInfo fi = e.GroupDescriptorElement.GetType().GetField("filterPopup", BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); fi.SetValue(e.GroupDescriptorElement, new MyPivotGroupFilterPopup(e.GroupDescriptorElement) { Visible = false }); e.GroupDescriptorElement.SortDirectionArrow.Visibility = ElementVisibility.Collapsed; } public class MyPivotGroupFilterPopup : PivotGroupFilterPopup { public MyPivotGroupFilterPopup(PivotGroupDescriptorElement pivotGroupDescriptorElement) : base(pivotGroupDescriptorElement) { } protected override void LoadSettings() { base.LoadSettings(); this.Items.Remove(SortAZMenuItem); this.Items.Remove(SortZAMenuItem); this.Items.Remove(SortOptionsMenuItem); } }
Workaround: public Form1() { InitializeComponent(); this.radPivotGrid1.GroupDescriptorElementCreating += radPivotGrid1_GroupDescriptorElementCreating; } private void radPivotGrid1_GroupDescriptorElementCreating(object sender, Telerik.WinControls.UI.GroupDescriptorElementCreatingEventArgs e) { e.GroupDescriptorElement.FilterPopup.PopupOpened -= FilterPopup_PopupOpened; e.GroupDescriptorElement.FilterPopup.PopupOpened += FilterPopup_PopupOpened; } private void FilterPopup_PopupOpened(object sender, EventArgs args) { PivotGroupFilterPopup filterPopup = (PivotGroupFilterPopup)sender; RadTreeView tree = filterPopup.TreeViewMenuItem.TreeElement.TreeView; ((RadScrollBarElement)tree.TreeViewElement.Children[2]).Value = 10; ((RadScrollBarElement)tree.TreeViewElement.Children[2]).Value = 0; }