To reproduce: Create a self reference RadGridView and add enough columns so that a horizontal scrollbar appears. Scroll the horizontal scrollbar to the right and close the form. You will see an exception. Workaround: Create a custom row element in the CreateRow event: void radGridView1_CreateRow(object sender, Telerik.WinControls.UI.GridViewCreateRowEventArgs e) { if (e.RowInfo is GridViewHierarchyRowInfo || e.RowInfo is GridViewDataRowInfo) { e.RowElement = new MyDataRowElement(); } } public class MyLayout : SelfReferenceCellLayout { public MyLayout(GridRowElement rowElement) : base(rowElement) { } public override void DetachCellElements() { if (this.StackLayoutElement != null) { base.DetachCellElements(); } } } public class MyDataRowElement : GridDataRowElement { private MyLayout cellReferenceLayout; public override void Detach() { base.Detach(); if (this.cellReferenceLayout != null) { this.cellReferenceLayout.DetachCellElements(); } } protected override void DisposeManagedResources() { if (this.cellReferenceLayout != null) { this.cellReferenceLayout.Dispose(); } base.DisposeManagedResources(); } public override SelfReferenceCellLayout SelfReferenceLayout { get { if (this.RowInfo is GridViewHierarchyRowInfo) { if (this.ViewTemplate != null && this.ViewTemplate.IsSelfReference && this.cellReferenceLayout == null) { this.cellReferenceLayout = new MyLayout(this); } return this.cellReferenceLayout; } return null; } } protected override Type ThemeEffectiveType { get { return typeof(GridDataRowElement); } } }
To reproduce: public Form1() { InitializeComponent(); radGridView1.Columns.Add("Id"); radGridView1.Columns.Add("ParentID"); radGridView1.Columns.Add("Name"); radGridView1.Relations.AddSelfReference(radGridView1.MasterTemplate, "Id", "ParentID"); for (int id = 1; id <= 3; id++) { radGridView1.MasterTemplate.Rows.Add(id, 0, "Node_" + id); for (int iChild = 1; iChild <= 5; iChild++) { int childId = id * 100 + iChild; radGridView1.MasterTemplate.Rows.Add(childId, id, "ChildNode_" + childId); } } foreach (GridViewHierarchyRowInfo row in this.radGridView1.Rows) { row.IsExpanded = true; } }
Workaround: the MasterTemplate has Copy method, which allows overriding in its descendants. Thus, it is possible to modify the copied data according to the specific requirements: public class CustomGrid : RadGridView { protected override RadGridViewElement CreateGridViewElement() { return new CustomRadGridViewElement(); } public override string ThemeClassName { get { return typeof(RadGridView).FullName; } } } public class CustomRadGridViewElement : RadGridViewElement { protected override MasterGridViewTemplate CreateTemplate() { return new CustomMasterGridViewTemplate(); } protected override Type ThemeEffectiveType { get { return typeof(RadGridViewElement); } } } public class CustomMasterGridViewTemplate : MasterGridViewTemplate { public override void Copy() { base.Copy(); if (Clipboard.ContainsData(DataFormats.Text)) { string data = Clipboard.GetData(DataFormats.Text).ToString(); if (data != string.Empty) { StringBuilder sb = new StringBuilder(data); //modify the copied data and replace it in the clipboard Clipboard.SetData(DataFormats.Text, sb.ToString()); } } } }
To reproduce: - Add grid with enabled paging and filtering to a blank form. - Select the second page and apply a filter.
To reproduce: add a RadGridView and bind it to the Northwind.Products data table. Use the following code: private void Form1_Load(object sender, EventArgs e) { this.productsTableAdapter.Fill(this.nwindDataSet.Products); RadMessageBox.Show(string.Format("TOTAL2 = {0}", NewExpression())); } public string NewExpression() { this.radGridView1.Columns.Add(new GridViewDecimalColumn("TOTAL1") { Expression = "ReorderLevel + UnitsOnOrder" }); this.radGridView1.Columns.Add(new GridViewDecimalColumn("TOTAL2") { Expression = "TOTAL1 + UnitPrice" }); //uncomment to get the value of "TOTAL2" // var total1 = this.radGridView1.Rows[2].Cells["TOTAL1"].Value; var total2 = this.radGridView1.Rows[2].Cells["TOTAL2"].Value; return total2.ToString(); } It is not possible to access the column value ("TOTAL2") before firstly to access the column "TOTAL1" value.
To reproduce: - Filer twice by a single column with Excel-like filtering. - The second time InvalidCastException will occur. Workaround: - Create custom columns and override the GetDistinctValues method. public class MyColumn : GridViewTextBoxColumn { protected override GridViewColumnValuesCollection GetDistinctValues() { int index = this.Index; if (index >= 0) { GridViewColumnValuesCollection distinctValues = new GridViewColumnValuesCollection(); foreach (GridViewRowInfo row in this.OwnerTemplate.Rows) { object cellValue = row.Cells[index].Value; if (!distinctValues.Contains(cellValue)) { distinctValues.Add(cellValue); } } if (distinctValues.Count > 0) { return distinctValues; } } return null; } }
To reproduce: - Add grid with a DateTime column with default value "5/1/2014"; - Start the app and press the following keys one after another: 5/1/ - You will notice that the "1" is not replaced. Please note that the similar behavior occur when the year is entered (it does not match the default one). Workaround handle the key press for such cases manually: void radGridView1_CellEditorInitialized(object sender, GridViewCellEventArgs e) { RadDateTimeEditor ed = e.ActiveEditor as RadDateTimeEditor; RadDateTimeEditorElement el = ed.EditorElement as RadDateTimeEditorElement; el.KeyPress += el_KeyPress; } private void el_KeyPress(object sender, KeyPressEventArgs e) { RadDateTimeEditorElement el = (RadDateTimeEditorElement)sender; int day = el.Value.Value.Day; int key = -1; int.TryParse(e.KeyChar.ToString(), key); RadMaskedEditBoxElement element = el.TextBoxElement.TextBoxItem.Parent as RadMaskedEditBoxElement; MaskDateTimeProvider provider = element.Provider as MaskDateTimeProvider; if (provider.SelectedItemIndex == 2) { if (key > 0 & key <= 9) { if (el.TextBoxElement.TextBoxItem.SelectionLength != 0) { if (!booKeying) { dynamic NewValue = new DateTime(el.Value.Value.Year, el.Value.Value.Month, key); el.Value = NewValue; e.Handled = true; booKeying = true; } } } } }
To reproduce: - Add a RadGridView and a button to a blank form. - Subscribe to CellValidating event from the grid and set the cancel property of the CellValidatingEventArgs to true upon some condition. - Add click event handler for the button and print a message in it. - Start the application and enter some invalid data in the grid cell, then click the button. - The code from the button's event handler is executed. Workaround use a flag to determine when to execute the corresponding button code: bool validating = false; void radGridView1_CellValidating(object sender, Telerik.WinControls.UI.CellValidatingEventArgs e) { if (e.Value.ToString().Length < 5) { e.Cancel = true; validating = true; e.Row.ErrorText = "Validation error!"; } else { validating = false; } } private void radButton1_Click(object sender, EventArgs e) { if (!validating) { Debug.WriteLine("Executed"); } }
To reproduce: - Add a grid with some columns to a blank form (the rows should not fill the entire space). - Press and hold the left mouse button, the move the mouse to the empty area of the grid. - Continue to move the mouse and you will notice the event is fired several times. Workaround: - use the CurrentCellChanged event.
Workaround: void radGridView1_PrintCellFormatting(object sender, PrintCellFormattingEventArgs e) { if (e.Column is GridViewImageColumn && e.Row is GridViewDataRowInfo) { e.PrintCell.DrawFill = true; if (radGridView1.PrintStyle.PrintAlternatingRowColor && e.Row.Index % 2 == 1) { e.PrintCell.BackColor = radGridView1.PrintStyle.AlternatingRowColor; } else { e.PrintCell.BackColor = radGridView1.PrintStyle.CellBackColor; } } }
To reproduce: -Add a RadGridView and use the following code snippet: public Form1() { InitializeComponent(); //add GridViewCheckBoxColumn with DataType to BOOL GridViewCheckBoxColumn autoTestingselectColumn = new GridViewCheckBoxColumn(); autoTestingselectColumn.DataType = typeof(bool); autoTestingselectColumn.Name = "AutomatedTestingSelectColumn"; autoTestingselectColumn.FieldName = "AutomatedTestingSelectColumn"; autoTestingselectColumn.HeaderText = "Automated Testing Select"; radGridView1.MasterTemplate.Columns.Add(autoTestingselectColumn); //add GridViewCheckBoxColumn with DataType to INT GridViewCheckBoxColumn startTestingColumn = new GridViewCheckBoxColumn(); startTestingColumn.DataType = typeof(int); startTestingColumn.Name = "StartTestingColumn"; startTestingColumn.FieldName = "StartTestingColumn"; startTestingColumn.HeaderText = "StartTesting"; radGridView1.MasterTemplate.Columns.Add(startTestingColumn); List<Item> items = new List<Item>(); for (int i = 0; i < 5; i++) { items.Add(new Item(Guid.NewGuid().ToString(),"Name"+i)); } this.radGridView1.DataSource = items; //set the AutoSizeColumnsMode property to Fill this.radGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill; } public class Item { public string UniqueIdentifier { get; set; } public string Name { get; set; } public Item(string uniqueIdentifier, string name) { this.UniqueIdentifier = uniqueIdentifier; this.Name = name; } } -Run the project. As a result 4 columns are displayed: two programmatically added and two coming from the data source. -Now open the Property Builder at design time and add a GridViewCheckBoxColumn. -Run the project. As a result, 5 columns are displayed: one added at design time, two programmatically added, two coming from the data source. -Open the Property Builder again and delete the GridViewCheckBoxColumn. -Run the project. You will notice that only two columns are displayed. The columns, coming from the data source are not generated. Workaround: delete columns using the Columns collection at design time, instead of using the property Builder.
To reproduce: - Subscribe to the following RowsChanged event handler: void radGridView1_RowsChanged(object sender, GridViewCollectionChangedEventArgs e) { if (e.Action == NotifyCollectionChangedAction.ItemChanged) { GridViewDataRowInfo updrow = (GridViewDataRowInfo)e.NewItems[0]; GridViewDataRowInfo oldrow = (GridViewDataRowInfo)e.OldItems[0]; if (updrow.Cells[2].Value != oldrow.Cells[2].Value) { Console.WriteLine(updrow.Cells[2].Value); Console.WriteLine(oldrow.Cells[2].Value); } } } - You will notice that both values are always equal. Workaround: The CellValidating event can be used instead.
By design the MinHeight property is not respected in ColumnGroupsViewDefinition. The right way to apply MinHeight in the ColumnGroupsViewDefinition is setting the GridViewColumnGroup's RowSpanProperty and GridViewColumnGroupRow's MinHeight property. For example: this.columnGroupsView = new ColumnGroupsViewDefinition(); this.columnGroupsView.ColumnGroups.Add(new GridViewColumnGroup("General") { RowSpan = 40 }); this.columnGroupsView.ColumnGroups.Add(new GridViewColumnGroup("Details") { RowSpan = 40 }); this.columnGroupsView.ColumnGroups[1].Groups.Add(new GridViewColumnGroup("Address") { RowSpan = 40 }); this.columnGroupsView.ColumnGroups[1].Groups.Add(new GridViewColumnGroup("Ime Tam") { RowSpan = 40 }); this.columnGroupsView.ColumnGroups[0].Rows.Add(new GridViewColumnGroupRow() { MinHeight = 40 }); this.columnGroupsView.ColumnGroups[0].Rows.Add(new GridViewColumnGroupRow() { MinHeight = 40 }); this.radGridView1.Columns["ContactName"].RowSpan = 40; this.columnGroupsView.ColumnGroups[0].Rows[0].Columns.Add(this.radGridView1.Columns["CustomerID"]); this.columnGroupsView.ColumnGroups[0].Rows[0].Columns.Add(this.radGridView1.Columns["ContactName"]); this.columnGroupsView.ColumnGroups[0].Rows[1].Columns.Add(this.radGridView1.Columns["CompanyName"]); this.columnGroupsView.ColumnGroups[1].Groups[0].Rows.Add(new GridViewColumnGroupRow() { MinHeight = 40 }); this.columnGroupsView.ColumnGroups[1].Groups[0].Rows[0].Columns.Add(this.radGridView1.Columns["City"]); this.columnGroupsView.ColumnGroups[1].Groups[0].Rows[0].Columns.Add(this.radGridView1.Columns["Country"]); this.columnGroupsView.ColumnGroups[1].Groups[1].Rows.Add(new GridViewColumnGroupRow() { MinHeight = 40 }); this.columnGroupsView.ColumnGroups[1].Groups[1].Rows[0].Columns.Add(this.radGridView1.Columns["Phone"]);
To reproduce: Add a RadGridView and fill it with data. Set the first column's IsVisible property to false. Right click over the row to Copy the row content and paste it in Excel. All data is in a single cell. The Clipboard content does not contain the corresponding <TABLE><TR> tags. Note: if the last columns is hidden, the line-breaks in the copied text are missing. Workaround: create custom RadGridView and replace the wrong content in the Clipboard: public class CustomGrid : RadGridView { protected override RadGridViewElement CreateGridViewElement() { return new CustomRadGridViewElement(); } } public class CustomRadGridViewElement : RadGridViewElement { protected override MasterGridViewTemplate CreateTemplate() { return new CustomMasterGridViewTemplate(); } } public class CustomMasterGridViewTemplate : MasterGridViewTemplate { public override void Copy() { base.Copy(); if (Clipboard.ContainsData(DataFormats.Html)) { string data = Clipboard.GetData(DataFormats.Html).ToString(); StringBuilder sb = new StringBuilder(data); if (!data.Contains("<TABLE>")) { int insertIndex = data.IndexOf("<TD>"); sb.Insert(insertIndex, "<TABLE><TR>"); } else if (!data.Contains("</TABLE>")) { int insertIndex = data.LastIndexOf("<TD>"); sb.Insert(insertIndex, "</TR></TABLE>"); } Clipboard.SetData(DataFormats.Html, sb.ToString()); } } }
To reproduce: - Open the examples solution in Visual Studio. - Navigate to hierarchy example. - Enable the excel like filtering for all templates. - Start the application and open the hierarchy first look example. - Add a new row in the second template. - Add such filter that only the newly added row will remain visible. - Expand the new added row and try to add new row to it.
This is not considered an issue, it is how RadGridView works. Here are more details: In order for a GridDetailViewCellElement to display a pageview instead of a single table element, either the template of the row holding it has to have more than one child template, or its ShowChildViewCaptions should be true. Once there is a page view, the tabs in it will be visible at all times, except when some of the templates has no rows and AllowAddNewRow for it is false – if it does not have any rows and the user cannot add row, it is considered that there is no need from it. If one needs to change the visibility of the tabs, this can be done in the ViewCellFormatting event: private void RadGridView1_ViewCellFormatting(object sender, CellFormattingEventArgs e) { GridDetailViewCellElement detailCell = e.CellElement as GridDetailViewCellElement; if (detailCell != null) { foreach (RadPageViewItem item in detailCell.PageViewElement.Items) { item.Visibility = Telerik.WinControls.ElementVisibility.Visible; } } }
Setting the DataSource is slower (about 1/3 times more) when ShowColumnHeaders is set to true. Workaround: Set the ShowColumnHeaders to false, then set the DataSource and restore the ShowColumnHeaders state: radGridView1.ShowColumnHeaders = false; radGridView1.DataSource = mySource; radGridView1.ShowColumnHeaders = true;
Workaround - listen for Reset of the rows collection and introduce your modification there: radGridView1.Rows.CollectionChanged += Rows_CollectionChanged; void Rows_CollectionChanged(object sender, Telerik.WinControls.Data.NotifyCollectionChangedEventArgs e) { if (e.Action == Telerik.WinControls.Data.NotifyCollectionChangedAction.Reset) { foreach (GridViewRowInfo row in radGridView1.Rows) { row.Cells[0].Value = false; } } }