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.
The event should be used to cancel copying for a single cell or override the value to be copied to the Clipboard.
To reproduce:
public Form1()
{
InitializeComponent();
List<Item> items = new List<Item>();
for (int i = 0; i < 10; i++)
{
items.Add(new Item(i,"Item" + i,Color.Red));
}
this.radGridView1.DataSource = items;
this.radGridView1.AutoSizeColumnsMode = Telerik.WinControls.UI.GridViewAutoSizeColumnsMode.Fill;
this.radGridView1.CellValidating += radGridView1_CellValidating;
}
private void radGridView1_CellValidating(object sender, Telerik.WinControls.UI.CellValidatingEventArgs e)
{
if (e.ActiveEditor != null && e.ActiveEditor is GridColorPickerEditor)
{
Color c = (Color)e.Value;
if (c == Color.Red)
{
e.Cancel = true;
Console.WriteLine("Red is not allowed!");
}
}
}
public class Item
{
public int Id { get; set; }
public string Name { get; set; }
public Color Color { get; set; }
public Item(int id, string name, Color color)
{
this.Id = id;
this.Name = name;
this.Color = color;
}
}
Steps:
1. Activate the editor for the Color cell.
2. Leave the color as it
3. Press the Enter key. The CellValidating event is fired twice.
Note: it seems that when the color text is selected, the event is fired twice.
How to reproduce:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.radGridView1.DataSource = this.GetSampleData();
this.radGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill;
this.radGridView1.EnableFiltering = true;
this.radGridView1.ShowFilteringRow = false;
this.radGridView1.ShowHeaderCellButtons = true;
}
private DataTable GetSampleData()
{
DataTable dt = new DataTable();
dt.Columns.Add("Id", typeof(double));
dt.Columns.Add("Name", typeof(string));
dt.Columns.Add("IsValid", typeof(bool));
dt.Columns.Add("Date", typeof(DateTime));
for (int i = 0; i < 115; i++)
{
dt.Rows.Add(((double)i * 5 / 7) * 3, "Name " + i, i % 2 == 0, DateTime.Now.AddDays(i));
}
return dt;
}
}
Workaround specify decimal as the type of the column in the DataTable object or clone the DataTAble object and change the type of the column:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
DataTable dt = this.GetSampleData();
DataTable dtCloned = dt.Clone();
dtCloned.Columns[0].DataType = typeof(decimal);
foreach (DataRow row in dt.Rows)
{
dtCloned.ImportRow(row);
}
this.radGridView1.DataSource = dtCloned;
this.radGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill;
this.radGridView1.EnableFiltering = true;
this.radGridView1.ShowFilteringRow = false;
this.radGridView1.ShowHeaderCellButtons = true;
}
private DataTable GetSampleData()
{
DataTable dt = new DataTable();
dt.Columns.Add("Id", typeof(double));
dt.Columns.Add("Name", typeof(string));
dt.Columns.Add("IsValid", typeof(bool));
dt.Columns.Add("Date", typeof(DateTime));
for (int i = 0; i < 115; i++)
{
dt.Rows.Add(((double)i * 5 / 7) * 3, "Name " + i, i % 2 == 0, DateTime.Now.AddDays(i));
}
return dt;
}
}
To reproduce:
- Add DateTime column and set the RowHeight to 20.
- Set the theme to Windows7.
- The text is not visible when the editor is shown.
Workaround:
private void RadGridView2_CellEditorInitialized(object sender, GridViewCellEventArgs e)
{
RadDateTimeEditor editor = e.ActiveEditor as RadDateTimeEditor;
if (editor != null)
{
var element = editor.EditorElement as RadDateTimeEditorElement;
element.Font = new Font("Segoe UI", 8, FontStyle.Regular);
element.Children[1].Visibility = ElementVisibility.Collapsed;
element.TextBoxElement.ShowBorder = false;
element.TextBoxElement.TextBoxItem.HostedControl.MinimumSize = new Size(0, 12);
}
}
Steps to reproduce: - create a winforms project - create form (normal windows form, not telerik form) - create radgridview from toolbox - right click and open property builder - select mastertemplate - set viewdefinition = columngroups view - add 3-4 columns (textbox, combobox, etc...) - click ok button at the property builder - right click on the radgridview and open the property builder - rename the name and the header text of the first column - click ok button at the property builder
To reproduce: use the following code snippet and enter in the filter row one of the row values as it is shown in the screenshot:
this.radGridView1.EnableFiltering = true;
GridViewDateTimeColumn dateTimeColumn = new GridViewDateTimeColumn("DateTimeColumn");
dateTimeColumn.Format = DateTimePickerFormat.Custom;
dateTimeColumn.CustomFormat = "dd/MM/yyyy HH:mm:ss";
radGridView1.MasterTemplate.Columns.Add(dateTimeColumn);
this.radGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill;
for (int i = 0; i < 10; i++)
{
this.radGridView1.Rows.Add(DateTime.Now.AddDays(i));
}
Workaround: custom filtering: http://docs.telerik.com/devtools/winforms/gridview/filtering/custom-filtering
To reproduce:
public class CustomGridViewCheckBoxColumn : GridViewCheckBoxColumn
{
}
CustomGridViewCheckBoxColumn col = new CustomGridViewCheckBoxColumn();
this.radGridView1.Columns.Add(col);
this.radGridView1.EnableFiltering = true;
1. Click the filter button and select "Custom"
2. Close the dialog.
Workaround:
this.radGridView1.CreateCompositeFilterDialog += radGridView1_CreateCompositeFilterDialog;
private void radGridView1_CreateCompositeFilterDialog(object sender, GridViewCreateCompositeFilterDialogEventArgs e)
{
e.Dialog = new CustomCompositeFilterForm();
}
public class CustomCompositeFilterForm : CompositeFilterForm
{
public override void Initialize(GridViewDataColumn dataColumn, FilterDescriptor filterDescriptor, bool useTypedEditors)
{
base.Initialize(dataColumn, filterDescriptor, useTypedEditors);
if (dataColumn is GridViewCheckBoxColumn)
{
RadGroupBox groupBox = this.Controls[0] as RadGroupBox;
groupBox.Controls.Remove(this.RightEditor);
groupBox.Controls.Remove(this.LeftEditor);
MethodInfo mi = typeof(CompositeFilterForm).GetMethod("InitializeCheckBoxEditors", BindingFlags.Instance | BindingFlags.NonPublic);
mi.Invoke(this, null);
}
}
}
Please refer to the attached sample project.
To reproduce: please refer to the attached sample project.
1. Edit the CommonInt property for the first child row.
2. Edit the CommonInt property for the second child row.
Workaround: Add the grid programmatically at run time.
Second Workaround:
this.radGridView1.CellValueChanged+=radGridView1_CellValueChanged;
private void radGridView1_CellValueChanged(object sender, GridViewCellEventArgs e)
{
e.Column.OwnerTemplate.Refresh(e.Column);
}
To reproduce: - Bind the grid to progress binding source at design time. - Locate GroupDescriptors in Properties and click the ellipsis button to open the GroupDescriptor Collection Editor. - Click Add and select the new item. - Select the GroupNames collection to open the SortDescriptor Collection Editor. - Click Add. - An exception is thrown and the UI freezes. Workaround: Add descriptors at runime.
To reproduce: populate the grid with data and use the code snippet below:
public Form1()
{
InitializeComponent();
this.radGridView1.EnablePaging = true;
this.radGridView1.AddNewRowPosition = Telerik.WinControls.UI.SystemRowPosition.Bottom;
}
Select the third page and click the new row at the bottom. The editor is activated as expected but the first page is made current.
Workaround: use the CellEditorInitialized event and move to the desired page
private void radGridView1_CellEditorInitialized(object sender, Telerik.WinControls.UI.GridViewCellEventArgs e)
{
if (e.Row is GridViewNewRowInfo)
{
this.radGridView1.MasterTemplate.MoveToPage(2);
}
}
To reproduce:
- Bind the grid and reset its data source in the CellValueChanged event handler.
- Start the application, click in a cell, delete the contents and right click a header cell.
- Exception is thrown.
Workaround:
class MyGridHeaderCellElement : GridHeaderCellElement
{
public MyGridHeaderCellElement(GridViewColumn col, GridRowElement row) : base(col, row)
{ }
protected override Type ThemeEffectiveType
{
get
{
return typeof(GridHeaderCellElement);
}
}
protected override void ShowContextMenu()
{
if (this.ViewTemplate != null)
{
base.ShowContextMenu();
}
}
}
private void RadGridView1_CreateCell(object sender, GridViewCreateCellEventArgs e)
{
if (e.CellType == typeof(GridHeaderCellElement))
{
e.CellType = typeof(MyGridHeaderCellElement);
}
}
To reproduce:
DataTable dt = new DataTable();
public Form1()
{
InitializeComponent();
dt.Columns.Add("Id");
dt.Columns.Add("Name");
dt.Columns.Add("Type");
for (int i = 0; i < 30; i++)
{
dt.Rows.Add(i, "Item" + i, "Type" + i % 2);
}
this.radGridView1.DataSource = dt;
this.radGridView1.AutoExpandGroups = true;
GroupDescriptor descriptor = new GroupDescriptor();
descriptor.GroupNames.Add("Type", ListSortDirection.Ascending);
this.radGridView1.GroupDescriptors.Add(descriptor);
}
private void button1_Click(object sender, EventArgs e)
{
dt.Rows.Add(30, "Item30", "Type3");
}
Workaround: set the AutoExpandGroups property to false and manually expand the groups when a new row is added.
To reproduce: please refer to the attached gif file demonstrating how to reproduce the issue with the Demo application. Workaround: use the basic filtering.
Add an ExportToXlsx option into the native RadGridView exporting. It has been done for WPF (http://docs.telerik.com/devtools/wpf/controls/radgridview/export/export-xlsx) - why not WinForms. This would avoid the pain of having to implement the export using RadSpreadProcessing.
To reproduce:
Open the attached project, select two rows and delete them.
Workaround:
private void RadGridView1_RowValidating(object sender, Telerik.WinControls.UI.RowValidatingEventArgs e)
{
if (e.RowIndex != -1)
{
}
}
To reproduce: populate RadGridView with data and use the following code snippet:
Me.RadGridView1.TableElement.TableHeaderHeight = 60
RadGridView1.PrintPreview()
Workaround:
Private Sub RadButton1_Click(sender As Object, e As EventArgs) Handles RadButton1.Click
Me.RadGridView1.TableElement.TableHeaderHeight = 60
Dim printStyle As GridPrintStyle = New GridPrintStyle(RadGridView1)
Dim renderer As CustomTableViewDefinitionPrintRenderer = New CustomTableViewDefinitionPrintRenderer(RadGridView1)
printStyle.PrintRenderer = renderer
RadGridView1.PrintStyle = printStyle
RadGridView1.PrintPreview()
End Sub
Public Class CustomTableViewDefinitionPrintRenderer
Inherits TableViewDefinitionPrintRenderer
Public Sub New(grid As RadGridView)
MyBase.New(grid)
End Sub
Private Function GetRowLayout(row As GridViewRowInfo, fitWidthMode As PrintFitWidthMode, _
hierarchyIndent As Integer, drawArea As Rectangle) As TableViewRowLayout
Dim hashKey As Integer = row.ViewTemplate.GetHashCode() + row.HierarchyLevel
Dim fi As FieldInfo = GetType(TableViewDefinitionPrintRenderer).GetField("rowLayouts", BindingFlags.NonPublic Or BindingFlags.Instance)
Dim rowLayouts As Dictionary(Of Integer, TableViewRowLayout) = fi.GetValue(Me)
If rowLayouts.ContainsKey(hashKey) Then
Return rowLayouts(hashKey)
End If
Dim table As GridTableElement = TryCast(row.ViewTemplate.ViewDefinition.CreateViewUIElement(row.ViewInfo), GridTableElement)
table.Initialize(Me.GridView.GridViewElement, row.ViewInfo)
table.RowHeight = Me.GridView.TableElement.RowHeight
table.TableHeaderHeight = Me.GridView.TableElement.TableHeaderHeight
Me.GridView.ElementTree.ApplyThemeToElement(table)
Dim rowLayout As New TableViewRowLayout()
rowLayout.Context = GridLayoutContext.Printer
rowLayout.Initialize(table)
Dim systemWidth As Integer = 0
For Each c As GridViewColumn In rowLayout.RenderColumns
If TypeOf c Is GridViewRowHeaderColumn OrElse TypeOf c Is GridViewIndentColumn Then
systemWidth += rowLayout.GetColumnWidth(c)
End If
Next
Me.GridView.BeginUpdate()
Dim mode As GridViewAutoSizeColumnsMode = rowLayout.ViewTemplate.AutoSizeColumnsMode
If fitWidthMode = PrintFitWidthMode.FitPageWidth Then
Dim state As ColumnsState = Me.SaveColumnsState(rowLayout.ViewTemplate)
rowLayout.ViewTemplate.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill
Dim groupLevel As Integer = If(row.Group IsNot Nothing, row.Group.Level + 1, 0)
rowLayout.MeasureRow(New SizeF(drawArea.Width + systemWidth - ((row.HierarchyLevel - groupLevel) * hierarchyIndent), drawArea.Height))
Me.RestoreColumnsState(state)
Else
rowLayout.ViewTemplate.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.None
rowLayout.MeasureRow(New SizeF(Me.GridView.Width, Me.GridView.Height))
End If
rowLayout.ViewTemplate.AutoSizeColumnsMode = mode
Me.GridView.EndUpdate(False)
rowLayouts.Add(hashKey, rowLayout)
Return rowLayout
End Function
Public Overrides Sub DrawPage(traverser As PrintGridTraverser, drawArea As Rectangle, _
graphics As Graphics, settings As GridPrintSettings, pageNumber As Integer)
Dim fi As FieldInfo = GetType(TableViewDefinitionPrintRenderer).GetField("currentPage", BindingFlags.Instance Or BindingFlags.NonPublic)
Dim currentPage As Integer = fi.GetValue(Me)
Dim skipPage As Boolean = currentPage <> pageNumber
Dim drawAreaHeight As Integer = drawArea.Height
Dim currentX As Integer = drawArea.X
Dim currentY As Integer = drawArea.Y
Dim rowLayout As TableViewRowLayout = Me.GetRowLayout(Me.GridView.MasterView.TableHeaderRow, _
settings.FitWidthMode, settings.HierarchyIndent, drawArea)
rowLayout.IgnoreColumnVisibility = settings.PrintHiddenColumns
Dim systemWidth As Integer = 0
For Each c As GridViewColumn In rowLayout.RenderColumns
If TypeOf c Is GridViewRowHeaderColumn OrElse TypeOf c Is GridViewIndentColumn Then
systemWidth += rowLayout.GetColumnWidth(c)
End If
Next
Dim rowWidth As Integer = CInt(rowLayout.DesiredSize.Width) - systemWidth
If settings.FitWidthMode = PrintFitWidthMode.NoFitCentered Then
currentX += ((drawArea.Width - rowWidth) / 2)
End If
Dim fi2 As FieldInfo = GetType(TableViewDefinitionPrintRenderer).GetField("firstPage", _
BindingFlags.Instance Or BindingFlags.NonPublic)
Dim firstPage As Integer = fi2.GetValue(Me)
If ((Me.GridView.ShowColumnHeaders AndAlso (firstPage AndAlso pageNumber = 1)) OrElse settings.PrintHeaderOnEachPage) _
AndAlso Not settings.PrintHierarchy Then
Me.PrintRow(Me.GridView.MasterView.TableHeaderRow, rowLayout, settings, currentX, currentY, graphics, _
drawArea)
Dim rowHeight As Integer = Me.GetDataRowHeight(Me.GridView.MasterView.TableHeaderRow, rowLayout) + Me.GridView.TableElement.RowSpacing
currentY += rowHeight
drawAreaHeight -= rowHeight
End If
fi2.SetValue(Me, False)
Dim skipPageCurrentY As Integer = currentY
Dim row As GridViewRowInfo = Nothing
If Me.PrintPages.Count > 0 AndAlso Not settings.PrintHierarchy Then
row = traverser.Current
End If
Dim firstRow As Boolean = True
While traverser.MoveNext()
If Not (TypeOf traverser.Current Is GridViewDataRowInfo OrElse TypeOf traverser.Current Is GridViewGroupRowInfo OrElse _
TypeOf traverser.Current Is GridViewSummaryRowInfo OrElse (TypeOf traverser.Current Is GridViewTableHeaderRowInfo _
AndAlso settings.PrintHierarchy)) Then
Continue While
End If
Dim hierarchyRow As GridViewHierarchyRowInfo = TryCast(traverser.Current, GridViewHierarchyRowInfo)
If hierarchyRow IsNot Nothing AndAlso hierarchyRow.Views.Count > 0 Then
Select Case settings.ChildViewPrintMode
Case ChildViewPrintMode.PrintFirstView
hierarchyRow.ActiveView = hierarchyRow.Views(0)
Exit Select
Case ChildViewPrintMode.PrintCurrentlyActiveView
'Do nothing the view is already selected
Exit Select
Case ChildViewPrintMode.SelectViewToPrint
Dim e As New ChildViewPrintingEventArgs(hierarchyRow.Views.IndexOf(hierarchyRow.ActiveView), hierarchyRow)
Me.OnChildViewPrinting(e)
hierarchyRow.ActiveView = hierarchyRow.Views(e.ActiveViewIndex)
Exit Select
End Select
End If
rowLayout = Me.GetRowLayout(traverser.Current, settings.FitWidthMode, settings.HierarchyIndent, drawArea)
Dim rowHeight As Integer = 0
If TypeOf traverser.Current Is GridViewGroupRowInfo Then
rowHeight = Me.GetRowSize(traverser.Current, rowLayout).Height
Else
rowHeight = Me.GetDataRowHeight(traverser.Current, rowLayout)
End If
If (currentY + rowHeight >= drawArea.Bottom OrElse skipPageCurrentY + rowHeight >= drawArea.Bottom) AndAlso Not firstRow Then
traverser.MovePrevious()
skipPageCurrentY = currentY
skipPage = currentPage <> pageNumber
fi.SetValue(Me, currentPage + 1)
If skipPage Then
Continue While
Else
Exit While
End If
End If
If TypeOf traverser.Current Is GridViewGroupRowInfo Then
If settings.PrintGrouping Then
If currentPage = pageNumber Then
Me.PrintRowWideCell(traverser.Current, rowLayout, settings, currentX, currentY, graphics)
currentY += rowHeight + Me.GridView.TableElement.RowSpacing
Else
skipPageCurrentY += rowHeight + Me.GridView.TableElement.RowSpacing
End If
End If
Else
If TypeOf traverser.Current Is GridViewSummaryRowInfo AndAlso Not settings.PrintSummaries Then
Continue While
End If
If currentPage = pageNumber Then
Me.PrintRow(traverser.Current, rowLayout, settings, currentX, currentY, graphics, _
drawArea)
currentY += rowHeight + Me.GridView.TableElement.RowSpacing
Else
skipPageCurrentY += rowHeight + Me.GridView.TableElement.RowSpacing
End If
End If
If drawAreaHeight < rowHeight AndAlso firstRow Then
fi.SetValue(Me, currentPage + 1)
Exit While
End If
firstRow = False
End While
If Me.PrintPages.Count > 0 AndAlso Not settings.PrintHierarchy Then
If currentY + Me.GetDataRowHeight(traverser.Current, rowLayout) < drawArea.Bottom OrElse _
skipPageCurrentY + Me.GetDataRowHeight(traverser.Current, rowLayout) < drawArea.Bottom Then
fi.SetValue(Me, currentPage + 1)
End If
Me.CurrentPrintPage += 1
Me.CurrentPrintPage = Me.CurrentPrintPage Mod Me.PrintPages.Count
If Me.CurrentPrintPage > 0 Then
If row Is Nothing Then
traverser.Reset()
Else
traverser.GoToRow(row)
End If
End If
End If
End Sub
End Class
WORKAROUND:
1. Create a custom GridTableElement and override the ProcessColumnEvent method.
2. Create a custom TableViewDefinition and override the CreateViewUIElement to return the custom table element.
3. Assign the custom view definition to the grid's ViewDefinition property
public class CustomGridTableElement : GridTableElement
{
protected override GridViewEventResult ProcessColumnEvent(GridViewColumn column, GridViewEvent eventData)
{
if (eventData.Info.Id == KnownEvents.PropertyChanged)
{
RadPropertyChangedEventArgs args = eventData.Arguments[0] as RadPropertyChangedEventArgs;
if (args.Property == GridViewColumn.IsVisibleProperty)
{
ViewElement.UpdateRowsWhenColumnsChanged();
if (this.GridViewElement.AutoSizeRows)
{
foreach (GridViewRowInfo row in this.ViewTemplate.Rows)
{
row.Height = -1;
}
this.UpdateLayout();
this.RowScroller.UpdateScrollRange();
}
return null;
}
}
return base.ProcessColumnEvent(column, eventData);
}
protected override Type ThemeEffectiveType
{
get { return typeof(GridTableElement); }
}
}
public class CustomTableViewDefinition : TableViewDefinition
{
public override IRowView CreateViewUIElement(GridViewInfo viewInfo)
{
return new CustomGridTableElement();
}
}
this.radGridView1.ViewDefinition = new CustomTableViewDefinition();
To reproduce:
this.radGridView1.EnableFiltering = true;
this.radGridView1.Columns.Add("Test column");
this.radGridView1.AutoSizeColumnsMode = Telerik.WinControls.UI.GridViewAutoSizeColumnsMode.Fill;
this.radGridView1.Rows.Add("Test ");
Workaround: use custom filtering:
this.radGridView1.EnableCustomFiltering = true;
this.radGridView1.CustomFiltering += radGridView1_CustomFiltering;
private void radGridView1_CustomFiltering(object sender, GridViewCustomFilteringEventArgs e)
{
if (this.radGridView1.FilterDescriptors.Count > 0)
{
GridViewCellInfo cell = e.Row.Cells[this.radGridView1.FilterDescriptors[0].PropertyName];
e.Visible = cell.Value.ToString().StartsWith(this.radGridView1.FilterDescriptors[0].Value.ToString());
}
}