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.
How to reproduce: public partial class Form1 : Form { public Form1() { InitializeComponent(); this.radGridView1.DataSource = this.GetData(); this.radGridView1.EditorRequired += RadGridView1_EditorRequired; } private void RadGridView1_EditorRequired(object sender, EditorRequiredEventArgs e) { if (this.radGridView1.CurrentColumn.Index == 0) { e.Editor = new RadTimePickerElement(); } } private DataTable GetData() { DataTable dt = new DataTable(); dt.Columns.Add("Date", typeof(DateTime)); for (int i = 0; i < 20; i++) { DataRow r = dt.NewRow(); dt.Rows.Add(r); } return dt; } } Workaround: the scenario is not completely valid as when handling the EditorRequiredEvent one should use the GridTimePickerEditor 1. Use the column`s EditorType property: ((GridViewDateTimeColumn)this.radGridView1.Columns["Date"]).EditorType = GridViewDateTimeEditorType.TimePicker 2. Alternatively, handle the event this way: private void RadGridView1_EditorRequired(object sender, EditorRequiredEventArgs e) { if (this.radGridView1.CurrentColumn.Index == 0) { e.Editor = new GridTimePickerEditor(); } }
Use attached to reproduce. - Check the filter box - Uncheck the header checkbox. - The cells are still visible and you cannot click on the data check boxes.
Use attached to reproduce. Workaround: class MyDataCellElement : GridDataCellElement { public MyDataCellElement(GridViewColumn col, GridRowElement row) : base(col,row) { } protected override List<CharacterRange> GetSearchHighlightRanges() { // return base.GetSearchHighlightRanges(); List<CharacterRange> ranges = new List<CharacterRange>(); if (this.ColumnInfo == null || !this.RowInfo.SearchCache.Contains(this.ColumnInfo)) { return ranges; } string criteria = this.RowInfo.SearchCache[this.ColumnInfo] as string; int index = -1; CompareOptions options; if (this.MasterTemplate.MasterViewInfo.TableSearchRow.CaseSensitive) { options = CompareOptions.Ordinal; } else { options = this.MasterTemplate.MasterViewInfo.TableSearchRow.CompareOptions; } do { if (index + 1 >= this.Text.Length) { break; } index = this.MasterTemplate.MasterViewInfo.TableSearchRow.Culture.CompareInfo.IndexOf(this.Text, criteria, index + 1, options); if (index >= 0) { var str = this.Text.Substring(index, criteria.Length); int symbolCount = 0; foreach (char ch in str) { if (!Char.IsLetterOrDigit(ch)) { symbolCount++; } } ranges.Add(new CharacterRange(index, criteria.Length + symbolCount)); } } while (index >= 0 && ranges.Count < 32); return ranges; } } private void MasterTemplate_CreateCell(object sender, GridViewCreateCellEventArgs e) { if (e.CellType == typeof(GridDataCellElement)) { e.CellElement = new MyDataCellElement(e.Column, e.Row); } }
To reproduce: run the attached sample project and click the new row. Workaround: don't call the Begin/EndUpdate methods in the CurrentRowChanged event.
This new API will be useful for implementing custom sorting scenarios when you need to have custom sorting only for a single column. A similar API is available for the filtering functionality (MasterTemplate.DataView.FilterEvaluate)
Use attached to reproduce. This is not an issue. Performing Begin/End update disposes of all elements along with the globally declared item. You need to check if the item is disposed of: void ContextMenuOpening(object sender, ContextMenuOpeningEventArgs e) { if (menuItem.IsDisposed) { menuItem = new RadMenuItem(); menuItem.Text = "Custom menu item"; menuItem.Click += menuItem_Click; } e.ContextMenu.Items.Add(menuItem); }
To reproduce: - Add 7-8 columns to the grid. - Set the AutoSizeColumnsMode to Fill - Set the MaxWidth/MaxWidth of the last two columns. - Resize the first column. - Sometimes the size of the other columns is randomly increased/decreased.
To reproduce: public RadForm1() { InitializeComponent(); this.radGridView1.EnableFiltering = true; this.radGridView1.ShowHeaderCellButtons = true; this.radGridView1.FilterPopupRequired += radGridView1_FilterPopupRequired; } private void radGridView1_FilterPopupRequired(object sender, Telerik.WinControls.UI.FilterPopupRequiredEventArgs e) { e.FilterPopup.PopupOpening -= FilterPopup_PopupOpening; e.FilterPopup.PopupOpening += FilterPopup_PopupOpening; } private void FilterPopup_PopupOpening(object sender, CancelEventArgs args) { args.Cancel = true; } Workaround: either set the ShowHeaderCellButtons property to false or closed the popup immediately after it is opened. private void radGridView1_FilterPopupRequired(object sender, Telerik.WinControls.UI.FilterPopupRequiredEventArgs e) { e.FilterPopup.PopupOpening -= FilterPopup_PopupOpening; e.FilterPopup.PopupOpening += FilterPopup_PopupOpening; } private void FilterPopup_PopupOpening(object sender, CancelEventArgs args) { RadListFilterPopup popup = sender as RadListFilterPopup; popup.PopupOpened -= popup_PopupOpened; popup.PopupOpened += popup_PopupOpened; } private void popup_PopupOpened(object sender, EventArgs args) { RadListFilterPopup popup = sender as RadListFilterPopup; popup.ClosePopup(RadPopupCloseReason.Mouse); }
How to reproduce: check the attached project Workaround: create a custom RadListFilterPopup public class MyRadListFilterPopup : RadListFilterPopup { public MyRadListFilterPopup(GridViewDataColumn dataColumn, bool groupedDateValues) : base(dataColumn, groupedDateValues) { } protected override void OnButtonOkClick(EventArgs e) { FilterOperator filterOperator = FilterOperator.IsEqualTo; IRadListFilterElement listFilterElement = (IRadListFilterElement)typeof(RadListFilterPopup).GetField("listFilterElement", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(this); RadListFilterDistinctValuesTable selectedValues = listFilterElement.SelectedValues; switch (listFilterElement.SelectedMode) { case ListFilterSelectedMode.All: filterOperator = FilterOperator.None; break; case ListFilterSelectedMode.Null: filterOperator = FilterOperator.IsNull; break; case ListFilterSelectedMode.NotNull: filterOperator = FilterOperator.IsNotNull; break; } if (filterOperator != FilterOperator.IsEqualTo) { SetFilterOperator(filterOperator); this.ClosePopup(RadPopupCloseReason.CloseCalled); } else { CompositeFilterDescriptor compositeFilterDescriptor = new CompositeFilterDescriptor(); compositeFilterDescriptor.PropertyName = this.DataColumn.Name; RadListFilterDistinctValuesTable distinctValues = this.GetDistinctValuesTable(); string blanksKey = RadGridLocalizationProvider.CurrentProvider.GetLocalizedString(RadGridStringId.FilterMenuBlanks); bool blanks = selectedValues.Contains(blanksKey); if (selectedValues.Count > distinctValues.Count / 2 && !blanks) { compositeFilterDescriptor.LogicalOperator = FilterLogicalOperator.And; foreach (DictionaryEntry entry in distinctValues) { string key = (string)entry.Key; if (string.IsNullOrEmpty(key)) { key = blanksKey; } if (!selectedValues.Contains(key)) { foreach (object value in (ArrayList)entry.Value) { FilterDescriptor descriptor; if (value == DBNull.Value) { descriptor = new FilterDescriptor(this.DataColumn.Name, FilterOperator.IsNotEqualTo, null); } else if (this.DataColumn is GridViewDateTimeColumn || this.DataColumn.DataType == typeof(DateTime) || this.DataColumn.DataType == typeof(DateTime?)) { descriptor = new DateFilterDescriptor(this.DataColumn.Name, FilterOperator.IsNotEqualTo, (DateTime?)value, false); } else { descriptor = new FilterDescriptor(this.DataColumn.Name, FilterOperator.IsNotEqualTo, value); } compositeFilterDescriptor.FilterDescriptors.Add(descriptor); } } } } else { compositeFilterDescriptor.LogicalOperator = FilterLogicalOperator.Or; foreach (DictionaryEntry entry in selectedValues) { foreach (object value in (ArrayList)entry.Value) { FilterDescriptor descriptor; if (value == DBNull.Value) { descriptor = new FilterDescriptor(this.DataColumn.Name, FilterOperator.IsNotEqualTo, null); } else if (this.DataColumn is GridViewDateTimeColumn || this.DataColumn.DataType == typeof(DateTime) || this.DataColumn.DataType == typeof(DateTime?)) { descriptor = new DateFilterDescriptor(this.DataColumn.Name, FilterOperator.IsEqualTo, (DateTime?)value, false); } else { descriptor = new FilterDescriptor(this.DataColumn.Name, FilterOperator.IsEqualTo, value); } compositeFilterDescriptor.FilterDescriptors.Add(descriptor); } } } this.FilterDescriptor = compositeFilterDescriptor; OnFilterConfirmed(); } } }
To reproduce: we have a RadPageView with two grids on two pages. The first grid has a ColumnGroupsViewDefinition applied. When you open the Property Builder and try to hide some of the columns, the error occurs. Workaround: make the changes programamtically at run time.
By default, when I am expanding a group and start sorting, the expanded group doesn't collapse. However, if you use a group comparer, all groups will always collapse, when you click a header cell to sort.
To reproduce: 1. Add a GridViewCheckBoxColumn with EnableHeaderCheckBox property set to true. 2. Use the TypeConverter demonstrated in the following help article: http://docs.telerik.com/devtools/winforms/gridview/columns/converting-data-types When you run the application and try to toggle the check box in the header cell, a FormatException occurs. Workaround: modify the TypeConverter: public class ToggleStateConverter : TypeConverter { public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { return destinationType == typeof(ToggleState); } public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { char charValue = (char)value; switch (charValue) { case 'Y': return ToggleState.On; case 'N': return ToggleState.Off; case 'M': return ToggleState.Indeterminate; } return base.ConvertTo(context, culture, value, destinationType); } public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) { return sourceType == typeof(ToggleState) || sourceType == typeof(bool); } public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { ToggleState state; bool boolValue; if (value is ToggleState) { state = (ToggleState)value ; switch (state) { case ToggleState.On: return 'Y'; case ToggleState.Off: return 'N'; case ToggleState.Indeterminate: return 'M'; } } else if (value is bool) { boolValue = (bool)value; switch (boolValue) { case true: return 'Y'; case false: return 'N'; default: return 'M'; } } return base.ConvertFrom(context, culture, value); } }
Currently, DisplayFormatType.GeneralDate, DisplayFormatType.ShortDate, DisplayFormatType.MediumDate all return culture's DateTimeFormat.ShortDatePattern. Workaround: GridViewDateTimeColumn columnDateTime = this.radGridView1.Columns["Date"] as GridViewDateTimeColumn; columnDateTime.ExcelExportType = DisplayFormatType.Custom; columnDateTime.ExcelExportFormatString = "dd/MM/yyyy hh:mm:ss";
To reproduce: bind the grid to a DataTable where one of the columns doesn't allow null values. Try to add a new record by using the new row in the grid. Even though you specify default values in the DefaultValuesNeeded event, the error still occurs. Please refer to the attached sample project and gif file. Workaround: handle the RadGridView.DataError event: private void RadGridView1_DataError(object sender, Telerik.WinControls.UI.GridViewDataErrorEventArgs e) { if (e.Exception.ToString().Contains("does not allow nulls")) { e.Cancel = true; } }
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.
How to reproduce: public partial class Form1 : Form { private DataTable dt = new DataTable(); public Form1() { InitializeComponent(); this.FillData(); this.radGridView1.DataSource = this.dt; this.radGridView1.EnableSorting = true; this.radGridView1.EnableFiltering = true; this.radGridView1.MasterTemplate.DataView.BypassSort = true; this.radGridView1.SortChanged += radGridView1_SortChanged; this.radGridView1.AutoSizeColumnsMode = Telerik.WinControls.UI.GridViewAutoSizeColumnsMode.Fill; } public void FillData() { dt.Columns.Add("Id", typeof(int)); dt.Columns.Add("Name", typeof(string)); for (int i = 0; i < 30; i++) { dt.Rows.Add(i, "Item" + i); } } private void radGridView1_SortChanged(object sender, Telerik.WinControls.UI.GridViewCollectionChangedEventArgs e) { if (e.Action == NotifyCollectionChangedAction.Add || e.Action == NotifyCollectionChangedAction.ItemChanged) { SortDescriptor s = e.NewItems[0] as SortDescriptor; string sortOperator = ""; if (s.Direction == ListSortDirection.Ascending) { sortOperator = "ASC"; } else { sortOperator = "DESC"; } dt.DefaultView.Sort = s.PropertyName + " " + sortOperator; } if (e.Action == NotifyCollectionChangedAction.Remove) { dt.DefaultView.Sort = ""; } } } Workaround: public partial class Form1 : Form { private DataTable dt = new DataTable(); public Form1() { InitializeComponent(); this.FillData(); this.radGridView1.DataSource = this.dt; this.radGridView1.EnableSorting = true; this.radGridView1.EnableFiltering = true; this.radGridView1.MasterTemplate.DataView.BypassSort = true; this.radGridView1.AutoSizeColumnsMode = Telerik.WinControls.UI.GridViewAutoSizeColumnsMode.Fill; this.radGridView1.CellBeginEdit += RadGridView1_CellBeginEdit; this.radGridView1.CellEndEdit += RadGridView1_CellEndEdit; } private void RadGridView1_CellEndEdit(object sender, GridViewCellEventArgs e) { if (e.Row is GridViewFilteringRowInfo) { this.radGridView1.MasterTemplate.DataView.BypassSort = true; } } private void RadGridView1_CellBeginEdit(object sender, Telerik.WinControls.UI.GridViewCellCancelEventArgs e) { if (e.Row is GridViewFilteringRowInfo) { this.radGridView1.MasterTemplate.DataView.BypassSort = false; } } public void FillData() { dt.Columns.Add("Id", typeof(int)); dt.Columns.Add("Name", typeof(string)); for (int i = 0; i < 30; i++) { dt.Rows.Add(i, "Item" + i); } } }