We'd like to see the ability to enable a search/filter function for column chooser. One of our applications that uses the RadGridView has dozens of columns, most hidden by default. Our users would like the ability to type in part of a column name and have the column chooser filter on it.
To reproduce: 1. Filter the first column in the grid 2. Click the header checkbox 3. Try to clear the filter. you iwll notice that the data is still filtered. Workaround: private void radGridView1_CreateCell(object sender, GridViewCreateCellEventArgs e) { if (e.CellType==typeof(GridCheckBoxHeaderCellElement)) { e.CellElement = new CustomHeaderCell(e.Column, e.Row); } } public class CustomHeaderCell : GridCheckBoxHeaderCellElement { public CustomHeaderCell(GridViewColumn column, GridRowElement row) : base(column, row) { } protected override void checkbox_ToggleStateChanged(object sender, StateChangedEventArgs args) { base.checkbox_ToggleStateChanged(sender, args); this.TableElement.EndUpdate(false); } }
How to reproduce: Check the attached video --> radgridview-filtering.gif Workaround: public partial class Form1 : Form { public Form1() { InitializeComponent(); this.radGridView1.DataSource = this.GetData(); this.radGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill; this.radGridView1.EnableFiltering = true; this.radGridView1.FilterChanging += RadGridView1_FilterChanging; this.radGridView1.FilterChanged += RadGridView1_FilterChanged; } private void RadGridView1_FilterChanged(object sender, GridViewCollectionChangedEventArgs e) { if (clearFiler) { this.radGridView1.FilterDescriptors.Remove((FilterDescriptor)e.NewItems[0]); clearFiler = false; } } bool clearFiler = false; private void RadGridView1_FilterChanging(object sender, GridViewCollectionChangingEventArgs e) { if (e.PropertyName == "Operator" && e.Action == Telerik.WinControls.Data.NotifyCollectionChangedAction.ItemChanging) { FilterDescriptor fd = e.OldItems[0] as FilterDescriptor; if (fd != null && (fd.Operator == FilterOperator.IsNull || fd.Operator == FilterOperator.IsNotNull)) { clearFiler = true; } } } private object GetData() { DataTable dt = new DataTable(); dt.Columns.Add("Id", typeof(int)); dt.Columns.Add("Name", typeof(string)); dt.Columns.Add("Date", typeof(DateTime)); dt.Columns.Add("Bool", typeof(bool)); for (int i = 0; i < 100; i++) { dt.Rows.Add(i, "Name " + i, DateTime.Now.AddDays(i), i % 2 == 0); } return dt; } }
Workaround: Use the Copying event.
The CustomSorting event should manipulate the pinned rows as well. Thus, the user will be allowed to control the sort order of the pinned rows within the pinned container.
Steps to reproduce: 1. Set DPI scale to 150 of all screens 2. Run attached sample 3. The column`s width is not calculated correctly.
Attached project for reproducing. Workaround: var column = radGridView1.Columns[2] as GridViewDecimalColumn; var format = column.FormatString; column.FormatString = ""; column.ExcelExportType = DisplayFormatType.Currency; //export the grid column.FormatString = format;
Please refer to the attached sample project and follow the steps illustrated in the attached gif file.
To reproduce: public Form1() { InitializeComponent(); DataTable dt = new DataTable(); dt.Columns.Add("Id", typeof(int)); dt.Columns.Add("Name", typeof(string)); dt.Columns.Add("ParentId", typeof(int)); for (int i = 0; i < 3; i++) { dt.Rows.Add(i, "Parent" + i, -1); } Random rand = new Random(); for (int i = 3; i < 15; i++) { dt.Rows.Add(i,"Child"+i,rand.Next(0,3)); } this.radGridView1.Relations.AddSelfReference(this.radGridView1.MasterTemplate, "Id", "ParentId"); this.radGridView1.DataSource = dt; this.radGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill; this.radGridView1.EnableGrouping = true; this.radGridView1.EnableCustomGrouping = true; this.radGridView1.CustomGrouping+=radGridView1_CustomGrouping; } private void radGridView1_CustomGrouping(object sender, GridViewCustomGroupingEventArgs e) { }
To reproduce: private void RadGridView1_KeyPress(object sender, KeyPressEventArgs e) { int startIndex = radGridView1.CurrentRow.Index +1; for (int i = startIndex; i < radGridView1.Rows.Count; i++) { var value = radGridView1.Rows[i].Cells["Name"].Value.ToString().ToLower(); if (value.StartsWith(e.KeyChar.ToString())) { radGridView1.TableElement.ScrollToRow(radGridView1.Rows[i]); radGridView1.ClearSelection(); radGridView1.Rows[i].IsSelected = true; radGridView1.Rows[i].IsCurrent = true; radGridView1.Columns[1].IsCurrent = true; break; } } } - Press some key so the grid is scrolled down, then press the down key. - The first row is selected instead of the next one. Workaround: remove this line: radGridView1.Rows[i].IsSelected = true;
To reproduce: 1. Run the attached sample project. 2. Right-click the grid. 3. Quickly navigate to another application (e.g. Windows Explorer) before the context menu is shown & wait at windows explorer to display the menu 4. The context will be stuck.
To reproduce: please refer to the attached sample project and follow the steps in the provided gif file: 1. Enter something in the search bar 2. Filter on some column, uncheck "All", then select a few items, then validate 3. Click on a random row on the grid 4. Filter on the same column as in 2., check "All", then uncheck a few items, then validate Workaround: private void radGridView1_FilterChanged(object sender, Telerik.WinControls.UI.GridViewCollectionChangedEventArgs e) { this.radGridView1.MasterTemplate.Refresh(); }
Please refer to the attached sample project and gif file illustrating the behavior. ColumnGroupsViewDefinition view = this.radGridView1.ViewDefinition as ColumnGroupsViewDefinition; foreach (GridViewColumnGroup group in view.ColumnGroups) { group.ShowHeader = false; } Workaround: use the ViewCellFormatting and enable the back color for the header cells that are over the hidden group headers public RadForm1() { InitializeComponent(); ColumnGroupsViewDefinition view = this.radGridView1.ViewDefinition as ColumnGroupsViewDefinition ; foreach (GridViewColumnGroup group in view.ColumnGroups) { group.ShowHeader = false; } } private void radGridView1_ViewCellFormatting(object sender, CellFormattingEventArgs e) { if (e.Row is GridViewTableHeaderRowInfo && !(e.CellElement is GridColumnGroupCellElement)) { e.CellElement.DrawFill = true; e.CellElement.BackColor = Color.FromArgb(234, 242, 252); e.CellElement.GradientStyle = GradientStyles.Solid; } else { e.CellElement.ResetValue(LightVisualElement.DrawFillProperty, ValueResetFlags.Local); e.CellElement.ResetValue(LightVisualElement.BackColorProperty, ValueResetFlags.Local); e.CellElement.ResetValue(LightVisualElement.GradientStyleProperty, ValueResetFlags.Local); } }
How to reproduce: public partial class Form1 : Form { public class Data { public bool Checked { get; set; } public string Text { get; set; } } private readonly RadGridView _grid; private readonly List<Data> _dataList = new List<Data> { new Data {Text = "abc"}, new Data {Text = "def"}, new Data {Text = "ghi"}, new Data {Text = "jkl"}, new Data {Text = "mno"}, new Data {Text = "pqr"}, new Data {Text = "stu"}, new Data {Text = "vwx"}, new Data {Text = "yz0"} }; public Form1() { InitializeComponent(); _grid = new RadGridView { Dock = DockStyle.Fill, AllowSearchRow = true }; Controls.Add(_grid); _grid.DataSource = _dataList; } protected override void OnLoad(EventArgs e) { base.OnLoad(e); _grid.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill; ((GridViewCheckBoxColumn)_grid.Columns["Checked"]).EnableHeaderCheckBox = true; _grid.Columns["Checked"].SortOrder = RadSortOrder.Ascending; ((GridViewCheckBoxColumn)_grid.Columns["Checked"]).Checked = ToggleState.On; _grid.MasterView.TableSearchRow.Search("abc"); } } Workaround: clear the search text protected override void OnLoad(EventArgs e) { base.OnLoad(e); _grid.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill; ((GridViewCheckBoxColumn)_grid.Columns["Checked"]).EnableHeaderCheckBox = true; _grid.Columns["Checked"].SortOrder = RadSortOrder.Ascending; ((GridViewCheckBoxColumn)_grid.Columns["Checked"]).Checked = ToggleState.On; _grid.MasterView.TableSearchRow.Search("abc"); this._grid.MouseDown += _grid_MouseDown; } private void _grid_MouseDown(object sender, MouseEventArgs e) { RadGridView grid = (RadGridView)sender; RadCheckBoxElement cell = grid.ElementTree.GetElementAtPoint(e.Location) as RadCheckBoxElement; if (cell != null && cell.Parent is GridCheckBoxHeaderCellElement && grid.SortDescriptors.Count > 0)) { grid.MasterView.TableSearchRow.Search(""); } }
To reproduce: protected override void OnLoad(EventArgs e) { base.OnLoad(e); DataTable dt = NewDt(); this.radGridView1.DataSource = dt; var c = this.radGridView1.Columns["Calculted"] as GridViewDecimalColumn; c.EnableExpressionEditor = true; c.Expression = "Column2 / SUM(Column2) * 10"; c.DecimalPlaces = 2; c.FormatString = "{0:N2}"; this.radGridView1.GroupDescriptors.Add("GroupByColumn", ListSortDirection.Ascending); } private DataTable NewDt() { var dt = new DataTable(); dt.Columns.Add("ItemColumn"); dt.Columns.Add("GroupByColumn"); dt.Columns.Add("Column2", typeof(decimal)); dt.Columns.Add("Calculted", typeof(decimal)); for (int i = 1; i <= 20; i++) { string gr = string.Empty; if (i % 3 == 0) gr = "gr3"; else if (i % 2 == 0) gr = "gr2"; else if (i % 5 == 0) gr = "gr5"; else gr = "item" + i.ToString(); dt.Rows.Add("id #" + i.ToString(), gr, i, 0); } return dt; } Workaround: public class CustomExpressionContext : Telerik.Data.Expressions.ExpressionContext { RadGridView radGridView; public CustomExpressionContext(RadGridView grid) { this.radGridView = grid; } public decimal MySum(string columnName) { decimal sum = 0; foreach (var item in radGridView.Rows) { sum += (decimal)item.Cells[columnName].Value; } return sum; } } Telerik.Data.Expressions.ExpressionContext.Context = new CustomExpressionContext(this.radGridView1);
To reproduce: run the attached sample project. You will notice the result illustrated in the provided screenshot. Although the grid is RTL, the print preview dialog show it in LTR. Workaround: public class CustomGridPrintStyle : GridPrintStyle { protected override BaseGridPrintRenderer InitializePrintRenderer(RadGridView grid) { if (this.PrintRenderer != null) { this.PrintRenderer.PrintCellPaint -= renderer_PrintCellPaint; this.PrintRenderer.PrintCellFormatting -= renderer_PrintCellFormatting; this.PrintRenderer.ChildViewPrinting -= renderer_ChildViewPrinting; } BaseGridPrintRenderer renderer = null; if (grid.ViewDefinition.GetType() == typeof(ColumnGroupsViewDefinition)) { if (!(renderer is ColumnGroupsViewDefinitionPrintRenderer)) { renderer = new CustomColumnGroupsViewDefinitionPrintRenderer(grid); } } else if (grid.ViewDefinition.GetType() == typeof(HtmlViewDefinition)) { if (!(renderer is HtmlViewDefinitionPrintRenderer)) { renderer = new HtmlViewDefinitionPrintRenderer(grid); } } else { if (!(renderer is TableViewDefinitionPrintRenderer)) { renderer = new TableViewDefinitionPrintRenderer(grid); } } renderer.ChildViewPrinting += renderer_ChildViewPrinting; renderer.PrintCellFormatting += renderer_PrintCellFormatting; renderer.PrintCellPaint += renderer_PrintCellPaint; return renderer; } private void renderer_PrintCellPaint(object sender, PrintCellPaintEventArgs e) { this.OnPrintCellPaint(sender, e); } private void renderer_PrintCellFormatting(object sender, PrintCellFormattingEventArgs e) { this.OnPrintCellFormatting(sender, e); } private void renderer_ChildViewPrinting(object sender, ChildViewPrintingEventArgs e) { this.OnChildViewPrinting(sender, e); } } public class CustomColumnGroupsViewDefinitionPrintRenderer : ColumnGroupsViewDefinitionPrintRenderer { public CustomColumnGroupsViewDefinitionPrintRenderer(RadGridView grid) : base(grid) { } protected override void PrintRow(GridViewRowInfo row, ColumnGroupRowLayout rowLayout, GridPrintSettings settings, int currentX, int currentY, Graphics graphics) { float scrollableColumnsOffset = 0f; float rightPinnedColumnsOffset = 0f; foreach (GridViewColumn col in rowLayout.RenderColumns) { if (col is GridViewRowHeaderColumn || col is GridViewIndentColumn) { continue; } float height = rowLayout.GetRowHeight(row); RectangleF cellBounds = rowLayout.GetCorrectedColumnBounds(row, col, this.GridView.RightToLeft == RightToLeft.Yes, new RectangleF(0f, 0f, rowLayout.DesiredSize.Width, height)); if (cellBounds == RectangleF.Empty) { continue; } if (col.PinPosition == PinnedColumnPosition.Left) { if (scrollableColumnsOffset < cellBounds.Right + rowLayout.Owner.CellSpacing) { scrollableColumnsOffset = cellBounds.Right + rowLayout.Owner.CellSpacing; rightPinnedColumnsOffset = scrollableColumnsOffset; } } else if (col.PinPosition == PinnedColumnPosition.None) { if (rightPinnedColumnsOffset < scrollableColumnsOffset + cellBounds.Right + rowLayout.Owner.CellSpacing) { rightPinnedColumnsOffset = scrollableColumnsOffset + cellBounds.Right + rowLayout.Owner.CellSpacing; } cellBounds.X += scrollableColumnsOffset; } else { cellBounds.X += rightPinnedColumnsOffset; } cellBounds.Offset(currentX, currentY); GridViewCellInfo cell; CellPrintElement printCell; if (row is GridViewTableHeaderRowInfo) { cell = this.GridView.MasterView.TableHeaderRow.Cells[col.Name]; printCell = this.CreateHeaderCellPrintElement(col); if (printCell.Font != settings.HeaderCellFont) { if (settings.HeaderCellFont != null) { printCell.Font = settings.HeaderCellFont; } else { settings.HeaderCellFont = printCell.Font; } } } else if (row is GridViewSummaryRowInfo) { GridViewSummaryRowInfo rowInfo = row as GridViewSummaryRowInfo; cell = rowInfo.Cells[col.Name]; if (cell == null) { continue; } printCell = this.CreateSummaryCellPrintElement(cell); if (printCell.Font != settings.SummaryCellFont) { if (settings.SummaryCellFont != null) { printCell.Font = settings.SummaryCellFont; } else { settings.SummaryCellFont = printCell.Font; } } } else { cell = row.Cells[col.Name]; if (cell == null) { continue; } if (col is GridViewImageColumn) { printCell = this.CreateImageCellPrintElement(cell); } else { printCell = this.CreateDataCellPrintElement(cell); if (printCell.Font != settings.CellFont) { if (settings.CellFont != null) { printCell.Font = settings.CellFont; } else { settings.CellFont = printCell.Font; } } } } printCell.TextPadding = this.GridView.PrintStyle.CellPadding; printCell.RightToLeft = this.GridView.RightToLeft == RightToLeft.Yes; Rectangle rect = new Rectangle((int)cellBounds.X, (int)cellBounds.Y, (int)cellBounds.Width, (int)cellBounds.Height); PrintCellFormattingEventArgs formattEventArgs = new PrintCellFormattingEventArgs(row, col, printCell); this.OnPrintCellFormatting(formattEventArgs); formattEventArgs.PrintCell.Paint(graphics, rect); PrintCellPaintEventArgs paintEventArgs = new PrintCellPaintEventArgs(graphics, row, col, rect); this.OnPrintCellPaint(paintEventArgs); } } } private void radButton1_Click(object sender, EventArgs e) { CustomGridPrintStyle style = new CustomGridPrintStyle(); this.radGridView1.PrintStyle = style; RadPrintDocument printDoc = new RadPrintDocument(); printDoc.Landscape = true; printDoc.RightHeader = "Right Header"; printDoc.HeaderHeight = 100; printDoc.AssociatedObject = this.radGridView1; RadPrintPreviewDialog dialog = new RadPrintPreviewDialog(printDoc); dialog.Size = new System.Drawing.Size(Screen.PrimaryScreen.Bounds.Width - 200, Screen.PrimaryScreen.Bounds.Height - 200); dialog.SetZoom(0.80); dialog.ShowDialog(); }
There should be a way for users to determine if a row passes a certain filter criteria without that affecting any data operations.
The selection mode should be as in Windows Explorer - when Control is pressed, one should be able to move the current row with the up/down arrow keys and when Space is pressed, the current row should be selected/deselected. This implementation can be used for the time being: public partial class Form1 : RadForm { protected override void OnLoad(EventArgs e) { base.OnLoad(e); AddGridSimpleUnbound(); radGridView1.MultiSelect = true; BaseGridBehavior gridBehavior = radGridView1.GridBehavior as BaseGridBehavior; gridBehavior.UnregisterBehavior(typeof(GridViewDataRowInfo)); gridBehavior.RegisterBehavior(typeof(GridViewDataRowInfo), new MyRowBehavior()); radGridView1.GridViewElement.Navigator = new MyNavigator(); } class MyNavigator : BaseGridNavigator { protected override bool DoMultiSelect(GridViewRowInfo oldRow, GridViewColumn oldColumn, GridViewRowInfo row, GridViewColumn column) { if (!this.IsShiftButtonPressed && this.IsControlButtonPressed && !this.IsMouseSelection) { return true; } return base.DoMultiSelect(oldRow, oldColumn, row, column); } } class MyRowBehavior : GridDataRowBehavior { bool kbdSelection = false; public override bool ProcessKeyPress(KeyPressEventArgs keys) { if (kbdSelection) { kbdSelection = false; return true; } return base.ProcessKeyPress(keys); } public override bool ProcessKey(KeyEventArgs keys) { if (keys.KeyCode == Keys.Space && this.GridControl.MultiSelect && keys.Control) { this.GridControl.CurrentRow.IsSelected ^= true; kbdSelection = true; return false; } else { return base.ProcessKey(keys); } } } }