A user should be able to disable executing any of the cut/copy/paste (ctrl+x, ctrl+c, ctrl+v) commands.
Steps to reproduce: 1. Add a RadGridView to a form and fill it with data so there would be a vertical scroll bar 2. Set AutoSizeRows to true 3. Run the project and call RadGridView.PrintPreview() method 4. You will see that only the rows that are visible in the RadGirdView or have been scrolled to will have a correct height.
If you set the MinWidth and MaxWidth to a column and then set AutoSizeColumnMode to Fill (all this in the form constructor) a gap will appear between the columns. Workaround: set the Fill before the MinWidth and MaxWidth and to do all these operations on Load.
The row's MaxHeight property does not affect the row sizing when the AutoSizeRows property of RadGridView is enabled. Workaround: Use the following data row: public class MyGridDataRowElement : GridDataRowElement { protected override Type ThemeEffectiveType { get { return typeof(GridDataRowElement); } } protected override System.Drawing.SizeF MeasureCore(System.Drawing.SizeF availableSize) { float maxHeight = this.RowInfo.MaxHeight; bool isAutoSize = this.GridViewElement.AutoSize && this.RowInfo.MaxHeight > 0 && availableSize.Height == float.PositiveInfinity; SizeF size = base.MeasureCore(availableSize); if (isAutoSize && size.Height > maxHeight) { availableSize.Height = maxHeight; size = base.MeasureCore(availableSize); } return size; } } here is how to replace it and set the max height: void radGridView1_RowFormatting(object sender, RowFormattingEventArgs e) { e.RowElement.RowInfo.MaxHeight = 32; } void radGridView1_CreateRow(object sender, GridViewCreateRowEventArgs e) { if (e.RowType == typeof(GridDataRowElement)) { e.RowType = typeof(MyGridDataRowElement); } }
The performance of excel-like filtering when you have more than 5000+ row in RadGridView.
ADD. RadGridView should support filtering operations when custom TypeConverters are used.
IMPROVE. RadGridView - add ability to change and customize the font (bold, italic, etc) in the ConditionalFormattingForm
Currently sub-property binding is supported in the MasterTemplate of the grid (level 1). We should make this functionality available in lower levels when users are creating an object relational hierarchy.
Steps to reproduce: 1. Use the RadGridView Smart Tag to set its data source 2. Press "Add Project DataSource" 3. Select "Object" 4. Drill down and select the class you created. (see below) 5. Select the New Data Source 6. Run the project Code to reproduce: public class TestClass { public enum Month { January, Febuary, March, April, May, June, July, August, September, October, November, December } public Month TestMonth {get; set;} public String TestMessage {get; set;} public TestClass(Month month, String message) { TestMonth = month; TestMessage = message; } } Workaround: Use BindingList instead System.Windows.Forms.BindingSource.
Add support for the GridViewComboBoxColumn to initialize properly when the BindingList it is bound to is empty.
After a couple clicks, grid's context menu becomes unresponsive when using RadGridView through remote connection and Windows 7
Customize the default DateTime filtering in order to allow scenarios, when the end users enters both date and time part, or only time and filter is applied based on the chosen criteria.
Currently, if there are not enough rows to fill the height of RadGridView control, the pinned row will appear right after the last row. It will be good to facilitate customization that sets the pinned row to appear at the bottom of the grid. Same logic holds for summary rows and columns. Workaround: public Form1() { InitializeComponent(); DataTable dt = new DataTable(); dt.Columns.Add("Id"); dt.Columns.Add("Name"); for (int i = 0; i < 5; i++) { dt.Rows.Add(i, "Item" + i); } this.radGridView1.DataSource = dt; this.radGridView1.AutoSizeColumnsMode = Telerik.WinControls.UI.GridViewAutoSizeColumnsMode.Fill; this.radGridView1.AllowSearchRow = true; this.radGridView1.SearchRowPosition = Telerik.WinControls.UI.SystemRowPosition.Bottom; this.radGridView1.ViewDefinition = new CustomTableViewDefition(); } public class CustomTableViewDefition : TableViewDefinition { public override IRowView CreateViewUIElement(GridViewInfo viewInfo) { return new CustomTableElement(); } } public class CustomTableElement : GridTableElement { protected override RowsContainerElement CreateViewElement() { return new CustomRowsContainerElement(); } } public class CustomRowsContainerElement : RowsContainerElement { protected override SizeF ArrangeOverride(SizeF finalSize) { float y = 0; this.TopPinnedRows.Arrange(new RectangleF(0, y, finalSize.Width, this.TopPinnedRows.DesiredSize.Height)); y += this.TopPinnedRows.DesiredSize.Height + ElementSpacing; this.ScrollableRows.Arrange(new RectangleF(0, y, finalSize.Width, this.ScrollableRows.DesiredSize.Height)); y += this.ScrollableRows.DesiredSize.Height + ElementSpacing; this.BottomPinnedRows.Arrange(new RectangleF(0, finalSize.Height - this.BottomPinnedRows.DesiredSize.Height, finalSize.Width, this.BottomPinnedRows.DesiredSize.Height)); return finalSize; } }
The GroupRow Height cannot be changed when ColumnGroupsViewDefinition and HtmlViewDefinition are used.
1. Create a new project with RadGridView and set MultiSelect to true and SelectionMode to CellSelect. 2. Run the project. 3. Use the mouse to select some cells and scroll down while selecting. 4. Remove some cells from the selection. 5. Scroll with the scrollbar up to the first selected cells. You will see that all previously selected cells which are not visible are not selected. Workaround: Use the following custom behavior: public class MyGridRowBehavior : GridDataRowBehavior { private FieldInfo oldCurrentLocationFieldInfo; private Point oldCurrentLocation { get { if (this.oldCurrentLocationFieldInfo == null) { this.oldCurrentLocationFieldInfo = typeof(GridRowBehavior).GetField("oldCurrentLocation", BindingFlags.Instance | BindingFlags.NonPublic); } return (Point)this.oldCurrentLocationFieldInfo.GetValue(this); } set { this.oldCurrentLocationFieldInfo.SetValue(this, value); } } private MethodInfo selectIntersectedCellsMethodInfo; private delegate void SelectIntersectedCellsDelegate(RadElementCollection rows, bool isProcessedShiftOrControl); private SelectIntersectedCellsDelegate SelectIntersectedCellsCore; private void SelectIntersectedCells(RadElementCollection rows, bool isProcessedShiftOrControl) { if (this.selectIntersectedCellsMethodInfo == null) { this.selectIntersectedCellsMethodInfo = typeof(GridRowBehavior).GetMethods(BindingFlags.Instance | BindingFlags.NonPublic).First(x => x.Name == "SelectIntersectedCells" && x.GetParameters().Length == 2); this.SelectIntersectedCellsCore = (SelectIntersectedCellsDelegate)Delegate.CreateDelegate(typeof(SelectIntersectedCellsDelegate), this, this.selectIntersectedCellsMethodInfo); } this.SelectIntersectedCellsCore(rows, isProcessedShiftOrControl); } private MethodInfo selectIntersectedRowsMethodInfo; private delegate bool SelectIntersectedRowsDelegate(RadElementCollection rows); private SelectIntersectedRowsDelegate SelectIntersectedRowsCore; private bool SelectIntersectedRows(RadElementCollection rows) { if (this.selectIntersectedRowsMethodInfo == null) { this.selectIntersectedRowsMethodInfo = typeof(GridRowBehavior).GetMethod("SelectIntersectedRows", BindingFlags.Instance | BindingFlags.NonPublic); this.SelectIntersectedRowsCore = (SelectIntersectedRowsDelegate)Delegate.CreateDelegate(typeof(SelectIntersectedRowsDelegate), this, this.selectIntersectedRowsMethodInfo); } return this.SelectIntersectedRowsCore(rows); } protected override bool ProcessMouseSelection(Point mousePosition, GridCellElement currentCell) { if (this.RootGridBehavior.LockedBehavior != this) { this.GridControl.Capture = true; this.RootGridBehavior.LockBehavior(this); } GridCellElement mouseDownCell = this.GetCellAtPoint(this.MouseDownLocation); GridCellElement oldCurrentCell = this.GetCellAtPoint(this.oldCurrentLocation); bool isValidResizingContext = this.ResizeSelectionRectangle(currentCell, mousePosition); bool result = false; if (isValidResizingContext && oldCurrentCell != currentCell) { if (this.MasterTemplate.MultiSelect && !this.GridViewElement.Template.AllowRowReorder) { if (this.MasterTemplate.SelectionMode == GridViewSelectionMode.FullRowSelect) { bool selectedRowsChanged = false; bool isPressedShiftOrControl = (this.IsPressedShift || this.IsPressedControl); GridTableElement tableElement = this.GridViewElement.CurrentView as GridTableElement; RadElementCollection scrollableRows = tableElement.ViewElement.ScrollableRows.Children; RadElementCollection topPinnedRows = tableElement.ViewElement.TopPinnedRows.Children; RadElementCollection bottomPinnedRows = tableElement.ViewElement.BottomPinnedRows.Children; GridViewRowInfo[] selectedRows = this.MasterTemplate.SelectedRows.ToArray(); tableElement.BeginUpdate(); int oldSelectedRows = this.MasterTemplate.SelectedRows.Count; if (!isPressedShiftOrControl) { for (int i = selectedRows.Length - 1; i >= 0; i--) { GridViewRowInfo rowInfo = selectedRows[i]; GridRowElement rowElement = tableElement.GetRowElement(rowInfo); bool select = rowElement != null && rowElement.ControlBoundingRectangle.IntersectsWith(this.GridViewElement.SelectionRectangle); if (select) { rowInfo.IsSelected = true; } if (!rowInfo.IsSelected) { selectedRowsChanged = true; } } } selectedRowsChanged = this.SelectIntersectedRows(topPinnedRows); selectedRowsChanged |= this.SelectIntersectedRows(scrollableRows); selectedRowsChanged |= this.SelectIntersectedRows(bottomPinnedRows); if (oldSelectedRows != this.MasterTemplate.SelectedRows.Count) { selectedRowsChanged = true; } tableElement.EndUpdate(false); } else { GridTableElement tableElement = this.GridViewElement.CurrentView as GridTableElement; if (tableElement == null) { return result; } CancelEventArgs cancelArgs = new CancelEventArgs(); this.MasterTemplate.EventDispatcher.RaiseEvent<CancelEventArgs>(EventDispatcher.SelectionChanging, this, cancelArgs); if (cancelArgs.Cancel) { return result; } //Since version Q2 2014 (version 2014.2.617), please use: //GridViewSelectionCancelEventArgs cancelArgs = new GridViewSelectionCancelEventArgs(this.MasterTemplate.CurrentRow, this.MasterTemplate.CurrentColumn); //this.MasterTemplate.EventDispatcher.RaiseEvent<GridViewSelectionCancelEventArgs>(EventDispatcher.SelectionChanging, this, cancelArgs); //if (cancelArgs.Cancel) //{ // return result; //} this.GridViewElement.CurrentView.BeginUpdate(); bool isProcessedShiftOrControl = (this.IsPressedShift || this.IsPressedControl); int count = this.MasterTemplate.SelectedCells.Count; RadElementCollection scrollableRows = tableElement.ViewElement.ScrollableRows.Children; RadElementCollection topPinnedRows = tableElement.ViewElement.TopPinnedRows.Children; RadElementCollection bottomPinnedRows = tableElement.ViewElement.BottomPinnedRows.Children; this.SelectIntersectedCells(scrollableRows, isProcessedShiftOrControl); this.SelectIntersectedCells(topPinnedRows, isProcessedShiftOrControl); this.SelectIntersectedCells(bottomPinnedRows, isProcessedShiftOrControl); bool notifyUpdates = true; if (isProcessedShiftOrControl) { notifyUpdates = count != this.MasterTemplate.SelectedCells.Count; } this.GridViewElement.CurrentView.EndUpdate(false); this.GridViewElement.Invalidate(); } result = true; } result = false; } this.oldCurrentLocation = mousePosition; return result; } } Register the new behavior as follows: BaseGridBehavior behavior = (BaseGridBehavior)this.radGridView1.GridBehavior; behavior.UnregisterBehavior(typeof(GridViewDataRowInfo)); behavior.RegisterBehavior(typeof(GridViewDataRowInfo), new MyGridRowBehavior());
Presently it is not possible to persist customer created formatting objects in RadGridView.
debug attached sample application steps: set number of rows to 500 change to 2nd page change to 1st page set number of rows to 0 change to 2nd page
FIX. RadGridView - the PropertyName from the arguments of the RowsChanged event is null, while it should display the changed field name
To reproduce, use the following localization provider and set a fitler to a boolean column in RadGridView, via the Custom filtering dialog. class MyRadGridLocalizationProvider : RadGridLocalizationProvider { public const string CustomTrue = "CustomTRUE"; public const string CustomFalse = "CustomFALSE"; public override string GetLocalizedString(string id) { if (id == "CustomFilterDialogTrue") { return CustomTrue; } else if (id == "CustomFilterDialogFalse") { return CustomFalse; } else { return base.GetLocalizedString(id); } } } Workaround - create custom type converter as follows: public class MyBooleanConverter : BooleanConverter { public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) { if (value is string) { string text = Convert.ToString(value); if (text == MyRadGridLocalizationProvider.CustomTrue) { return true; } else if (text == MyRadGridLocalizationProvider.CustomFalse) { return false; } } return base.ConvertFrom(context, culture, value); } } and apply it to the check box column: radGridView1.Columns["BoolColumn"].DataTypeConverter = new MyBooleanConverter();