I have a little question about RadGridView editors.
In SQL Server 2008-Entity Framework context, a Time datatype field is translated as a .NET TimeSpan class. I tried to edit this kind of fields in a RadGridView, but a cast exception is thrown.
Is there any way to edit this data type in the GridView?
Thank you so much.
15 Answers, 1 is accepted
Thank you for contacting us. The TimeSpan object cannot be edited through its properties e.g Tick as they are read-only (have only getters). Therefore, even if you write a custom editor for this type, you will not be able to change the values.
I think that the right conversion of SQL type Time is DateTime in .net. I suggest that you find how to make that conversion in Entity Framework if the generated mapping is wrong. Please read further in MSDN.
Do not hesitate to write me back if you have further questions.
Best wishes,
Nick
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
Thank you for the fast response.
No, the right conversion for SQL Server 2008 Time in Entity Framework 4 is TimeSpan. If I try to modify the type mapping, the compiler throws several errors saying that Edm.DateTime is not compatible with SqlServer.time
Error 3 Error 2019: Member Mapping specified is not valid. The type 'Edm.DateTime[Nullable=False,DefaultValue=,Precision=]' of member Time' in type 'Model.Registry' is not compatible with 'SqlServer.time[Nullable=False,DefaultValue=,Precision=0]' of member 'Time' in type 'Model.Store.Registries'. DataModel.edmx 1161 13 Data Library
Is there any possibility to handle this issue creating an editor that converts String text to TimeSpan?
You can find more information about SQL.Time at the following link:
http://msdn.microsoft.com/en-us/library/cc716757.aspx
The Time type represents an interval of time that can be added to or subtracted from an instance of the DateTime type in the Entity Data Model (EDM).
This type maps to the TimeSpan type in the common language runtime (CLR) and to the Time type in SQL Server."
Hoping we can find a solution,
Best regards,
Sergio
You are absolutely correct. Thank you for providing the link. I created a work-around for you.
First you need to create a custom editor for your column where you need to parse the string value of the grid textbox column and write a TimeSpan to your database:
class
MyEditor : RadTextBoxEditor
{
public
override
object
Value
{
get
{
return
base
.Value;
}
set
{
base
.Value = TimeSpan.Parse(value.ToString());
}
}
}
Then you have to replace the standard text box editor with the new one in EditorRequired event:
void
radGridView1_EditorRequired(
object
sender, EditorRequiredEventArgs e)
{
if
(
this
.radGridView1.CurrentColumn.HeaderText ==
"TimeSpan"
)
{
if
(e.EditorType ==
typeof
(RadTextBoxEditor))
{
e.Editor =
new
MyEditor();
}
}
}
I hope that this helps. You may find more information about our editors in our online documentation.
Greetings,
Nick
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
But I have a last problem...
I put the code exactly as you said (saving the difference of the column header).
This time when I edit the TimeSpan I don't get any error, but the TimeSpan value does not change in grid or EDM context and the following messages are sent to the Debug console:
at System.ComponentModel.ReflectPropertyDescriptor.SetValue(Object component, Object value)
at Telerik.WinControls.Data.DataAccessComponent.set_Item(GridViewRowInfo row, GridViewDataColumn column, Object value)
Only and only this 2 lines.
Here follows my code:
public class RadTimeSpanEditor : RadTextBoxEditor |
{ |
public override object Value |
{ |
get |
{ |
return base.Value; |
} |
set |
{ |
base.Value = TimeSpan.Parse(value.ToString()); |
} |
} |
} |
private void gridView_EditorRequired(object sender, EditorRequiredEventArgs e) |
{ |
if (gridView.CurrentColumn.HeaderText == "Registry") |
{ |
if (e.EditorType == typeof(RadTextBoxEditor)) |
{ |
e.Editor = new RadTimeSpanEditor(); |
} |
} |
} |
For this second block code, I checked that e.EditorType is RadTextBoxEditor in order to instance the RadTimeSpanEditor. In all cases, all code goes right but the Value change.
Thank you for contacting us back. It is my error, here is the modified code:
public
class
RadTimeSpanEditor : RadTextBoxEditor
{
public
override
object
Value
{
get
{
return
TimeSpan.Parse(
base
.Value.ToString());
}
set
{
base
.Value = value.ToString();
}
}
}
And you need to call SaveChanges at the appropriate places for your applications.
int
result = entities.SaveChanges();
Please excuse me for not providing the correct work-around the first time.
Regards,
Nick
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
Worked perfectly.
Thank you so much.
Would be nice if someday Telerik provide an editor for TimeSpan.
I just share my version, which handle Nullable TimeSpan and keep only hour and minutes. And how to handle format error with the CellValidating Event.
Private
Sub
aRadGridView_CellValidating(sender
As
System.
Object
, e
As
Telerik.WinControls.UI.CellValidatingEventArgs)
Handles
aRadGridView.CellValidating
If
e.ActiveEditor IsNot
Nothing
AndAlso
TypeOf
e.ActiveEditor
Is
RadTimeSpanEditor
Then
Dim
test
As
TimeSpan
If
TimeSpan.TryParse(e.Value, x)
OrElse
String
.IsNullOrWhiteSpace(e.Value)
Then
Else
e.Cancel =
True
Beep()
End
If
End
If
End
Sub
Private
Class
RadTimeSpanEditor
Inherits
RadTextBoxEditor
Public
Overrides
Property
Value
As
Object
Get
Dim
temp
As
TimeSpan
If
TimeSpan.TryParse(
MyBase
.Value.ToString, temp)
Then
temp =
New
TimeSpan(temp.Hours, temp.Minutes, 0)
Return
temp.ToString
End
If
Return
MyBase
.Value
End
Get
Set
(value
As
Object
)
MyBase
.Value =
If
(value
Is
Nothing
,
String
.Empty, value.ToString())
End
Set
End
Property
End
Class
Thank you for sharing your solution with the community.
We have a feature request for developing a GridTimeColumn which will work with a TimeSpan editor in RadGridView. Please make sure that you cast your vote to the public feedback item: ADD. RadGridView - New Grid Column - GridTimeColumn.
I hope this information is useful. Should you have further questions please do not hesitate to write back.
Regards,
Hristo Merdjanov
Telerik
I just want to update you that we have released the RadTimeSpanPicker control in the R1 2019 version of the suite. RadGridView is also updated to support the TimeSpan data type. Here is the relevant documentation:
- https://docs.telerik.com/devtools/winforms/controls/editors/timespanpicker/overview
- https://docs.telerik.com/devtools/winforms/controls/gridview/columns/column-types/gridviewtimespancolumn
I hope that the new control and column would fit well in your projects whenever you are dealing with TimeSpan values.
Regards,
Hristo
Progress Telerik
GridViewTimeSpanColumn
If data source contains negative values, then there is not processed error which cannot be corrected. Version 2019.2.508.40
private DataTable dt
{
get
{
DataTable dt = new DataTable();
dt.Columns.Add("ID", typeof(decimal));
dt.Columns.Add("TIME", typeof(TimeSpan));
dt.Rows.Add(1, -new TimeSpan(1,12,0,0));
dt.Rows.Add(2, new TimeSpan(1,12,0,0));
dt.Rows.Add(3, new TimeSpan(1,12,0,0));
dt.Rows.Add(1, new TimeSpan(1,12,0,0));
return dt;
}
}
radGridView1.DataSource = dt;
radGridView1.Visible = true;//ERROR!!!
System.Reflection.TargetInvocationException
HResult=0x80131604
Сообщение = Адресат вызова создал исключение.
Источник = mscorlib
Трассировка стека:
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes, StackCrawlMark& stackMark)
at System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes)
at System.Activator.CreateInstance(Type type, Object[] args)
at Telerik.WinControls.UI.GridRowElement.CreateCell(GridViewColumn column)
at Telerik.WinControls.UI.GridDataRowElement.CreateCell(GridViewColumn column)
at Telerik.WinControls.UI.CellElementProvider.CreateElement(GridViewColumn data, Object context)
at Telerik.WinControls.UI.CellElementProvider.GetElement(GridViewColumn data, Object context)
at Telerik.WinControls.UI.BaseVirtualizedContainer`1.UpdateElement(Int32 position, T data)
at Telerik.WinControls.UI.BaseVirtualizedContainer`1.MeasureElements()
at Telerik.WinControls.UI.BaseVirtualizedContainer`1.MeasureOverride(SizeF availableSize)
at Telerik.WinControls.RadElement.MeasureCore(SizeF availableSize)
at Telerik.WinControls.RadElement.Measure(SizeF availableSize)
at Telerik.WinControls.UI.GridVirtualizedRowElement.MeasureElements(SizeF availableSize, SizeF clientSize, Padding borderThickness)
at Telerik.WinControls.UI.LightVisualElement.MeasureOverride(SizeF availableSize)
at Telerik.WinControls.UI.GridRowElement.MeasureOverride(SizeF availableSize)
at Telerik.WinControls.RadElement.MeasureCore(SizeF availableSize)
at Telerik.WinControls.RadElement.Measure(SizeF availableSize)
at Telerik.WinControls.UI.VirtualizedStackContainer`1.MeasureElementCore(RadElement element, SizeF availableSize)
at Telerik.WinControls.UI.ScrollableRowsContainerElement.MeasureElementCore(RadElement element, SizeF availableSize)
at Telerik.WinControls.UI.VirtualizedStackContainer`1.MeasureElement(IVirtualizedElement`1 element)
at Telerik.WinControls.UI.BaseVirtualizedContainer`1.MeasureElements()
at Telerik.WinControls.UI.ScrollableRowsContainerElement.MeasureOverride(SizeF availableSize)
at Telerik.WinControls.RadElement.MeasureCore(SizeF availableSize)
at Telerik.WinControls.RadElement.Measure(SizeF availableSize)
at Telerik.WinControls.UI.RowsContainerElement.MeasureOverride(SizeF availableSize)
at Telerik.WinControls.RadElement.MeasureCore(SizeF availableSize)
at Telerik.WinControls.RadElement.Measure(SizeF availableSize)
at Telerik.WinControls.Layouts.ContextLayoutManager.UpdateLayout()
at Telerik.WinControls.RadControl.OnLayout(LayoutEventArgs e)
at System.Windows.Forms.Control.PerformLayout(LayoutEventArgs args)
at System.Windows.Forms.ScrollableControl.OnVisibleChanged(EventArgs e)
at Telerik.WinControls.RadControl.OnVisibleChanged(EventArgs e)
at System.Windows.Forms.Control.SetVisibleCore(Boolean value)
at XTest.MainXT.Test_Load(Object sender, EventArgs e) in C:\PROJECTS\AksSoft TFVC\XTest\MainXT.cs:line 115
at System.Windows.Forms.Form.OnLoad(EventArgs e)
at System.Windows.Forms.Form.OnCreateControl()
at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
at System.Windows.Forms.Control.CreateControl()
at System.Windows.Forms.Control.WmShowWindow(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.Form.WmShowWindow(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.SendMessage(HandleRef hWnd, Int32 msg, Int32 wParam, Int32 lParam)
at System.Windows.Forms.Form.SetVisibleCore(Boolean value)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at XTest.Program.Main() in C:\PROJECTS\AksSoft TFVC\XTest\ProgramXT.cs:line 15
Внутреннее исключение 1:
NullReferenceException: Ссылка на объект не указывает на экземпляр объекта.
To allow the GridViewTimeSpanColumn to work with negative values you should use the FormatInfo property which will set the culture info when formatting cells values. You should set the Minimum property to MinValue as well. Please refer to the following code snippet which extends yours:
GridViewTimeSpanColumn timeSpanColumn =
this
.radGridView1.Columns[
"TIME"
]
as
GridViewTimeSpanColumn;
timeSpanColumn.FormatInfo = System.Threading.Thread.CurrentThread.CurrentUICulture;
timeSpanColumn.Minimum = TimeSpan.MinValue;
I hope this helps. Should you have any other questions, I will be glad to help.
Regards,
Nadya
Progress Telerik
I thank for the answer, but it does not work!
You set necessary properties for not attached columns.
The problem is that the error arises during a binding to data source.
How to set necessary properties to a binding to data source?
Works if you terminate the binding command in BeginUpdate ()/EndUpdate ():
radGridView2.BeginUpdate();
radGridView2.DataSource = dt;
(radGridView2.Columns["TIME"] as GridViewTimeSpanColumn).Minimum = TimeSpan.MinValue;
(radGridView2.Columns["TIME"] as GridViewTimeSpanColumn).FormatInfo = System.Threading.Thread.CurrentThread.CurrentUICulture;
radGridView2.EndUpdate();
Thank you!!!!
I am glad that you have found a suitable solution for your case. Using BeginUpdate/EndUpdate method is a valid approach because the grid layout would be refreshed right after calling the EndUpdate method.
If you need any further assistance please don't hesitate to contact me.
Regards,
Nadya
Progress Telerik