Hi,
I'm evaluating the Telerik GridView for use in a new project and am coming up against a couple of difficulties. I haven't found answers in the Forum, so I thought I would ask.
The situation. We are binding CSLA collections to a data grid. We want to use comboboxes for certain columns. Due to customer restraints, we are forced to use WinForms.
First. For GridViewComboBoxColumns. Is it possible to bind not to a value of the SelectedItem but to the item itself? We use readonly "Mini Objects" for things like Products and try not to expose the ID for that product. It shouldn't be necessary for the UI Developer to know what the ID is. You might think about adding the option SelectedItem to the ValueMember options. Then the SelectedItem is bound to the object and not the ID. I would think this would also be interesting for things like EF Entities where you also want to bind to an object and not directly to an ID.
I found a partial workaround for the above problem, see below, but it seems very cludgy.
Second: Our Business objects are based on bindinglists. That means they have logic for determining default values for new items added to collections. For example for the OrderDetail object will automatically set the default discount depending on the Customer defined in the OrderObject.
Does the RadGridView support this kind of senario? How can I convince the grid to use my 'correct' value instead of an empty version?
Also, since the RadGridView adds a "Phantom" object, the above code doesn't work. I can't set the editable price for the OrderDetail. It gets ignored.
Note, the default object works perfectly in the Windows datagrid but causes problems with the Telerik product. Interestingly, if I have both controls on the same form, bound to the same bindinglist and click on the "new row" in the Windows DataGrid, the Telerik gets all the events and shows the right information.
Thanks for any help.
I'm evaluating the Telerik GridView for use in a new project and am coming up against a couple of difficulties. I haven't found answers in the Forum, so I thought I would ask.
The situation. We are binding CSLA collections to a data grid. We want to use comboboxes for certain columns. Due to customer restraints, we are forced to use WinForms.
First. For GridViewComboBoxColumns. Is it possible to bind not to a value of the SelectedItem but to the item itself? We use readonly "Mini Objects" for things like Products and try not to expose the ID for that product. It shouldn't be necessary for the UI Developer to know what the ID is. You might think about adding the option SelectedItem to the ValueMember options. Then the SelectedItem is bound to the object and not the ID. I would think this would also be interesting for things like EF Entities where you also want to bind to an object and not directly to an ID.
I found a partial workaround for the above problem, see below, but it seems very cludgy.
Private Sub RadGridView1_ValueChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles RadGridView1.ValueChanged
Dim dataRow As GridViewDataRowInfo = TryCast(Me.RadGridView1.CurrentRow, GridViewDataRowInfo)
If dataRow Is Nothing Then
Return
End If
Dim orderDetail As BO.OrderDetail = TryCast(dataRow.DataBoundItem, BO.OrderDetail)
Dim cbEditor As RadDropDownListEditor = TryCast(Me.RadGridView1.ActiveEditor, Telerik.WinControls.UI.RadDropDownListEditor)
If cbEditor IsNot Nothing Then
Dim editorElement As RadDropDownListEditorElement = TryCast(cbEditor.EditorElement, RadDropDownListEditorElement)
Dim prod As BO.ProductInfo = DirectCast(editorElement.SelectedItem.DataBoundItem, BO.ProductInfo)
orderDetail.ProductInfo = prod
orderDetail.UnitPrice = prod.UnitPrice
End If
End Sub
Second: Our Business objects are based on bindinglists. That means they have logic for determining default values for new items added to collections. For example for the OrderDetail object will automatically set the default discount depending on the Customer defined in the OrderObject.
Does the RadGridView support this kind of senario? How can I convince the grid to use my 'correct' value instead of an empty version?
Also, since the RadGridView adds a "Phantom" object, the above code doesn't work. I can't set the editable price for the OrderDetail. It gets ignored.
Note, the default object works perfectly in the Windows datagrid but causes problems with the Telerik product. Interestingly, if I have both controls on the same form, bound to the same bindinglist and click on the "new row" in the Windows DataGrid, the Telerik gets all the events and shows the right information.
Thanks for any help.
7 Answers, 1 is accepted
0
Hello B,
2) RadGridView performs real adding operation in the underlying bound object after you press the 'Enter' key in the new row or change the focus to another row. You can use DefaultValuesNeeded event for your scenario to populate the default values.
Julian Benkov
the Telerik team
Please accept my apologies for the delayed answer.
1) Currently RadGridView does not support this functionality out of the box. Please refer to the solution below. It demonstrates how to achieve the desired behavior using the ValueChanging event:
Public Partial Class Form1 Inherits Form Public Class Product Public Property Id() As Integer Get Return m_Id End Get Set m_Id = Value End Set End Property Private m_Id As Integer Public Property Name() As String Get Return m_Name End Get Set m_Name = Value End Set End Property Private m_Name As String Public Property Category() As Category Get Return m_Category End Get Set m_Category = Value End Set End Property Private m_Category As Category End Class Public Class Category Public Property Id() As Integer Get Return m_Id End Get Set m_Id = Value End Set End Property Private m_Id As Integer Public Property Name() As String Get Return m_Name End Get Set m_Name = Value End Set End Property Private m_Name As String End Class Private comboColumn As GridViewComboBoxColumn Public Sub New() InitializeComponent() Me.radGridView1.ValueChanging += New ValueChangingEventHandler(AddressOf radGridView1_ValueChanging) Dim categories As New BindingList(Of Category)() Dim cat As New Category() cat.Id = 0 cat.Name = "PC" categories.Add(cat) cat = New Category() cat.Id = 1 cat.Name = "Laptop" categories.Add(cat) cat = New Category() cat.Id = 2 cat.Name = "Phone" categories.Add(cat) Dim products As New BindingList(Of Product)() Dim product As New Product() product.Id = 0 product.Name = "IBM" product.Category = categories(0) products.Add(product) product = New Product() product.Id = 1 product.Name = "HP" product.Category = categories(1) products.Add(product) product = New Product() product.Id = 2 product.Name = "HTC" product.Category = categories(2) products.Add(product) Me.radGridView1.DataSource = products Me.radGridView1.Columns.RemoveAt(2) 'remove auto-generated Category column Me.comboColumn = New GridViewComboBoxColumn() comboColumn.DataType = GetType(String) comboColumn.DataSource = categories comboColumn.DisplayMember = "Name" comboColumn.FieldName = "Category.Name" Me.radGridView1.Columns.Add(comboColumn) End Sub Private Sub radGridView1_ValueChanging(sender As Object, e As ValueChangingEventArgs) Dim editor As RadComboBoxEditor = TryCast(Me.radGridView1.ActiveEditor, RadComboBoxEditor) If editor IsNot Nothing AndAlso Me.radGridView1.CurrentColumn = Me.comboColumn Then Dim element As RadComboBoxEditorElement = TryCast(editor.EditorElement, RadComboBoxEditorElement) Dim item As RadComboBoxItem = TryCast(element.SelectedItem, RadComboBoxItem) Dim cat As Category = TryCast(item.DataItem, Category) If cat IsNot Nothing Then Dim product As Product = TryCast(Me.radGridView1.CurrentRow.DataBoundItem, Product) product.Category = cat End If e.Cancel = True Me.radGridView1.CurrentRow.InvalidateRow() End If End SubEnd Class2) RadGridView performs real adding operation in the underlying bound object after you press the 'Enter' key in the new row or change the focus to another row. You can use DefaultValuesNeeded event for your scenario to populate the default values.
I hope this information is useful. Let me know if you need further assistance.
Greetings,Julian Benkov
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
0
B
Top achievements
Rank 1
answered on 26 Aug 2010, 10:44 AM
Hi Julian,
Thanks for your answer.
For question 1, I have a follow up. Why do you have the lines:
Is it correct that the e.Cancel overrides the original combobox behavior and the InvalidateRow call still allows row validation to fire?
Unfortunately 2 is a deal breaker. While I could set the default properties for the row I completely lose the business logic included in the object.
That means, for example, I have a a required field. My business object already handles that problem and returns the appropriate validation information. I can just bind my collection to the grid and it works. For your solution, I would have to completely redo that validation in the UI. Of course that validation should only fire if the current item is new.
There are of course other issues. For example, an order line item automatically calculates the current price dependant on the product price, quantity, tax, discounts and so forth. That logic is already included in the BO and sometimes can get very complex. Doubling that code in the UI would be ... um ... suboptimal.
You might consider allowing the user to override the AddNew behavior in future releases. An AddingNewRow event that lets the user set the new object. Life would be good. :-)
I'll have to think about a workaround. Is there a way to completely override the addnew row and replace it with a button? Then I could simply add the object myself. The problem is that the data entry should be mouseless if possible. Thus I'd like to replace the add new row with a button that gets tabbed to after the last column in the last row.
Thanks for your help.
Thanks for your answer.
For question 1, I have a follow up. Why do you have the lines:
e.Cancel = True Me.radGridView1.CurrentRow.InvalidateRow()Unfortunately 2 is a deal breaker. While I could set the default properties for the row I completely lose the business logic included in the object.
That means, for example, I have a a required field. My business object already handles that problem and returns the appropriate validation information. I can just bind my collection to the grid and it works. For your solution, I would have to completely redo that validation in the UI. Of course that validation should only fire if the current item is new.
There are of course other issues. For example, an order line item automatically calculates the current price dependant on the product price, quantity, tax, discounts and so forth. That logic is already included in the BO and sometimes can get very complex. Doubling that code in the UI would be ... um ... suboptimal.
You might consider allowing the user to override the AddNew behavior in future releases. An AddingNewRow event that lets the user set the new object. Life would be good. :-)
I'll have to think about a workaround. Is there a way to completely override the addnew row and replace it with a button? Then I could simply add the object myself. The problem is that the data entry should be mouseless if possible. Thus I'd like to replace the add new row with a button that gets tabbed to after the last column in the last row.
Thanks for your help.
0
Hi B,
Julian Benkov
the Telerik team
1) e.Cancel in ValueChanging event overrides the behavior only in the special case of a combo box column. All validation events will be processed with the default behavior for cells and rows.
2) If you want to override the operation of adding a new row in RadGridView, you can use the new event introduced in Q2 2010 - UserAddingRow - and cancel the adding operation if the new row is not valid in regards to your BO model and relations.
Julian Benkov
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
0
B
Top achievements
Rank 1
answered on 01 Sep 2010, 04:57 PM
Thanks,
Unfortunately the UserAddingRow fires too late. You have to have edited the row and click somewhere else before it fires. I would still have to rewrite all the business logic and validation use while the new row is being edited. That was my point.
Preferably you should handle the case where someone implements the IBindingList interface. That let's developers implement the AllowNew property and the AddNew method. The AddNew method should add the new object to the list and call the ListChanged Event. The ListChangedEventArgs give the properties ListChangedType and NewIndex. You can tell you are adding a new item and the object can be found in the list at the NewIndex location. Then bind to the newly added Item.
My BO's do this and in the normal Windows DataGrid the binding works normally.
Alternatively you would need a BeforeUserAddRow event with a NewItem Property in the Event Args. That way you could create the new object and return it. That would get added to the listview automatically. The user would write something like:
Unfortunately the UserAddingRow fires too late. You have to have edited the row and click somewhere else before it fires. I would still have to rewrite all the business logic and validation use while the new row is being edited. That was my point.
Preferably you should handle the case where someone implements the IBindingList interface. That let's developers implement the AllowNew property and the AddNew method. The AddNew method should add the new object to the list and call the ListChanged Event. The ListChangedEventArgs give the properties ListChangedType and NewIndex. You can tell you are adding a new item and the object can be found in the list at the NewIndex location. Then bind to the newly added Item.
My BO's do this and in the normal Windows DataGrid the binding works normally.
Alternatively you would need a BeforeUserAddRow event with a NewItem Property in the Event Args. That way you could create the new object and return it. That would get added to the listview automatically. The user would write something like:
Private Sub RadGridView1_BeforeUserAddRow(ByVal sender As Object, ByVal e As Telerik.WinControls.UI.GridViewBeforeAddNewRowArgs) Handles RadGridView1.BeforeUserAddRow
e.NewItem = New OrderLineItem
End Sub
0
Hi B,
Thank you for writing me back.
Now I understand your scenario. In our previous versions we supported it. However, this behavior caused confusion in our users. It was not clear when the row is actually added in the data source and when in RadGridView. That is why we changed the behavior and now the row is added to the data source when the validation process finishes. Nevertheless, your scenario makes sense and we will consider extending our API to support both cases.
If you have further questions, do not hesitate to contact me.
Regards,
Julian Benkov
the Telerik team
Thank you for writing me back.
Now I understand your scenario. In our previous versions we supported it. However, this behavior caused confusion in our users. It was not clear when the row is actually added in the data source and when in RadGridView. That is why we changed the behavior and now the row is added to the data source when the validation process finishes. Nevertheless, your scenario makes sense and we will consider extending our API to support both cases.
If you have further questions, do not hesitate to contact me.
Regards,
Julian Benkov
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
0
B
Top achievements
Rank 1
answered on 08 Sep 2010, 11:21 AM
Ah. Now I understand.
Should I add this as a feature request?
Should I add this as a feature request?
0
Hi B,
The issue has already been logged in our Issue tracking system. The new behavior and properties will be ready for the Q3 2010 release.
Thank you for you time.
Greetings,
Julian Benkov
the Telerik team
The issue has already been logged in our Issue tracking system. The new behavior and properties will be ready for the Q3 2010 release.
Thank you for you time.
Greetings,
Julian Benkov
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