Changing the DataSource or scrolling are slow. Create a grid with more than 20 columns and add 5K rows for example. Maximize the form and try to scroll with mouse wheel. You will notice that the scrolling performance is worse compared to the normal state of the form with less visible visual elements. Workaround: this.radGridView1.EnableFastScrolling = true; and use the scrollbar's thumb Second workaround: use paging: https://docs.telerik.com/devtools/winforms/gridview/paging/overview Thus, you will display as many rows as possible to display on the screen per page. Instead of scrolling, you will navigate through pages.
When UseCompatibleTextRendering property is set to false, the data cells overlaps the row header cells when horizontal scrolling is performed.
The scenario which should be covered is selecting some data from Excel and pasting in the new row of RadGridView. This is an easy way for inserting data in the grid.
ADD. RadGridView - add support for self-reference hierarchy for child levels as well
Run the attached project on a monitor with 100% DPI scaling and open the Excel-like filter popup:
100%:
After moving the form to the second monitor with 150% DPI scaling, the filter popup is not OK:
150%:
The popup is smaller and smaller with each next opening (see the attached gif file) at 150%. If you decide to move back the form on the monitor with 100% DPI scaling, the filter popup is not scaled properly.
It appears that this scenario is not handled properly in our exporter. Consider the case where you have two templates that use view definition. The view definition from the second template is not exported at all.
Consider the iTunes Artist mode grid http://www.telerik.com/forums/itunes-like-grid
Use attached project to reproduce! Another case is when the font size is changed from the settings dialog - in this case, the row height is not adjusted. Workaround: Use the following custom print style: class MyTableViewDefinitionPrintRenderer : TableViewDefinitionPrintRenderer { public MyTableViewDefinitionPrintRenderer(RadGridView grid) : base(grid) { } protected override int GetDataRowHeight(GridViewRowInfo row, TableViewRowLayoutBase rowLayout) { int result = base.GetDataRowHeight(row, rowLayout); int newHeight = 0; if (!(row is GridViewGroupRowInfo)) { foreach (GridViewColumn col in row.ViewTemplate.Columns) { if (col is GridViewRowHeaderColumn || col is GridViewIndentColumn || !col.IsVisible) { continue; } string value = row.Cells[col.Name].Value.ToString(); TableViewCellArrangeInfo info = ((TableViewRowLayout)rowLayout).LayoutImpl.GetArrangeInfo(col); float cellWidth = (float)info.CachedWidth; int currentHeight = TextRenderer.MeasureText(value, this.GridView.PrintStyle.CellFont, new Size((int)cellWidth, 0), TextFormatFlags.WordBreak).Height + this.GridView.Font.Height *4; newHeight = Math.Max(newHeight, currentHeight); } } return Math.Max(newHeight, result); } } class MyPrintStyle :GridPrintStyle { protected override BaseGridPrintRenderer InitializePrintRenderer(RadGridView grid) { return new MyTableViewDefinitionPrintRenderer(grid); } }
To reproduce: use the following code snippet, save the layout and load it afterwards. You will notice that only the master and the first child template are successfully loaded. public Form1() { InitializeComponent(); DataTable dt = new DataTable(); dt.Columns.Add("Id", typeof(int)); dt.Columns.Add("Name", typeof(string)); for (int i = 0; i < 5; i++) { dt.Rows.Add(i, "Parent" + i); } this.radGridView1.MasterTemplate.DataSource = dt; this.radGridView1.MasterTemplate.AutoSizeColumnsMode = Telerik.WinControls.UI.GridViewAutoSizeColumnsMode.Fill; //child level 1 GridViewTemplate template = new GridViewTemplate(); template.DataSource = GetData(5, 20, 0, 5); template.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill; radGridView1.MasterTemplate.Templates.Add(template); GridViewRelation relation = new GridViewRelation(radGridView1.MasterTemplate); relation.ChildTemplate = template; relation.RelationName = "ParentChild"; relation.ParentColumnNames.Add("Id"); relation.ChildColumnNames.Add("ParentId"); radGridView1.Relations.Add(relation); //child level 2 GridViewTemplate template2 = new GridViewTemplate(); template2.DataSource = GetData(20, 40, 5, 20); template2.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill; template.Templates.Add(template2); GridViewRelation relation2 = new GridViewRelation(template); relation2.ChildTemplate = template2; relation2.RelationName = "ParentChild"; relation2.ParentColumnNames.Add("Id"); relation2.ChildColumnNames.Add("ParentId"); radGridView1.Relations.Add(relation2); //child level 3 GridViewTemplate template3 = new GridViewTemplate(); template3.DataSource = GetData(40, 100, 20, 40); template3.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill; template2.Templates.Add(template3); GridViewRelation relation3 = new GridViewRelation(template2); relation3.ChildTemplate = template3; relation3.RelationName = "ParentChild"; relation3.ParentColumnNames.Add("Id"); relation3.ChildColumnNames.Add("ParentId"); radGridView1.Relations.Add(relation3); //child level 4 GridViewTemplate template4 = new GridViewTemplate(); template4.DataSource = GetData(100, 200, 40, 100); template4.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill; template3.Templates.Add(template4); GridViewRelation relation4 = new GridViewRelation(template3); relation4.ChildTemplate = template4; relation4.RelationName = "ParentChild"; relation4.ParentColumnNames.Add("Id"); relation4.ChildColumnNames.Add("ParentId"); radGridView1.Relations.Add(relation4); } private object GetData(int from, int to, int parentFrom, int parentTo) { DataTable dt = new DataTable(); dt.Columns.Add("Id", typeof(int)); dt.Columns.Add("Name", typeof(string)); dt.Columns.Add("ParentId", typeof(int)); Random rand = new Random(); for (int i = from; i < to; i++) { dt.Rows.Add(i, "Child" + i, rand.Next(parentFrom, parentTo)); } return dt; } private void radButton1_Click(object sender, EventArgs e) { string s = "default.xml"; SaveFileDialog dialog = new SaveFileDialog(); dialog.Filter = "xml files (*.xml)|*.xml|All files (*.*)|*.*"; dialog.Title = "Select a xml file"; if (dialog.ShowDialog() == DialogResult.OK) { s = dialog.FileName; } this.radGridView1.SaveLayout(s); } private void radButton2_Click(object sender, EventArgs e) { string s = "default.xml"; OpenFileDialog dialog = new OpenFileDialog(); dialog.Filter = "xml files (*.xml)|*.xml|All files (*.*)|*.*"; dialog.Title = "Select a xml file"; if (dialog.ShowDialog() == DialogResult.OK) { s = dialog.FileName; } this.radGridView1.LoadLayout(s); } Workaround: grid templates for the inner levels are recreated after loading the layout. Their DataSource is null and the existing relations points to the old templates. Clear the relations and setup them again with the new child template instances.
How can I enter the Value "" (empty string) in the traditional filter system (not Excel like filter).
The grid does not seem to accept an empty string as an argument to "Equals" through the UI.
Ideally I would like to extend the standard filter menu in traditional filtering (and the filter operator drop down in custom filtering dialog) to contain operators "Is Empty" "Is Not Empty" and "Is Null Or Empty", "Is Not Null And Not Empty"
Regards
Erwin
To reproduce: Add a RadGridView and use the following code. When you expand the first row, the vertical scrollbar is not correct. Scrolling down changes its size. However, if you expand the last row, it takes few seconds to open. Second scenario: In addition of the following code, if you change the TableElement.PageViewMode to PageViewMode.ExplorerBar, expanding the first row takes few seconds to load the hierarchical data as well. public partial class Form1 : Form { public Form1() { InitializeComponent(); List<Item> items = new List<Item>(); List<SubItem> subItems = new List<SubItem>(); for (int i = 1; i <= 3; i++) { Item item = new Item(i, "Item" + i); for (int j = 1000; j <= 2010; j++) { subItems.Add(new SubItem(j, "SubItem" + j, i)); } items.Add(item); } this.radGridView1.DataSource = items; this.radGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill; GridViewTemplate template = new GridViewTemplate(); template.ReadOnly = true; template.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill; GridViewRelation relation = new GridViewRelation(this.radGridView1.MasterTemplate, template); relation.ParentColumnNames.Add("Id"); relation.ChildColumnNames.Add("ItemId"); this.radGridView1.MasterTemplate.Templates.Add(template); this.radGridView1.Relations.Add(relation); template.DataSource = subItems; } } public class Item { public int Id { get; set; } public string Title { get; set; } public Item(int id, string title) { this.Id = id; this.Title = title; } } public class SubItem { public int Id { get; set; } public int ItemId { get; set; } public string Name { get; set; } public SubItem(int id, string name, int itemId) { this.Id = id; this.ItemId = itemId; this.Name = name; } }
Improve RadGridViewDragDropService extensibility to perform visual drop indication over RadTreeView.
When the pencil icon is clicked the RowValidating event must be fired. WORKAROUND: 1. When clicking the "pencil" icon, the current row is not changed, thus the RowValidating is not fired. A suitable event to cover this case is the CellValidating event which will be triggered when the "pencil" icon is clicked. 2. When the pencil is clicked, save the grid's CurrentRow, set it to null and then set it back to the saved row. This will trigger the RowValidating event and the desired logic will be executed. The downside of this approach is that the event will be triggered twice, because we change the CurrentRow twice. void radGridView1_MouseDown(object sender, MouseEventArgs e) { GridRowHeaderCellElement rowHeader = radGridView1.ElementTree.GetElementAtPoint(e.Location) as GridRowHeaderCellElement; if (rowHeader != null) { GridViewRowInfo saveRow = radGridView1.CurrentRow; radGridView1.CurrentRow = null; radGridView1.CurrentRow = saveRow; } }
The specified format in the DisplayFormat attribute should be considered when automatically generating the GridViewDateTimeColumn. public RadForm1() { InitializeComponent(); List<Item> items = new List<Item>(); for (int i = 0; i < 5; i++) { items.Add(new Item(DateTime.Now.AddDays(i))); } this.radGridView1.DataSource = items; this.radGridView1.AutoSizeColumnsMode = Telerik.WinControls.UI.GridViewAutoSizeColumnsMode.Fill; } public class Item { [System.ComponentModel.DisplayName("My Date")] [System.ComponentModel.DataAnnotations.DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")] public DateTime Date { get; set; } public Item(DateTime date) { this.Date = date; } }
To reproduce: please refer to the attached sample project. Note that the CellValidating event is fired twice even without showing a RadMessageBox. With an MS Button the problem is not reproducible. Workaround: use the RadGridView.ValueChanging event to perform validation while the user is typing in the active editor: private void radGridView1_ValueChanging(object sender, Telerik.WinControls.UI.ValueChangingEventArgs e) { if (((string)e.NewValue) != "x") { RadMessageBox.Show("Only 'x' allowed!"); e.Cancel = true; } }
Repeat the master template headers right after the end of an expanded detail template. The purpose is clarity for the end user.