This is a migrated thread and some comments may be shown as answers.

Binding Data To UserControl for Editing

8 Answers 436 Views
Grid
This is a migrated thread and some comments may be shown as answers.
William Corry
Top achievements
Rank 1
William Corry asked on 26 Feb 2009, 08:08 PM
I am trying to use a custom usercontrol for editing items in a RadGrid.  The user control only has a textbox, the cancel and update buttons on it.  I am trying to bind the textbox with via a bind statment but have an error returned.  The description of the usercontrol is:

<%

@ Control Language="VB" AutoEventWireup="false" CodeFile="frmPartnerAttributing.ascx.vb" Inherits="frmPartnerAttributing" %>

 

<

 

asp:TextBox ID="txtPartnerAttributing" runat="server"

 

Text

 

='<%# DataBinder.Eval( Container, "Parent.BindingContainer.DataItem.PartnerAttributing") %>'

 

Width

 

="239px"></asp:TextBox>

 

<

 

br /><br />

 

<

 

asp:Button ID="cmdUpdate" runat="server" Text="Update" />

 

<

 

asp:Button ID="cmdCancel" runat="server" Text="Cancel" />

The error is that the BindingContainer is a GridTableView which does not have a DataItem member.  Is there something wrong with tis method of binding data to the textbox in the usercontrol? The method comes straight from one of the examples.

Thanks,


 

8 Answers, 1 is accepted

Sort by
0
Nikolay Rusev
Telerik team
answered on 27 Feb 2009, 11:36 AM
Hello William,

You can find workable example of RadGrid with custom UserControl for edit form on the following link:
Automatic insert, update and delete with UserControl edit form for the grid
I hope this helps.

Best wishes,
Nikolay
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.
0
William Corry
Top achievements
Rank 1
answered on 27 Feb 2009, 02:08 PM
Thanks for the link.  Could you supply the VB.Net equivalent?  Thanks
0
Sebastian
Telerik team
answered on 27 Feb 2009, 03:05 PM
Hello William,

You can convert the C# code in VB.NET language using our free online converter here:

http://converter.telerik.com/

Note that we will add such type of auto-editing with WebUserControl custom edit form to one of the new ASPNET 3.5 RadGrid examples for the Q1 2009 release of the product, scheduled in the middle of March.

Best regards,
Sebastian
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.
0
William Corry
Top achievements
Rank 1
answered on 27 Feb 2009, 04:50 PM
Thanks for the link to the code converter.  It will probably be most useful. However, in this instance something went wrong.  When I used the code converter to convert the code supplied by the first link  it created the code shown below. 

Partial Class WebUserControl

 

Inherits System.Web.UI.UserControl

 

Implements IBindableControl

 

    Public Sub ExtractValues(ByVal dictionary As IOrderedDictionary)

        Controls.OfType(

Of TextBox)().[Select](Function(t As ) dictionary(t.ID) = t.Text).count()

 

 

    End Sub

End

 

Class



When this code is used a new instance of a UserControl there were two error messages.

The Error messages were:
1: Type 'IBindableControl' is not defined
2: 

Overload resolution failed because no accessible 'Select' can be called with these arguments:

    Extension method 'Public Function Select(Of TResult)(selector As System.Func(Of System.Web.UI.WebControls.TextBox, Integer, TResult)) As System.Collections.Generic.IEnumerable(Of TResult)' defined in 'System.Linq.Enumerable': Nested function does not have the same signature as delegate 'System.Func(Of System.Web.UI.WebControls.TextBox, Integer, TResult)'.

    Extension method 'Public Function Select(Of TResult)(selector As System.Func(Of System.Web.UI.WebControls.TextBox, Integer, TResult)) As System.Collections.Generic.IEnumerable(Of TResult)' defined in 'System.Linq.Enumerable': Data type(s) of the type parameter(s) cannot be inferred from these arguments. Specifying the data type(s) explicitly might correct this error.

    Extension method 'Public Function Select(Of TResult)(selector As System.Func(Of System.Web.UI.WebControls.TextBox, TResult)) As System.Collections.Generic.IEnumerable(Of TResult)' defined in 'System.Linq.Enumerable': Data type(s) of the type parameter(s) cannot be inferred from these arguments. Specifying the data type(s) explicitly might correct this error.    C:\Documents and Settings\bcorry\My Documents\Visual Studio 2008\WebSites\WebSite1\WebUserControl.ascx.vb 

