Eery time I use the GridView, I have to remember to un-select the last item in the list.
This is almost always to wrong thing to be selected - so why select it by default?
..and the way to swith this 'feaure' off isn't obvious - I always have to look it up....RadGridView1.CurrentRow = Nothing
When the RadGridView AutoSize property is set to true and a row is expanded, an exception is thrown:
System.InvalidOperationException: 'MeasureOverride returned positive infinity: Telerik.WinControls.UI.GridDetailViewRowElement'
A possible workaround is to replace the GridDetailViewRowElement with your own class. Then overriding the MeasureOverride method we can pass valid size to the element.
private void RadGridView1_CreateRow(object sender, GridViewCreateRowEventArgs e)
{
if (e.RowInfo is GridViewDetailsRowInfo)
{
e.RowElement = new MyGridDetailViewRowElement();
}
}
public class MyGridDetailViewRowElement : GridDetailViewRowElement
{
protected override SizeF MeasureOverride(SizeF availableSize)
{
var baseSize = base.MeasureOverride(availableSize);
if(baseSize.Width == float.PositiveInfinity)
{
baseSize.Width = 800;
}
return baseSize;
}
}
To reproduce: please run the attached sample project and follow the steps illustrated in the attached gif file: Scrolling to a newly added row does not work when inner templates are visible. Add data to the inner templates of several rows near the bottom using the button. Expand these inner templates so they are all visible. Scroll back up to the top. Add a new item to the outer grid normally. The table will jump to where it things the new item is but will fall short, instead scrolling to a location in one of the inner templates. Workaround: private void RadGridView1_UserAddedRow(object sender, GridViewRowEventArgs e) { foreach (GridViewRowInfo row in this.radGridView1.Rows) { if (row.IsExpanded) { row.IsExpanded = false; row.IsExpanded = true; } } }
With releasing .NET 6, there are TimeOnly and DateOnly types which would be more appropriate for managing such values:
https://devblogs.microsoft.com/dotnet/date-time-and-time-zone-enhancements-in-net-6/
It would be good to add support for these types in GridViewDateTimeView.
Currently, the following code gives an exception when entering edit mode:
public RadForm1()
{
InitializeComponent();
DataTable dt = new DataTable();
dt.Columns.Add("DateOnly", typeof(DateOnly));
dt.Rows.Add(new DateOnly(2022,3,3));
this.radGridView1.AutoGenerateColumns = false;
GridViewDateTimeColumn dateColumn = new GridViewDateTimeColumn();
dateColumn.FieldName = "DateOnly";
this.radGridView1.Columns.Add(dateColumn);
this.radGridView1.DataSource = dt;
this.radGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill;
}
Workaround: you can use the following custom TypeConverter:
public RadForm1()
{
InitializeComponent();
DataTable dt = new DataTable();
dt.Columns.Add("DateOnly", typeof(DateOnly));
dt.Rows.Add(new DateOnly(2022,3,3));
this.radGridView1.AutoGenerateColumns = false;
GridViewDateTimeColumn dateColumn = new GridViewDateTimeColumn();
dateColumn.DataType = typeof(DateTime);
dateColumn.FieldName = "DateOnly";
dateColumn.Format = DateTimePickerFormat.Custom;
dateColumn.CustomFormat = "dd/MM/yyyy";
dateColumn.FormatString = "{0:dd/MM/yyyy}";
dateColumn.DataTypeConverter = new DateOnlyConverter();
this.radGridView1.Columns.Add(dateColumn);
this.radGridView1.DataSource = dt;
this.radGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill;
}
public class DateOnlyConverter : TypeConverter
{
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
return destinationType == typeof(DateTime);
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
if (value is DateOnly && destinationType == typeof(DateTime))
{
DateOnly date = (DateOnly)value;
return new DateTime(date.Year, date.Month, date.Day);
}
return base.ConvertTo(context, culture, value, destinationType);
}
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(DateTime) ;
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if (value is DateTime)
{
DateTime date = (DateTime)value;
return new DateOnly(date.Year, date.Month, date.Day);
}
return base.ConvertFrom(context, culture, value);
}
}
Hi. it was great to see the option "ImageOnly", for columns of small width, where only the image is placed in the header, and the "HederText" property was set, for the correct display of the grouping field
GridViewDataColumn column;
column.HeaderText = "Счет";
column.HeaderImage = ...; // some img
column.TextImageRelation = TextImageRelation.Overlay;
GridViewDataColumn column;
column.HeaderText = "";
column.HeaderImage = ...; // some img
column.TextImageRelation = TextImageRelation.Overlay;
it’s impossible to choose one thing, either an ugly header, or a grouping without a description
Use the following code snippet:
GridViewDateTimeColumn orderDate = this.radGridView1.Columns["OrderDate"] as GridViewDateTimeColumn;
orderDate.Format = DateTimePickerFormat.Custom;
orderDate.CustomFormat = "dd-MM-yyyy";
orderDate.FormatString = "{0:dd-MM-yyyy}";
GridViewDateTimeColumn shippedDate = this.radGridView1.Columns["ShippedDate"] as GridViewDateTimeColumn;
shippedDate.Format = DateTimePickerFormat.Custom;
shippedDate.CustomFormat = "dd-MM-yyyy";
shippedDate.FormatString = "{0:dd-MM-yyyy}";
When the grid is grouped by a column with a specific format, it should be taken in consideration by the group row as well.
Please run the sample project and follow the steps:
1.Open the attached solution in Visual Studio - I am using VS 2022.Use this XML layout:
this.radGridView1.LoadLayout(@"..\..\..\Layout.xml");
<RadGridView Padding="0, 0, 0, 1" Cursor="Default" TabIndex="49">
<MasterTemplate EnableGrouping = "True" AllowEditRow="False" AllowDeleteRow="False" AllowAddNewRow="False" EnableFiltering="True" AutoExpandGroups="True">
<Columns>
<Telerik.WinControls.UI.GridViewTextBoxColumn Width="100" FieldName="JobID" Name="JobID" IsAutoGenerated="True" IsVisible="True" HeaderText="JobID" />
<Telerik.WinControls.UI.GridViewTextBoxColumn Width="100" FieldName="CustomerID" Name="CustomerID" IsAutoGenerated="True" IsVisible="True" HeaderText="CustomerID" />
<Telerik.WinControls.UI.GridViewTextBoxColumn Width="285" FieldName="StatusID" Name="StatusID" IsAutoGenerated="True" IsVisible="True" HeaderText="StatusID" />
<Telerik.WinControls.UI.GridViewTextBoxColumn Width="100" FieldName="UnitID" Name="UnitID" IsAutoGenerated="True" IsVisible="True" HeaderText="UnitID" />
<Telerik.WinControls.UI.GridViewTextBoxColumn Width="100" FieldName="OperatorID" Name="OperatorID" IsAutoGenerated="True" IsVisible="True" HeaderText="OperatorID" />
<Telerik.WinControls.UI.GridViewTextBoxColumn Width="100" FieldName="JobTypeID" Name="JobTypeID" IsAutoGenerated="True" IsVisible="True" HeaderText="JobTypeID" />
<Telerik.WinControls.UI.GridViewTextBoxColumn Width="100" FieldName="JobCatID" Name="JobCatID" IsAutoGenerated="True" IsVisible="True" HeaderText="JobCatID" />
<Telerik.WinControls.UI.GridViewDateTimeColumn Width="100" FieldName="StartTime" Name="StartTime" IsAutoGenerated="True" IsVisible="True" HeaderText="StartTime">
<FilterDescriptor xsi:type="Telerik.WinControls.Data.DateFilterDescriptor" Value="" IgnoreTimePart="False" PropertyName="StartTime" Operator="IsNotNull" IsFilterEditor="True" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
</Telerik.WinControls.UI.GridViewDateTimeColumn>
<Telerik.WinControls.UI.GridViewDateTimeColumn Width="100" FieldName="FinishTime" Name="FinishTime" IsAutoGenerated="True" IsVisible="True" HeaderText="FinishTime" />
<Telerik.WinControls.UI.GridViewDateTimeColumn Width="100" FieldName="CreateDate" Name="CreateDate" SortOrder="Descending" IsAutoGenerated="True" IsVisible="True" HeaderText="CreateDate" />
<Telerik.WinControls.UI.GridViewDateTimeColumn Width="100" FieldName="StatusJobDate" Name="StatusJobDate" IsAutoGenerated="True" IsVisible="True" HeaderText="StatusJobDate" />
<Telerik.WinControls.UI.GridViewTextBoxColumn Width="100" FieldName="UserID" Name="UserID" IsAutoGenerated="True" IsVisible="True" HeaderText="UserID" />
<Telerik.WinControls.UI.GridViewTextBoxColumn DataType="System.Guid" Width="100" FieldName="TableKey" Name="TableKey" IsAutoGenerated="True" IsVisible="False" HeaderText="TableKey" />
</Columns>
<FilterDescriptors>
<Telerik.WinControls.Data.DateFilterDescriptor Value="" IgnoreTimePart="False" PropertyName="StartTime" Operator="IsNotNull" IsFilterEditor="True" />
</FilterDescriptors>
<SortDescriptors>
<Telerik.WinControls.Data.SortDescriptor PropertyName="CreateDate" Direction="Descending" />
</SortDescriptors>
<ViewDefinition xsi:type="Telerik.WinControls.UI.TableViewDefinition" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
</MasterTemplate>
</RadGridView>
Workaround:
public class CustomGridView : RadGridView
{
protected override GridViewLayoutSerializer CreateGridViewLayoutSerializer(Telerik.WinControls.XmlSerialization.ComponentXmlSerializationInfo info)
{
return new CustomGridViewLayoutSerializer(info);
}
public override string ThemeClassName
{
get
{
return typeof(RadGridView).FullName;
}
}
}
public class CustomGridViewLayoutSerializer : GridViewLayoutSerializer
{
public CustomGridViewLayoutSerializer(ComponentXmlSerializationInfo componentSerializationInfo) : base(componentSerializationInfo)
{
}
protected override bool ProcessReaderAttribute(System.Xml.XmlReader reader, object parentObject, object toRead, PropertyDescriptor property)
{
if (toRead is FilterDescriptor && reader.Value == string.Empty)
{
object val = reader.Value;
if (property.ComponentType == typeof(DateFilterDescriptor))
{
val = null;
}
this.SetPropertyValue(property, toRead, val);
return true;
}
return base.ProcessReaderAttribute(reader, parentObject, toRead, property);
}
}
Please refer to the sample project and open the Home form. The attached gif file illustrates how to reproduce the error.
Workaround: define the grid relations via code.
To reproduce:
public RadForm1()
{
InitializeComponent();
string txt = "what follows is test characters (some of) which should cause error: เปลี่ยน UPS ที่ห้อง Truck scale เนื่องจากเมื่อวันพฤหัสที่ 13 มีการออฟเบรกเกอร์ที่ ฺฺB/H แต่ว่า เครื่องคอมพิวเตอร์ที่ T/S ดับ ตัว UPS ไม่ทำงาน ทำให้ข้อมูลขณะนั้นหายไป ";
this.label1.Text = txt; // No error
Font font = this.label1.Font;// new Font("Segoe UI", 9.5f, FontStyle.Regular);
this.radLabel1.Font = font;
this.radLabel1.Text = txt; //GDI error
}
Workaround:
this.radLabel1.UseCompatibleTextRendering = false;
To reproduce : public partial class RadForm1 : Telerik.WinControls.UI.RadForm { public RadForm1() { InitializeComponent(); radGridView1.DataSource = GetTable(); } private void radButton1_Click(object sender, EventArgs e) { var exporter = new GridViewPdfExport(radGridView1); exporter.FileExtension = "pdf"; exporter.ShowHeaderAndFooter = true; exporter.LeftFooter = GridViewPdfExport.DatePrintedString; exporter.FitToPageWidth = true; exporter.PageMargins = new Padding(20, 15, 10, 10); exporter.RunExport(@"C:\Users\dkaramfi\Desktop\test123.pdf", new PdfExportRenderer()); } static DataTable GetTable() { DataTable table = new DataTable(); table.Columns.Add("Dosage", typeof(int)); table.Columns.Add("Drug", typeof(string)); table.Columns.Add("Name", typeof(string)); table.Columns.Add("Name1", typeof(string)); table.Columns.Add("Name2", typeof(string)); table.Columns.Add("Name3", typeof(string)); table.Columns.Add("Name4", typeof(string)); table.Rows.Add(50, "Enebrel", "Sam", "Sam1", "Sam2", "Sam4", "Sam4"); table.Rows.Add(25, "Indocin", "David"); table.Rows.Add(50, "Enebrel", "Sam"); table.Rows.Add(10, "Hydralazine", "Christoff"); table.Rows.Add(21, "Combivent", "Janet"); table.Rows.Add(100, "Dilantin", "Melanie"); return table; } } Workaround: Leave the default margins.
Use the following code snippet:
public RadForm1()
{
InitializeComponent();
GridViewDecimalColumn idColumn = new GridViewDecimalColumn("Id");
this.radGridView1.Columns.Add(idColumn);
GridViewTextBoxColumn nameColumn = new GridViewTextBoxColumn("Name");
this.radGridView1.Columns.Add(nameColumn);
GridViewDateTimeColumn dateColumn = new GridViewDateTimeColumn("Date");
dateColumn.FilteringMode = GridViewTimeFilteringMode.Date;
dateColumn.Format = DateTimePickerFormat.Custom;
dateColumn.CustomFormat = "dd/MM/yyyy";
dateColumn.FormatString = "{0:dd/MM/yyyy}";
this.radGridView1.Columns.Add(dateColumn);
this.radGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill;
for (int i = 0; i < 50; i++)
{
this.radGridView1.Rows.Add(i,"Row"+i,DateTime.Now.AddDays(i));
}
this.radGridView1.EnableFiltering = true;
this.radGridView1.ShowHeaderCellButtons = true;
this.radGridView1.ShowFilteringRow = false;
this.radGridView1.FilterExpressionChanged += RadGridView1_FilterExpressionChanged;
}
private void RadGridView1_FilterExpressionChanged(object sender, FilterExpressionChangedEventArgs e)
{
Console.WriteLine(e.FilterExpression);
}
If I use the calendar control then the sequence works:
Click the filter button
Click Available filters
Click Equals
Click the calendar button in the value field
Click on December 10, 2021
But if I do not use the calendar control then it does not work. This sequence produces no results:
Click the filter button
Click Available filters
Click Equals
Click on the day component of the value field
Type in 10
Click OK
Workaround:
private void RadGridView1_CreateCompositeFilterDialog(object sender, GridViewCreateCompositeFilterDialogEventArgs e)
{
e.Dialog = new CustomCompositeDataFilterForm();
}
public class CustomCompositeDataFilterForm : CompositeDataFilterForm
{
protected override void OnClosing(CancelEventArgs e)
{
base.OnClosing(e);
if (GridFilterCellElement.ValidateUserFilter(this.FilterDescriptor))
{
CompositeFilterDescriptor cfd = this.FilterDescriptor as CompositeFilterDescriptor;
if (cfd != null)
{
foreach (FilterDescriptor fd in cfd.FilterDescriptors)
{
TrimTimePart(fd);
}
}
else
{
TrimTimePart(this.FilterDescriptor);
}
}
}
private void TrimTimePart(FilterDescriptor filterDescriptor)
{
CompositeFilterDescriptor cfd = filterDescriptor as CompositeFilterDescriptor;
if (cfd != null)
{
foreach (FilterDescriptor fd in cfd.FilterDescriptors)
{
TrimTimePart(fd);
}
}
else
{
DateTime dateValue = DateTime.MinValue;
if (DateTime.TryParse(filterDescriptor.Value + "", out dateValue))
{
dateValue = dateValue.Date;
filterDescriptor.Value = dateValue;
}
}
}
}
Hi,
I have a question regarding RadGridView. When I edit a cell in GridView and then click on a button (outside of gridview) immediately (i.e I don't click on another cell to exit edit mode), the Gridview is still edit mode. Please refer to the short video named "Without Using EndEdit()" to easily understand my point here.
In order to exit the edit mode, I try the following code:
Private Sub CustomGridView_LostFocus(sender As Object, e As EventArgs) Handles Me.LostFocus Me.EndEdit() End Sub
With this code, the gridview does exit the edit mode when I click on another button. But there is a problem with this method is that afterwards, I cannot edit the cell anymore. Please refer to the short video named "Using EndEdit()" to better understand the problem.
So my question here is, is there any way that I can exit edit mode when clicking on another button right after editing a cell?
Thank you for your help.
Best regards,
Tran
To reproduce, rebind the grid to a data table on button click and show grid's search row.
public RadForm1()
{
InitializeComponent();
this.radGridView1.AllowSearchRow = true;
}
private void RadButton1_Click()
{
DataTable dt = this.GetData();
this.radGridView1.DataSource = dt;
}
private DataTable GetData()
{
DataTable data = new DataTable();
for (int i = 0; i < 5; i++)
{
data.Columns.Add("Column " + i, typeof(int));
data.Columns.Add("Column " + i + 1, typeof(string));
data.Columns.Add("Column " + i + 2, typeof(string));
}
for (int k = 0; k < 5000; k++)
{
object[] parameters = new object[15];
for (int i = 0; i < 15; i += 3)
{
parameters[i] = k;
parameters[i + 1] = "Text " + i;
parameters[i + 2] = "Text " + i + 1;
}
data.Rows.Add(parameters);
}
return data;
}
There are situations where SelectedRows won't return the number of rows preselected when using Begin/EndUpdate even though it seems like there's a row selected in the UI. By preselected I mean the row that looks selected after the rows has been added. This bug has caused some problems for us because the user tried some action on a row they thought was preselected and it would fail.
One situation I found where this bug can be reproducted is by using SortOrder in combination of Begin/EndUpdate. There are probably more situations but I hope this one will let you find the underlying bug.
The attached project contains a simple form with a RadGridView which will contain a list of persons. The list is populated by this method:
public void PopulateGridView(List<Person> persons)
{
PersonGridView.BeginUpdate();
PersonGridView.DataSource = persons;
PersonGridView.EndUpdate();
PersonGridView.Columns[nameof(Person.LastName)].SortOrder = RadSortOrder.Ascending;
}
There are two buttons: "Step one" and "Step two". The first will mimick a situation where the user search a database for persons and none will be found. By clicking the "Get selected rows" you will see that the SelectedRows will return zero rows which is correct.
But when you afterwards click "Step two" (which will add five rows) it seems like there's one row preselected. I would expect the SelectedRows to return that row but by clicking "Get selected rows" again you will see that the returned rows are zero still. The CurrentRow, however is set to the preselected row as expected.
If you start by clicking "Step two" the SelectedRows actually returns the correct rows. Quite strange :-)
I know this is a very small issue and can be avoided. But as I mentioned there are other situations where this problem occurs and it's quite hard to figure out exactly what causes it.
Thank you for your help.
Best regards
Ulrik Skovenborg