There should be a Enum (Left, Right, None) property of the Expander Column indicating whether the position of the expander column should be left right or none. This would be especially important during pinning activities meaning no matter how many columns are being pinned and repositioned in the pinned area of the grid, it would always remain on the left, right or none.
How to reproduce:
public Form1()
{
InitializeComponent();
string newLine = "line";
string multiLine = "line";
for (int i = 0; i < 10; i++)
{
radGridView1.Rows.Add(newLine, multiLine);
multiLine += Environment.NewLine + multiLine;
}
this.Load += Form1_Load;
}
Workaround:
private void Form1_Load(object sender, EventArgs e)
{
this.radGridView1.Columns[1].PropertyChanged += item_PropertyChanged;
}
private void item_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "IsVisible")
{
this.radGridView1.TableElement.ScrollTo(0, 0);
}
}
Note: if you try to clear the initial minimum value by pressing Backspace or Delete key, the editor value reappears.
To reproduce:
GridViewDecimalColumn decimalColumn2 = new GridViewDecimalColumn("Col2");
decimalColumn2.FieldName = "Number";
decimalColumn2.Minimum = -50;
decimalColumn2.Maximum = 50;
radGridView2.MasterTemplate.Columns.Add(decimalColumn2);
radGridView2.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill;
radGridView2.EnableFiltering = true;
Workaround:
private void radGridView2_EditorRequired(object sender, Telerik.WinControls.UI.EditorRequiredEventArgs e)
{
if (e.EditorType == typeof(GridSpinEditor))
{
e.EditorType = typeof(CustomEditor);
}
}
public class CustomEditor : GridSpinEditor
{
protected override Telerik.WinControls.RadElement CreateEditorElement()
{
return new CustomElement();
}
}
public class CustomElement : GridSpinEditorElement
{
protected override decimal GetValueFromText()
{
if (string.IsNullOrEmpty(this.Text))
{
return this.MinValue;
}
return base.GetValueFromText();
}
}
How to reproduce:
Public Class Form1
Sub New()
InitializeComponent()
Dim dataTable As New DataTable
dataTable.Columns.Add("Id", GetType(Integer))
dataTable.Columns.Add("Name", GetType(String))
dataTable.Columns.Add("IsValid", GetType(Boolean))
For i As Integer = 0 To 40
dataTable.Rows.Add(i, "Name " & i, i Mod 2 = 0)
Next
Me.RadGridView1.DataSource = dataTable
Me.RadGridView1.AutoSizeColumnsMode = Telerik.WinControls.UI.GridViewAutoSizeColumnsMode.Fill
Me.RadGridView1.TableElement.RowHeight = 20
End Sub
Private Sub btnPrint_Click(sender As Object, e As EventArgs) Handles btnPrint.Click
Me.RadGridView1.PrintPreview()
End Sub
End Class
Workaround: before printing increase the row height or set RadGridView.AutoSizeRows = True
Private Sub btnPrint_Click(sender As Object, e As EventArgs) Handles btnPrint.Click
'Me.RadGridView1.TableElement.RowHeight = 24
Me.RadGridView1.AutoSizeRows = True
Me.RadGridView1.PrintPreview()
End Sub
To reproduce:
1. Add a GridViewDecimalColumn to a grid with data type int, float, decimal, double, real, money.
2. Add few rows where one of rows contains null value.
3. Run the form. Sort the grid by any of column with null data and you will see that the exception is thrown.
Workaround:
1. Use custom TypeConverter
public class CustomFloatConverter : TypeConverter
{
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
return destinationType == typeof(float);
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
if (destinationType == typeof(float) && (value == null || value is DBNull))
{
return float.MinValue;
}
return value;
}
}
public class CustomIntConverter : TypeConverter
{
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
return destinationType == typeof(int);
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
if (destinationType == typeof(int) && (value == null || value is DBNull))
{
return int.MinValue;
}
return value;
}
}
public class CustomDecimalConverter : TypeConverter
{
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
return destinationType == typeof(decimal);
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
if (destinationType == typeof(decimal) && (value == null || value is DBNull))
{
return decimal.MinValue;
}
return value;
}
}
public class CustomDoubleConverter : TypeConverter
{
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
return destinationType == typeof(double);
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
if (destinationType == typeof(double) && (value == null || value is DBNull))
{
return double.MinValue;
}
return value;
}
}
public class CustomSingleConverter : TypeConverter
{
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
return destinationType == typeof(Single);
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
if (destinationType == typeof(Single) && (value == null || value is DBNull))
{
return Single.MinValue;
}
return value;
}
}
2. Apply the converter to GridViewDecimalColumn
this.radGridView2.Columns["ColumnReal"].DataTypeConverter = new CustomSingleConverter();
this.radGridView2.Columns["ColumnFloat"].DataTypeConverter = new CustomDoubleConverter();
this.radGridView2.Columns["ColumnDecimal"].DataTypeConverter = new CustomDecimalConverter();
this.radGridView2.Columns["ColumnInt"].DataTypeConverter = new CustomIntConverter();
this.radGridView2.Columns["ColumnNumeric"].DataTypeConverter = new CustomDecimalConverter();
this.radGridView2.Columns["ColumnMoney"].DataTypeConverter = new CustomDecimalConverter();
To reproduce:
radGridView1.DataSource = GetTable();
radGridView1.MultiSelect = true;
radGridView1.SelectionMode = Telerik.WinControls.UI.GridViewSelectionMode.CellSelect;
Then just select and deselect several cells without releasing the mouse button.
Workaround:
void radGridView1_MouseUp(object sender, MouseEventArgs e)
{
int endIndexCol = -1;
int endIndexRow = -1;
GridDataCellElement curentCell = radGridView1.ElementTree.GetElementAtPoint(e.Location) as GridDataCellElement;
if (curentCell != null)
{
endIndexCol = curentCell.ColumnInfo.Index;
endIndexRow = curentCell.RowInfo.Index;
}
if (endIndexCol < startIndexCol)
{
int temp = endIndexCol;
endIndexCol = startIndexCol;
startIndexCol = temp;
}
if (endIndexRow < startIndexRow)
{
int temp = endIndexRow;
endIndexRow = startIndexRow;
startIndexRow = temp;
}
foreach (GridViewCellInfo cell in radGridView1.SelectedCells.ToList())
{
if (cell.RowInfo.Index < startIndexRow || cell.RowInfo.Index > endIndexRow)
{
cell.IsSelected = false;
}
if (cell.ColumnInfo.Index < startIndexCol || cell.ColumnInfo.Index > endIndexCol)
{
cell.IsSelected = false;
}
}
}
int startIndexCol = -1 ;
int startIndexRow = -1;
void radGridView1_MouseDown(object sender, MouseEventArgs e)
{
GridDataCellElement curentCell = radGridView1.ElementTree.GetElementAtPoint(e.Location) as GridDataCellElement;
if (curentCell != null)
{
startIndexCol = curentCell.ColumnInfo.Index;
startIndexRow = curentCell.RowInfo.Index;
}
}
To reproduce:
protected override void OnLoad(EventArgs e)
{
this.radGridView1.AllowAddNewRow = false;
this.radGridView1.TableElement.RowHeight = 40;
this.radGridView1.MasterTemplate.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill;
GridViewTextBoxColumn id = new GridViewTextBoxColumn("ID");
id.IsVisible = false;
GridViewTextBoxColumn parentID = new GridViewTextBoxColumn("ParentID");
parentID.IsVisible = false;
GridViewTextBoxColumn name = new GridViewTextBoxColumn("Name");
GridViewDateTimeColumn date = new GridViewDateTimeColumn("Date");
GridViewTextBoxColumn type = new GridViewTextBoxColumn("Type");
GridViewTextBoxColumn size = new GridViewTextBoxColumn("Size");
size.FormatString = "{0} MB";
radGridView1.Columns.AddRange(new GridViewDataColumn[]
{
id,
parentID,
name,
date,
type,
size
});
this.radGridView1.Relations.AddSelfReference(this.radGridView1.MasterTemplate, "ID", "ParentID");
radGridView1.CellValueChanged += radGridView1_CellValueChanged;
fillData();
}
void radGridView1_CellValueChanged(object sender, GridViewCellEventArgs e)
{
fillData();
}
private void fillData()
{
radGridView1.Rows.Clear();
radGridView1.Rows.Add(1, null, "Program Files", DateTime.Now.AddDays(-100), "Folder", 5120);
radGridView1.Rows.Add(2, 1, "Visual Studio 2010", DateTime.Now.AddDays(-100), "Folder", 3220);
radGridView1.Rows.Add(3, 2, "bin", DateTime.Now.AddDays(-100), "Folder", 3220);
radGridView1.Rows.Add(4, 2, "READEME.txt", DateTime.Now.AddDays(-100), "Text Document", 3);
radGridView1.Rows.Add(100, null, "Test.txt", DateTime.Now.AddDays(-10), "Text File", 0);
radGridView1.Rows.Add(5, 1, "Telerik RadControls", DateTime.Now.AddDays(-10), "Folder", 3120);
radGridView1.Rows.Add(6, 5, "Telerik UI for Winforms", DateTime.Now.AddDays(-10), "Folder", 101);
radGridView1.Rows.Add(7, 5, "Telerik UI for Silverlight", DateTime.Now.AddDays(-10), "Folder", 123);
radGridView1.Rows.Add(8, 5, "Telerik UI for WPF", DateTime.Now.AddDays(-10), "Folder", 221);
radGridView1.Rows.Add(9, 5, "Telerik UI for ASP.NET AJAX", DateTime.Now.AddDays(-10), "Folder", 121);
radGridView1.Rows.Add(10, 1, "Microsoft Office 2010", DateTime.Now.AddDays(-120), "Folder", 1230);
radGridView1.Rows.Add(11, 10, "Microsoft Word 2010", DateTime.Now.AddDays(-120), "Folder", 1230);
radGridView1.Rows.Add(12, 10, "Microsoft Excel 2010", DateTime.Now.AddDays(-120), "Folder", 1230);
radGridView1.Rows.Add(13, 10, "Microsoft Powerpoint 2010", DateTime.Now.AddDays(-120), "Folder", 1230);
radGridView1.Rows.Add(14, 1, "Debug Diagnostic Tools v1.0", DateTime.Now.AddDays(-400), "Folder", 2120);
radGridView1.Rows.Add(15, 1, "Designer's 3D Tools", DateTime.Now.AddDays(-500), "Folder", 1120);
radGridView1.Rows.Add(16, 1, "Communication", DateTime.Now.AddDays(-700), "Folder", 120);
}
Then start the application edit a value and click another cell.
Workaround:
- Enclose the rows addition within Begin/End update block.
Steps to reproduce:
1. Add a GridViewDateTimeColumn to a grid.
2. Add rows where one or more rows should contain null as the columns value.
3. Sort the grid by the date time column.
WORKAROUND:
Create a custom RadGridDateTimeConverter and assign it as the column's date type converter:
public class CustomRadGridDateTimeConverter : RadGridDateTimeConverter
{
public CustomRadGridDateTimeConverter(GridViewDateTimeColumn column)
: base(column)
{ }
public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
{
if (destinationType == typeof(DateTime) && value == null)
{
return DateTime.MinValue;
}
return base.ConvertTo(context, culture, value, destinationType);
}
}
this.radGridView1.Columns["DateTime"].DataTypeConverter = new CustomRadGridDateTimeConverter(this.radGridView1.Columns["DateTime"] as GridViewDateTimeColumn);
To reproduce:
public Form1()
{
InitializeComponent();
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("Id", typeof(int)));
dt.Columns.Add(new DataColumn("Name", typeof(string)));
for (int i = 0; i < 50; i++)
{
dt.Rows.Add(i, "Item" + i);
}
radGridView1.DataSource = dt;
radGridView1.MasterTemplate.MultiSelect = true;
}
1. Load a grid with enough rows to make scrolling necessary to see the bottom row.
2. Drag a column header into the group area.
3. Move the vertical scroll bar down. It doesn't matter if you scroll all the way to the end or just barely move the vertical scroll bar, as long as it isn't all the way to the top.
4. Put the mouse on the "X" of the group descriptor. Hold the left mouse button and move the mouse.
Workaround: use custom row behavior:
BaseGridBehavior gridBehavior = rgvTest.GridBehavior as BaseGridBehavior;
gridBehavior.UnregisterBehavior(typeof(GridViewDataRowInfo));
gridBehavior.RegisterBehavior(typeof(GridViewDataRowInfo), new CustomGridDataRowBehavior());
public class CustomGridDataRowBehavior : GridDataRowBehavior
{
public CustomGridDataRowBehavior()
{
typeof(GridRowBehavior).GetField("orderedRows", System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Instance).SetValue(this, new List<GridViewRowInfo>()) ;
}
public override bool OnMouseUp(MouseEventArgs e)
{
bool result = base.OnMouseUp(e);
typeof(GridRowBehavior).GetField("orderedRows", System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Instance).SetValue(this, new List<GridViewRowInfo>()) ;
return result;
}
}
The AllowNaturalSort property should indicate whether the no-sort state when changing sort order will be allowed.
Workaround:
Private Sub SortChanging(sender As Object, e As Telerik.WinControls.UI.GridViewCollectionChangingEventArgs)
If e.Action = NotifyCollectionChangedAction.Remove AndAlso e.OldValue = ListSortDirection.Descending Then
e.Cancel = True
For Each sd As SortDescriptor In Me.RadGridView1.SortDescriptors
If sd.PropertyName = e.PropertyName Then
sd.Direction = ListSortDirection.Ascending
End If
Next
End If
End Sub
Workaround: handle the KeyDown event of the inner TextBoxControl and manipulate the TextBox.SelectionStart:
private void radPropertyGrid1_EditorInitialized(object sender, Telerik.WinControls.UI.PropertyGridItemEditorInitializedEventArgs e)
{
PropertyGridDropDownListEditor ddlEditor = e.Editor as PropertyGridDropDownListEditor;
if (ddlEditor != null)
{
ddlEditor.DropDownStyle = Telerik.WinControls.RadDropDownStyle.DropDown;
BaseDropDownListEditorElement el = ddlEditor.EditorElement as BaseDropDownListEditorElement;
el.EditableElement.TextBox.TextBoxItem.TextBoxControl.KeyDown -= el_KeyDown;
el.EditableElement.TextBox.TextBoxItem.TextBoxControl.KeyDown += el_KeyDown;
}
}
private void el_KeyDown(object sender, KeyEventArgs e)
{
TextBox tb = sender as TextBox;
if (e.KeyData == Keys.Left && tb.SelectionStart > 0)
{
tb.SelectionStart = --tb.SelectionStart;
}
if (e.KeyData == Keys.Right && tb.SelectionStart <= tb.Text.Length)
{
tb.SelectionStart = ++tb.SelectionStart;
}
}
Workaround: check for the theme and set a minimum size to the text box item
private void radGridView1_CellEditorInitialized(object sender, Telerik.WinControls.UI.GridViewCellEventArgs e)
{
BaseGridEditor gridEditor = e.ActiveEditor as BaseGridEditor;
if (gridEditor != null)
{
RadTextBoxElement el = gridEditor.OwnerElement.FindDescendant<RadTextBoxElement>();
if (el != null)
{
if (ThemeResolutionService.ApplicationThemeName == "VisualStudio2012Dark")
{
el.TextBoxItem.MinSize = new Size(0, 20);
el.TextBoxItem.TextBoxControl.MinimumSize = new Size(0, 20);
}
}
}
}
To reproduce:
public Form1()
{
InitializeComponent();
this.Text = Telerik.WinControls.VersionNumber.MarketingVersion + " " + Telerik.WinControls.VersionNumber.Number;
this.radGridView1.Dock = DockStyle.Fill;
string[] coffeeDrinks =
{
"Americano",
"Cafe Crema",
"Caffe Latte",
"Caffe macchiato",
"Coffee milk",
"Cafe mocha",
"Irish coffee",
};
DataTable tableDrinks = new DataTable();
tableDrinks.Columns.Add("DrinkID", typeof(int));
tableDrinks.Columns.Add("Drink", typeof(string));
tableDrinks.Columns.Add("State", typeof(bool));
for (int i = 0; i < coffeeDrinks.Length; i++)
{
if (i % 2 == 0)
{
tableDrinks.Rows.Add(i, coffeeDrinks[i], true);
}
else
{
tableDrinks.Rows.Add(i, coffeeDrinks[i], false);
}
}
this.radGridView1.DataSource = tableDrinks;
GroupDescriptor descriptor = new GroupDescriptor();
descriptor.GroupNames.Add("State", ListSortDirection.Ascending);
this.radGridView1.GroupDescriptors.Add(descriptor);
this.radGridView1.MasterTemplate.ExpandAllGroups();
this.radGridView1.TableElement.GroupIndent = 1;
}
When set the GroupIndent property to 1, the space should be 1 pixel. Currently is bigger than 1 pixel (see attached image). And when users wants to hide the indent column, can not set the GroupIndent property to 0.
Workaround:
this.radGridView1.TableElement.GroupIndent = 1;
foreach (GridViewColumn col in this.radGridView1.TableElement.ViewElement.RowLayout.RenderColumns)
{
if (col is GridViewIndentColumn)
{
col.MinWidth = 0;
break;
}
}
To reproduce:
radGridView1.TableElement.ColumnScroller.ScrollMode = ItemScrollerScrollModes.Discrete;
Workaround:
radGridView1.TableElement.HScrollBar.MouseUp += RadGridView1_HScrollBarMouseUp;
private void RadGridView1_HScrollBarMouseUp(object sender, MouseEventArgs e)
{
int ixCol = GetLeftCol(radGridView1);
Debug.WriteLine( "Index = "+ ixCol);
if (ixCol > -1)
{
radGridView1.TableElement.ScrollToColumn(ixCol);
radGridView1.Rows[0].Cells[ixCol].EnsureVisible();
}
}
private int currentLeftColumnIndex = 0;
private int lastScrollPos = 0;
public int GetLeftCol(RadGridView grd)
{
try
{
if (!grd.Columns.Any())
return -1;
if (!grd.TableElement.VisualRows.Any())
return -1;
if (grd.TableElement.ColumnScroller.Scrollbar.Value == 0)
return -1;
GridRowElement firstVisualRow = grd.TableElement.VisualRows.Where(r => r is Telerik.WinControls.UI.GridDataRowElement).First();
GridCellElement firstVisualCell = firstVisualRow.VisualCells.Where(c => c is Telerik.WinControls.UI.GridDataCellElement).First();
GridCellElement lastVisualCell = firstVisualRow.VisualCells.Where(c => c is Telerik.WinControls.UI.GridDataCellElement).Last();
if (grd.TableElement.ColumnScroller.Scrollbar.Value > lastScrollPos)
{
//"Scrolling Right"
if (lastVisualCell.ColumnIndex == grd.Columns.Last().Index)
{
lastScrollPos = grd.TableElement.ColumnScroller.Scrollbar.Value;
return -1;
}
if (currentLeftColumnIndex == firstVisualCell.ColumnIndex)
{
currentLeftColumnIndex += 1;
}
else
{
currentLeftColumnIndex = firstVisualCell.ColumnIndex < grd.Columns.Count ? firstVisualCell.ColumnIndex : grd.Columns.Count - 1;
}
lastScrollPos = grd.TableElement.ColumnScroller.Scrollbar.Value + 1;
}
else
{
currentLeftColumnIndex = firstVisualCell.ColumnIndex;
lastScrollPos = grd.TableElement.ColumnScroller.Scrollbar.Value - 1;
}
return currentLeftColumnIndex;
}
catch (Exception ex)
{
return -1;
}
}
To reproduce: 1.Populate RadGridView with data and enable Excel-like filtering. 2.Click on a column filter icon and type in the Search textbox so more than two results appear. Then, click OK 2.The grid returns correct result. 3. Click on the previous column filter icon and navigate to Available Filters -> Contains 4. Evaluate the initial pop up dialog. Its conditions should be "Contains" and "Contains". Actually, it shows "Equals" and "Equals" according to the available filter. Workaround:By using the CreateCompositeFilterDialog event you can replace the default CompositeFilterForm with your custom one where you can load the selected filter operators.
Workaround
this.radGridView1.Templates["MyEmptyTemplate"]..AddNewRowPosition = SystemRowPosition.Top
Then handle the ViewCellFormatting event and get notifications when the hierarchy tabs are being clicked.
private void radGridView1_ViewCellFormatting(object sender, CellFormattingEventArgs e)
{
GridDetailViewCellElement detailCell = e.CellElement as GridDetailViewCellElement;
if (detailCell != null) {
detailCell.PageViewElement.ItemSelected -= PageViewElement_ItemSelected;
detailCell.PageViewElement.ItemSelected += PageViewElement_ItemSelected;
}
}
private void PageViewElement_ItemSelected(object sender, RadPageViewItemSelectedEventArgs e)
{
if (e.SelectedItem.Text == "MyEmptyTemplate") {
this.SetsGridViewTemplate.AddNewRowPosition = SystemRowPosition.Bottom;
}
}
To reproduce:
- Add logo in the header and export the document.
Workaround:
void exporter_HeaderExported(object sender, ExportEventArgs e)
{
PdfEditor ed = e.Editor as PdfEditor;
using (MemoryStream ms = new MemoryStream())
{
System.Drawing.Image.FromFile(@"C:\img\delete.png").Save(ms, System.Drawing.Imaging.ImageFormat.Png);
ed.TranslatePosition(e.Rectangle.Width - 30, e.Rectangle.Y);
ed.DrawImage(ms, new System.Windows.Size(30,30));
}
}
How to reproduce: Create a grid in self referencing hierarchy and set up a filter expression like this: this.radGridView1.FilterDescriptors.Expression = "Name = \"bin\" AND (FileSystemInfoType = \"Folder\" OR Id = \"2\")" Immediately after the expression is set, the OR logical operator is substituted with AND