This prompts me to ask:
The closest implement clause I could find was IBindableTemplate; was this the correct item to implement?
What select is the second error message referring to? Does the message imply I should be using Linq?
How would this interface be used in the context of the original question to bind the controls on the EditForm?

0
Todd Anglin
Top achievements
Rank 2
answered on 02 Mar 2009, 06:14 PM
Hello William-

Sorry for the trouble with the conversion! I think the issue here may be part converter - part missing code. Let's see if we can find some steps to solve the problem:

  1. Make sure you're referencing the namespace that contains IBindableControl in your class. It should be found in System.Web.UI namespace. http://msdn.microsoft.com/en-us/library/system.web.ui.ibindablecontrol.aspx
  2. For the second error- the error about the lamda expression- I think the converter does not yet do a good job of converting C# syntax to VB lamda syntax. You'll probably need to convert that manually. Here's an example:

    Controls.OfType(Of TextBox).Select(Function(t) dictionary(t.ID) = t.Text).Count()

    I've done a lot of VB lately, so I apologize if that's not 100% correct, but I think that's the C# equiv.

Give those steps a try and see if that helps solve your build problems!

-Todd
0
William Corry
Top achievements
Rank 1
answered on 02 Mar 2009, 09:11 PM
Thanks Todd:

At this point I'm having conceptual difficulties with how this works.  The following code works for one control but I'm having troubles figuring out how to extend the example.   In the example that follows I use the ItemDataBound event to catch the GridEditFormItem while in edit mode. The ItemView shows 10 fields but I only wish to edit  one.  The user control only has two control buttons and a textbox (for now).  What I haven't figured out is how to map the controls in the Itemview with the controls in the usercontrol.  I empirically determined that Item(8) was the correct item to map to the appropriate user control.  Is there a way to map controls using the names of the controls? (e.g. any control on the itemview having a corresponding control on the usercontrol would have it's value mapped).  Another issue is that there will be times when the values (comma separate values) on in the itemview will come as a label but need to be mapped to a multiselected listbox.

The code you supplied makes it look like textboxes map to textboxes and so on.  Does the iBindabletemplate implementation allow mapping between controls of diffent type?  

BTW, is there a way to get rid of the triple spacing that shows up in code when it's posted? 

 

Protected Sub RadGrid1_ItemDataBound(ByVal sender As Object, ByVal e As Telerik.Web.UI.GridItemEventArgs) Handles RadGrid1.ItemDataBound

 

 

 

If (TypeOf e.Item Is GridEditFormItem AndAlso e.Item.IsInEditMode) Then

 

 

 

'this is an attempt to get the edit items from the sender (radgrid)

 

'Dim parentItem As GridEditFormItem = CType(e.Item, GridEditFormItem).Parent

 

 

 

Dim EIColn As Telerik.Web.UI.GridItemCollection = CType(sender.EditItems, Telerik.Web.UI.GridItemCollection)

 

 

 

If EIColn.Count > 0 Then

 

 

 

Dim EI As Telerik.Web.UI.GridEditableItem = EIColn.Item(0)

 

 

 

Dim GI As Telerik.Web.UI.GridItem = EI.DataItem 'get the parent item

 

 

 

End If

 

 

 

Dim GEFI As Telerik.Web.UI.GridEditFormItem = e.Item

 

 

 

Dim DI As System.Data.DataRowView = GEFI.DataItem

 

 

 

Dim ob As Object = DI.Row.ItemArray

 

 

 

Try

 

 

 

Dim Itm9 As Object = DI.Row.Item(8)    

 

 

 

'next line gets the usercontrol that is being used to edit the items and updates it

 

 

 

Dim MyUserControl As UserControl = CType(e.Item.FindControl(GridEditFormItem.EditFormUserControlID), UserControl)

 

 

 

Dim box As TextBox = CType(MyUserControl.FindControl("txtPartnerAttributing"), TextBox)

 

box.Text = Itm9

 

 

Catch ex As Exception

 

