Workaround: use the following custom editor: using System; using Telerik.WinControls.UI; namespace radGridView_MultipleFilters { public class CustomRadMultiColumnComboBoxElement : RadMultiColumnComboBoxElement { protected override Type ThemeEffectiveType { get { return typeof(RadMultiColumnComboBoxElement); } } public GridViewDataColumn DisplayColumn { get { string displayMember = this.DisplayMember; if (string.IsNullOrEmpty(displayMember)) { for (int i = 0; i < this.MultiColumnPopupForm.EditorControl.Columns.Count; i++) { if (this.MultiColumnPopupForm.EditorControl.Columns[i].DataType == typeof(string)) { displayMember = this.MultiColumnPopupForm.EditorControl.Columns[i].FieldName; break; } } if (this.MultiColumnPopupForm.EditorControl.Columns.Count > 0 && string.IsNullOrEmpty(displayMember)) { displayMember = this.MultiColumnPopupForm.EditorControl.Columns[0].FieldName; } } DisplayMember = displayMember; GridViewDataColumn[] columns = this.MultiColumnPopupForm.EditorControl.Columns.GetColumnByFieldName(displayMember); if (columns.Length > 0) { return columns[0]; } return null; } } protected override object FindItemExact(string text) { int index = this.FindItemIndexExact(text); if (index != -1) { return this.EditorControl.ChildRows[index]; } return null; } protected override void SetActiveItem(string text) { int rowIndex = this.FindItemIndexExact(text); if (rowIndex != -1) { this.EditorControl.CurrentRow = this.EditorControl.ChildRows[rowIndex]; this.Select(this.Text.Length, 0); } } protected override int FindItemIndexExact(string text) { GridViewRowInfo rowInfo = this.FindItemExact(text, this.DisplayColumn.Name); if (rowInfo != null) { return rowInfo.Index; } return -1; } protected override GridViewRowInfo FindItemExact(string text, string field) { GridViewDataColumn[] foundColumns = this.EditorControl.Columns.GetColumnByFieldName(field); if (foundColumns.Length > 0) { for (int i = 0; i < this.EditorControl.ChildRows.Count; i++) { object element = this.EditorControl.ChildRows[i].Cells[foundColumns[0].Name].Value; string elementText = Convert.ToString(element); if (!string.IsNullOrEmpty(elementText) && elementText.Equals(text, this.EditorControl.MasterTemplate.CaseSensitive ? StringComparison.InvariantCulture : StringComparison.InvariantCultureIgnoreCase)) { return this.EditorControl.ChildRows[i]; } } } return null; } } }
How to reproduce: public partial class Form1 : Form { private RadGridView grid = new RadGridView(); public Form1() { InitializeComponent(); Controls.Add(grid); grid.Dock = DockStyle.Fill; grid.DataSource = this.GetData(); } private object GetData() { DataTable dataTable = new DataTable(); dataTable.Columns.Add("Id", typeof(int)); dataTable.Columns.Add("Name", typeof(string)); dataTable.Columns.Add("Checked", typeof(bool)); for (int i = 0; i < 200; i++) { dataTable.Rows.Add(i, "Name " + i, i % 2 == 0); } return dataTable; } protected override void OnLoad(EventArgs e) { base.OnLoad(e); grid.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill; GridViewCheckBoxColumn checkBoxColumn = (GridViewCheckBoxColumn)grid.Columns["Checked"]; checkBoxColumn.EnableHeaderCheckBox = true; checkBoxColumn.SortOrder = RadSortOrder.Ascending; } } Workaround: public partial class Form1 : Form { private RadGridView grid = new RadGridView(); public Form1() { InitializeComponent(); Controls.Add(grid); grid.Dock = DockStyle.Fill; grid.DataSource = this.GetData(); grid.MouseDown += grid_MouseDown; grid.MouseUp += grid_MouseUp; } private object GetData() { DataTable dataTable = new DataTable(); dataTable.Columns.Add("Id", typeof(int)); dataTable.Columns.Add("Name", typeof(string)); dataTable.Columns.Add("Checked", typeof(bool)); for (int i = 0; i < 200; i++) { dataTable.Rows.Add(i, "Name " + i, i % 2 == 0); } return dataTable; } 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) { sw = new Stopwatch(); sw.Start(); grid.BeginUpdate(); } } Stopwatch sw; private void grid_MouseUp(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.EndUpdate(); sw.Stop(); Console.WriteLine(sw.ElapsedMilliseconds); } } protected override void OnLoad(EventArgs e) { base.OnLoad(e); grid.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill; GridViewCheckBoxColumn checkBoxColumn = (GridViewCheckBoxColumn)grid.Columns["Checked"]; checkBoxColumn.EnableHeaderCheckBox = true; checkBoxColumn.SortOrder = RadSortOrder.Ascending; } }
FormatException is raised when a user attempts to filter RadGridView's combobox column
To reproduce: public Form1() { InitializeComponent(); List<Item> items = new List<Item>(); items.Add(new Item(1,"sample")); items.Add(new Item(2, null)); items.Add(new Item(3, "sample2")); this.radGridView1.DataSource = items; this.radGridView1.AutoSizeColumnsMode = Telerik.WinControls.UI.GridViewAutoSizeColumnsMode.Fill; this.radGridView1.EnableFiltering = true; this.radGridView1.ShowFilteringRow = false; this.radGridView1.ShowHeaderCellButtons = true; } public class Item { public int Id { get; set; } public string Description { get; set; } public Item(int id, string description) { this.Id = id; this.Description = description; } } Workaround: If possible, instead of using null value, use empty string. If not possible, you will have to employ 3 classes - MyFilterMenuTreeElement, MyFilterMenuTreeItem, MyListFilterPopup. The classes are provided in the attached project RadGridViewFiltering.zip. Once you add the classes to your project, all you have to do is to replace the default popup with the new one, in the FilterPopupRequired handler: private void RadGridView1_FilterPopupRequired(object sender, FilterPopupRequiredEventArgs e) { if (e.FilterPopup is RadListFilterPopup) { e.FilterPopup = new MyListFilterPopup(e.Column); } } The approach is also demonstrated in the attached project.
RadGridView is throwing exception when loading layout that contains a GroupDescriptor with predefined Format with Aggregate function. Steps to reproduce: 1. Add GroupDescriptor: Dim descriptor As New GroupDescriptor descriptor.GroupNames.Add("column3", System.ComponentModel.ListSortDirection.Ascending) descriptor.Aggregates.Add("Sum(column3)") descriptor.Format = "{0}: {1} Total montant : {2:c2}" Me.RadGridView1.GroupDescriptors.Add(descriptor) 2. Save Layout 3. Load Layout
To reproduce: - Assing context menu using one of the default properties.
Workaround: public partial class Form1 : Form { public Form1() { InitializeComponent(); this.radGridView1.DataSource = this.GetData(); this.radGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill; ((GridViewDateTimeColumn)this.radGridView1.Columns["Date"]).FormatString = "{0: yyyy-MM-dd hh:mm:ss.fff tt}"; } private DataTable 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; } } public class MyRadGridView : RadGridView { public override string ThemeClassName { get { return typeof(RadGridView).FullName; } } protected override RadGridViewElement CreateGridViewElement() { return new MyRadGridViewElement(); } } public class MyRadGridViewElement : RadGridViewElement { protected override Type ThemeEffectiveType { get { return typeof(MyRadGridViewElement); } } protected override MasterGridViewTemplate CreateTemplate() { return new MyMasterGridViewTemplate(); } } public class MyMasterGridViewTemplate : MasterGridViewTemplate { public override void Copy() { base.Copy(); GridViewCellInfo[] cells = null; if (this.SelectionMode == GridViewSelectionMode.CellSelect) { cells = new GridViewCellInfo[this.SelectedCells.Count]; this.SelectedCells.CopyTo(cells, 0); } else if (this.SelectionMode == GridViewSelectionMode.FullRowSelect) { GridViewDataRowInfo row = this.SelectedRows[0] as GridViewDataRowInfo; if (this.SelectedRows.Count == 1 && row.ViewTemplate.CurrentColumn != null) { cells = new GridViewCellInfo[row.Cells.Count]; for (int i = 0; i < row.Cells.Count; i++) { cells[i] = row.Cells[i]; } } } if (Clipboard.GetData(DataFormats.Text) != null) { string data = Clipboard.GetData(DataFormats.Text).ToString(); if (data != string.Empty && cells != null) { var values = data.Split(new char[] { '\t' }, StringSplitOptions.RemoveEmptyEntries); StringBuilder sb = new StringBuilder(); foreach (string value in values) { DateTime date; if (DateTime.TryParse(value, out date)) { string baseFormat = "yyyy-MM-dd HH:mm tt"; foreach (var cell in cells) { if (cell.ColumnInfo is GridViewDateTimeColumn && ((DateTime)cell.Value).ToString(baseFormat) == date.ToString(baseFormat)) { sb.Append(string.Format(((GridViewDateTimeColumn)cell.ColumnInfo).FormatString, cell.Value) + "\t"); break; } } } else { sb.Append(value + "\t"); } } Clipboard.Clear(); Clipboard.SetData(DataFormats.Text, sb.ToString()); } } } }
To reproduce: private void Form1_Load(object sender, EventArgs e) { this.productsTableAdapter.Fill(this.nwindDataSet.Products); this.categoriesTableAdapter.Fill(this.nwindDataSet.Categories); this.radGridView1.AutoGenerateColumns = false; this.radGridView1.DataSource = this.productsBindingSource; GridViewComboBoxColumn col = new GridViewComboBoxColumn(); col.DataSource = this.categoriesBindingSource; col.MinWidth = 200; col.DisplayMember = "Description"; 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) { string value = "{nothing}"; if (e.Value != null) { value = Convert.ToString(e.Value); } RadMessageBox.Show("CellValueChanged. Value >> " + value); } Note: if the cell value is not null, the CellValueChanged event is not fired when the selection in drop down is not changed. Additional scenario: if you use a RadMultiColumnComboBoxElement for this column replaced in the EditorRequired, the issue is reproducible again.
Add the ability to filter by empty values (not null values) just like in excel.
To reproduce: public Form1() { InitializeComponent(); radGridView1.Columns.Add(new GridViewTextBoxColumn("Text1")); radGridView1.Columns.Add(new GridViewTextBoxColumn("Text2")); radGridView1.Columns.Add(new GridViewTextBoxColumn("Text3")); radGridView1.Columns.Add(new GridViewTextBoxColumn("Text4")); radGridView1.Columns.Add(new GridViewTextBoxColumn("Text5")); radGridView1.Columns.Add(new GridViewTextBoxColumn("Text6")); radGridView1.Columns.Add(new GridViewTextBoxColumn("Text7")); radGridView1.Columns.Add(new GridViewTextBoxColumn("Text8")); radGridView1.Columns.Add(new GridViewDateTimeColumn("Date1")); radGridView1.Columns.Add(new GridViewDecimalColumn("Amount1")); radGridView1.Columns.Add(new GridViewDecimalColumn("Amount2")); radGridView1.Columns.Add(new GridViewDecimalColumn("Amount3")); radGridView1.Columns.Add(new GridViewDecimalColumn("Amount4")); radGridView1.Columns.Add(new GridViewDecimalColumn("Amount5")); radGridView1.Columns.Add(new GridViewDecimalColumn("Amount6")); radGridView1.DataSource = GetDataSet(); } private DataTable GetDataSet() { DataTable dt = new DataTable(); dt.Columns.Add(new DataColumn("Text1", typeof(string))); dt.Columns.Add(new DataColumn("Text2", typeof(string))); dt.Columns.Add(new DataColumn("Text3", typeof(string))); dt.Columns.Add(new DataColumn("Text4", typeof(string))); dt.Columns.Add(new DataColumn("Text5", typeof(string))); dt.Columns.Add(new DataColumn("Text6", typeof(string))); dt.Columns.Add(new DataColumn("Text7", typeof(string))); dt.Columns.Add(new DataColumn("Text8", typeof(string))); dt.Columns.Add(new DataColumn("Date1", typeof(DateTime))); dt.Columns.Add(new DataColumn("Amount1", typeof(decimal))); dt.Columns.Add(new DataColumn("Amount2", typeof(decimal))); dt.Columns.Add(new DataColumn("Amount3", typeof(decimal))); dt.Columns.Add(new DataColumn("Amount4", typeof(decimal))); dt.Columns.Add(new DataColumn("Amount5", typeof(decimal))); dt.Columns.Add(new DataColumn("Amount6", typeof(decimal))); for (int i = 1; i <= 150000; i++) { dt.Rows.Add(new object[] { "Example Text For Row " + i.ToString(), "Example Text For Row " + i.ToString(), "More Example Text For Row " + i.ToString(), "Even More Example Text For Row " + i.ToString(), "Lots More Example Text For Row " + i.ToString(), "Excessive Example Text For Row " + i.ToString(), "Extra Example Text For Row " + i.ToString(), "Random Example Text For Row " + i.ToString(), new DateTime(2015, i % 12 + 1, i % 28 + 1), i % 2 * 10000, i % 3 * 10000, i % 5 * 10000, i % 7 * 10000, i % 11 * 10000, i % 13 * 10000 }); } return dt; } string fileName = @"..\..\" + DateTime.Now.ToLongTimeString().Replace(":", "_"); private void button1_Click(object sender, EventArgs e) { SaveFileDialog sfdExportToExcel = new SaveFileDialog(); DialogResult exportBrowse = sfdExportToExcel.ShowDialog(); if (exportBrowse == DialogResult.OK) { GridViewSpreadExport exporter = new GridViewSpreadExport(this.radGridView1); exporter.SheetMaxRows = Telerik.WinControls.UI.Export.ExcelMaxRows._1048576; exporter.FileExportMode = FileExportMode.CreateOrOverrideFile; exporter.ExportVisualSettings = false; exporter.AsyncExportCompleted += exporter_AsyncExportCompleted; SpreadExportRenderer renderer = new SpreadExportRenderer(); exporter.RunExportAsync(fileName, renderer); } }
Implement "Tag" and "Name" properties into the GridViewColumnGroup.
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
use attached project with pre-build release version of assemblies included in the 'telerik-devbranch-release' folder 1. Create a new project with RadGridView and bind it to a data source. The data source should contain a large number of rows (30000 for example) 2. Add a check box column 3. Run the project 4. Sort by a column (different from the checkbox column) 5. Check a checkbox 6. Click on some other column or row
To reproduce: Add a RadGridView wth a few columns ,add rows as a few rows should have increasingly long text. Right click on the header cell to show the context menu and click bestfit. You will notice that the size of the column is not correct Workaround: void grid_MouseMove(object sender, MouseEventArgs e) { this.mouseLocation = e.Location; } private Point mouseLocation; private GridViewColumn currentColumn; void grid_ContextMenuOpening(object sender, ContextMenuOpeningEventArgs e) { if (this.grid.CurrentRow is GridViewHierarchyRowInfo) { RadItem bestFitItem = e.ContextMenu.Items.FirstOrDefault(x => x.Text == "Best Fit"); if (bestFitItem != null) { e.ContextMenu.Items.Remove(bestFitItem); } RadMenuItem newBestFitItem = new RadMenuItem { Text = "Best Fit" }; this.currentColumn = (this.grid.ElementTree.GetElementAtPoint(this.mouseLocation) as GridCellElement).ColumnInfo; newBestFitItem.Click += newBestFitItem_Click; e.ContextMenu.Items.Add(newBestFitItem); } } void newBestFitItem_Click(object sender, EventArgs e) { int highestWidth = this.GetHeightestWidthFromColumn(this.currentColumn); this.currentColumn.Width = highestWidth; } private int GetHeightestWidthFromColumn(GridViewColumn gridViewColumn) { int max = int.MinValue; Font cellFont = this.grid.TableElement.VisualRows[0].VisualCells[0].Font; for (int i = 0; i < this.grid.Rows.Count; i++) { int textWidth = TextRenderer.MeasureText(this.grid.Rows[i].Cells[gridViewColumn.Index].Value + "", cellFont).Width; if (max < textWidth) { max = textWidth; } } return max; }
Improve the filtering by date time column by adding properties that enable choosing whether to include time part and seconds part
IIF function in Expression for calculated columns does not work.
IMPROVE. RadExpressionEditorForm - one should be able to access the form and its controls in order to customize their appearance
Currently it is not possible to insert custom worksheets (for example notes or a cover page) when exporting via ExportToExcelML
Currently RadGridView supports only copy & paste between grid cells