System.Windows.Forms.MessageBox.Show(ex.ToString)

 

 

End Try

 

 

 

 

End If

 

 

 

End Sub

 

 

0
Todd Anglin
Top achievements
Rank 2
answered on 02 Mar 2009, 10:42 PM
Let me try to help clear-up some of confusion- I apolgize in advance if I don't hit your question directly.

  1. First, you can use the "Format Code Block" tool to more easily share code snippets. It is button next to the spell check button on the forum reply editor.
  2. Connecting controls is not really required (at least as far as the ItemsTemplate to the EditItemTemplate is concerned). The idea is that the controls in your UserControl edit form are automatically bound to a field in your data source via the "<%# Bind("YourFieldName") %>" syntax. Then, when you click submit, the value of IBindableControl is that your DataSourceControl can automatically find your changed values and persist them to the data layer. No extra code required. Your only burden is to implement the IBindableControl interface, which means you must fill the IOrderedDictionary with your edit form values.

What's that mean? That means you should do the following to extend this demo:

  1. Make sure your UserControl is inheriting from IBindableControl
  2. Make sure your controls in your edit form ASCX are using the <%# Bind(...) %> syntax
  3. Make sure you implement the ExtractValues method by writing code that grabs values from your edit form and stores them in the dictionary with a key that = the data field name (in this demo, the data field name is also the control ID).

That's really it. Then, when working with data source controls and "AllowAutomaticX" operations set to "True," your values will automatically be persisted. The LINQ in the demo is just one of getting your values from your UserControl and persisting them to the dictionary- you can use any code and/or approach you want to accomplish this step.

Does that help?

-Todd
0
William Corry
Top achievements
Rank 1
answered on 03 Mar 2009, 09:56 PM
Thanks Todd:
It certainly gets me a step closer, but brings up a few more questions: 

You mentioned populating the controls on the usercontrol with the <%# Bind(...) %>  syntax.  What does one do when you need to use a multiselect listbox to represent the data in the editform?  Is there a way that one can pass the control to which the old answers are to be represented, along with the old answers to a procedure and have it select the appropriate rows on the control?  Currently I'm using the ItemDataBound event to populate multiselect listbox on the usercontrol.  The event is triggered when the user clicks the Update button on the RadGrid.

The code the codegenerator used to create the ExtractValues(ByVal dictionary As IOrderedDictionary) function that is required by iBindableTemplate doesn't match the signature required.  When I type in the implements iBindablestatement and the have Visual Studio generate the required methods the signature for the function is:

    Function ExtractValues(ByVal container As Control) As Collections.Specialized.IOrderedDictionary Implements System.Web.UI.IBindableTemplate.ExtractValues  
 
    End Function 
I copied another the code from another example to try to get a dictionary object out of the function, the code for a single textbox is:
    Function ExtractValues(ByVal container As Control) As Collections.Specialized.IOrderedDictionary Implements System.Web.UI.IBindableTemplate.ExtractValues  
        Dim od As New OrderedDictionary()  
        od.Add("PartnerAttributing", (DirectCast(((DirectCast((container), GridEditFormItem)).FindControl("txtPartnerAttributing")), TextBox)).Text)  
        Return od  
    End Function 
I'm assuming that the ExtractValues function is called when the update button on the user control is clicked?  The following code block is run when the user clicks on the Update button on the usercontrol.  If i had values returned I could presumable write code to update the database? 
    Protected Sub Update(ByVal sender As ObjectByVal e As System.Web.UI.WebControls.CommandEventArgs) Handles cmdUpdate.Command  
        Dim UserCtl As System.Web.UI.Control = CType(sender.namingContainer.namingContainer, System.Web.UI.Control)  
        Dim od As OrderedDictionary = Me.ExtractValues(UserCtl)  
 
        'At this point more code would be written to use the dictionary values to update the database?  
 
 
    End Sub 

If one does update the database at this point, how does one get out of the editview and back to the view where no items are in edit view?

Thanks for your patience,
Tags
Grid
Asked by
William Corry
Top achievements
Rank 1
Answers by
Nikolay Rusev
Telerik team
William Corry
Top achievements
Rank 1
Sebastian
Telerik team
Todd Anglin
Top achievements
Rank 2
Share this question
or