By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
429,570 Members | 999 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 429,570 IT Pros & Developers. It's quick & easy.

DataGridView with databound combobox

P: n/a
1) I have a DataGridView with edit capability.
But in some columns I want to limit the input with a DropDownList.
There is no inbuilt column for DropDownLists so I intended to add one myself.
I thought the TemplateField would be a good candidate so I added a
DropDownList in the EditItemTemplate and a Literal in the ItemTemplate, but
then I was kind of lost ....
It would be convenient to use the DataGridView for all other fields but
maybe it will not work?

2) Is there a way to Format the value in the normal Show/Edit fields? I have
a date column that looks strange with all "extra time details".
Mar 15 '06 #1
Share this Question
Share on Google+
9 Replies


P: n/a
Hi Jakob,

1) For the dropdownlist within a GridView, you can add within the
EditItemTemplate a dropdownlist that retrieves its values based on a
datasource object. The dropdownlist can be updated using the one-way
databinding (using Eval) but in order for it to update the datasource you
would have to write code while consuming the GridVeiw.RowUpdating event. I
have a sample that implements this strategy albeit using a FormView. You may
look at its source code and adapt it for the GridView

http://www.webswapp.com/codesamples/...s/default.aspx

2) As for your second question, if you have a DataFormatString applied to a
BoundField you can set the ApplyFormatInEditMode to true.

http://msdn2.microsoft.com/en-us/lib...de(VS.80).aspx
--
HTH,
Phillip Williams
http://www.societopia.net
http://www.webswapp.com
"Jakob Lithner" wrote:
1) I have a DataGridView with edit capability.
But in some columns I want to limit the input with a DropDownList.
There is no inbuilt column for DropDownLists so I intended to add one myself.
I thought the TemplateField would be a good candidate so I added a
DropDownList in the EditItemTemplate and a Literal in the ItemTemplate, but
then I was kind of lost ....
It would be convenient to use the DataGridView for all other fields but
maybe it will not work?

2) Is there a way to Format the value in the normal Show/Edit fields? I have
a date column that looks strange with all "extra time details".

Mar 15 '06 #2

P: n/a
1) Looks interesting. I will try to apply it to my application tomorrow.
2) Perfect!

Thanks!
Mar 15 '06 #3

P: n/a
It is a bit different when using a GridView .....
This is what I came up with:

<asp:GridView ID="grdActivity" runat="server"
AutoGenerateColumns="False" DataSourceID="objActivities">
<Columns>
<asp:BoundField DataField="ActivityDate"
HeaderText="ActivityDate"/>
<asp:TemplateField HeaderText="ActivityTime">
<EditItemTemplate>
<asp:DropDownList ID="cboActivityTime"
runat="server"></asp:DropDownList>
</EditItemTemplate>
<ItemTemplate>
<asp:Literal ID="litActivityTime"
runat="server"></asp:Literal>
</ItemTemplate>
</asp:TemplateField>
<asp:CommandField ShowDeleteButton="True"
ShowEditButton="True" />
</Columns>
</asp:GridView>

Protected Sub grdActivity_RowEditing(ByVal sender As Object, ByVal e As
System.Web.UI.WebControls.GridViewEditEventArgs) Handles
grdActivity.RowEditing

'Get hold of combobox
Dim row As GridViewRow = DirectCast(sender,
GridView).Rows(e.NewEditIndex)
Dim cbo As DropDownList =
DirectCast(row.FindControl("cboActivityTime"), DropDownList)

'Load the combobox
cbo.DataSource = GetAvailableTimes.DefaultView
cbo.DataValueField = "Time"
cbo.DataTextField = "TimeString"
cbo.DataBind()
End Sub

Protected Sub grdActivity_RowUpdating(ByVal sender As Object, ByVal e As
System.Web.UI.WebControls.GridViewUpdateEventArgs) Handles
grdActivity.RowUpdating

'Get hold of combobox
Dim row As GridViewRow = DirectCast(sender,
GridView).Rows(e.NewEditIndex)
Dim cbo As DropDownList =
DirectCast(row.FindControl("cboActivityTime"), DropDownList)

'Set the New value of the object
e.NewValues("ActivityTime") = cbo.SelectedValue

'Accept the value
e.Cancel = False
End Sub
The first problem is that the FindControl will not find the DropDownList,
probably because it is placed inside a TemplateField.

Mar 16 '06 #4

P: n/a
Hi Jakob,

I figured that the best response is to put a sample of the GridView similar
the FormView that I had.
http://www.webswapp.com/codesamples/.../gridview.aspx

--
HTH,
Phillip Williams
http://www.societopia.net
http://www.webswapp.com
"Jakob Lithner" wrote:
It is a bit different when using a GridView .....
This is what I came up with:

<asp:GridView ID="grdActivity" runat="server"
AutoGenerateColumns="False" DataSourceID="objActivities">
<Columns>
<asp:BoundField DataField="ActivityDate"
HeaderText="ActivityDate"/>
<asp:TemplateField HeaderText="ActivityTime">
<EditItemTemplate>
<asp:DropDownList ID="cboActivityTime"
runat="server"></asp:DropDownList>
</EditItemTemplate>
<ItemTemplate>
<asp:Literal ID="litActivityTime"
runat="server"></asp:Literal>
</ItemTemplate>
</asp:TemplateField>
<asp:CommandField ShowDeleteButton="True"
ShowEditButton="True" />
</Columns>
</asp:GridView>

Protected Sub grdActivity_RowEditing(ByVal sender As Object, ByVal e As
System.Web.UI.WebControls.GridViewEditEventArgs) Handles
grdActivity.RowEditing

'Get hold of combobox
Dim row As GridViewRow = DirectCast(sender,
GridView).Rows(e.NewEditIndex)
Dim cbo As DropDownList =
DirectCast(row.FindControl("cboActivityTime"), DropDownList)

'Load the combobox
cbo.DataSource = GetAvailableTimes.DefaultView
cbo.DataValueField = "Time"
cbo.DataTextField = "TimeString"
cbo.DataBind()
End Sub

Protected Sub grdActivity_RowUpdating(ByVal sender As Object, ByVal e As
System.Web.UI.WebControls.GridViewUpdateEventArgs) Handles
grdActivity.RowUpdating

'Get hold of combobox
Dim row As GridViewRow = DirectCast(sender,
GridView).Rows(e.NewEditIndex)
Dim cbo As DropDownList =
DirectCast(row.FindControl("cboActivityTime"), DropDownList)

'Set the New value of the object
e.NewValues("ActivityTime") = cbo.SelectedValue

'Accept the value
e.Cancel = False
End Sub
The first problem is that the FindControl will not find the DropDownList,
probably because it is placed inside a TemplateField.

Mar 20 '06 #5

P: n/a
Thanks Phillip, I appreciate your effort!

1) I tried hard to get this working but one remaining stumblingblock is this
line:

<asp:DropDownList ID="cboActivityTime" runat="server"
DataSourceID="objTimes" DataValueField="TimeShow" DataTextField="TimeShow"
SelectedValue='<%# Bind("ActivityTime") %>' ></asp:DropDownList>

It will cause this error:
"'cboActivityTime' has a SelectedValue which is invalid because it does not
exist in the list of items.
Parameter name: value"

Possible workaoround?
Your solution obviously works. What is the difference? My ObjectDatasource
retrieves a DataView, will that be a problem?
2) And I am still VERY eager to manipulate the DropDownList in code behind
(Load, set SelectedValue, etc). I am much more used to plain code than these
ObjectSource objects, and find it more flexible.

In the GridView RowEditing Event I can easily get hold of the Literal
control of the TemplateField. Is it impossible to get hold of the
DropDownList control in a similar way?

<asp:TemplateField HeaderText="ActivityTime">
<ItemTemplate>
<asp:Literal ID="litActivityTime" runat="server"
Text='<%# Eval("ActivityTime") %>'></asp:Literal>
</ItemTemplate>
<EditItemTemplate>
<asp:ObjectDataSource ID="objTimes" runat="server"
TypeName="SKF.BusinessLogic.StaticInfo"
SelectMethod="GetNormalTimes"
DataObjectTypeName="SKF.BusinessLogic.StaticInfo"> </asp:ObjectDataSource>
<asp:DropDownList ID="cboActivityTime" runat="server"
DataSourceID="objTimes" DataValueField="TimeShow" DataTextField="TimeShow"
SelectedValue='<%# Bind("ActivityTime") %>' ></asp:DropDownList>
</EditItemTemplate>
</asp:TemplateField>
Protected Sub grdActivity_RowEditing(ByVal sender As Object, ByVal e As
System.Web.UI.WebControls.GridViewEditEventArgs) Handles
grdActivity.RowEditing
Dim grd As GridView
Dim row As GridViewRow
Dim lit As New Literal
Dim cbo As DropDownList

grd = DirectCast(sender, GridView)
row = DirectCast(sender, GridView).Rows(e.NewEditIndex)
lit = DirectCast(row.FindControl("litActivityTime"), Literal)
'cbo = DirectCast(row.FindControl("cboActivityTime"), DropDownList)
End Sub
Mar 23 '06 #6

P: n/a
Hello Jakob,

Since you are using Bind (which will set the selected value from the data as
well as save the selected value to data upon update), the dropdownlist must
be populated with all possible values. In your specific code, for example,
if you had a value in the field named “ActivityTime” that is not within the
set of values for “TimeShow” then you would get that error. It can also
happen if your datatable schema was created to allow nulls in ActivityTime.

The solutions are:
1- if the problem is happening due to Null values in AcitvityTime then you
can declare the dropdownlist like this:

<asp:DropDownList ID="cboActivityTime" runat="server"
AppendDataBoundItems=”true”
DataSourceID="objTimes" DataValueField="TimeShow" DataTextField="TimeShow"
SelectedValue='<%# Bind("ActivityTime") %>' ></asp:DropDownList>

http://msdn2.microsoft.com/en-us/lib...ms(VS.80).aspx

2- if the problem is happening due to illegal values saved in “ActivityTime”
(that are not part of the set of values for TimeShow) then you can:

a. fix the data

b. create a UNION query within the objTimes that would bring not only the
values from the “TimeShow” but also any values in “ActivityTime” that is not
included

c. handle it on the level of the user interface like I did on my sample
where I removed the Bind statement from the DropDownList and replaced with
code within the dropdownlist.DataBound event, e.g.

Protected Sub cboAcitvityTime_DataBound(ByVal sender As Object, ByVal e As
EventArgs)
Dim ddl As DropDownList = CType(sender, DropDownList)
Dim gvr As GridViewRow = CType(ddl.NamingContainer, GridViewRow)
If Not gvr.DataItem Is Nothing Then
Dim strTimeShow As String = CType(gvr.DataItem, DataRowView)("
TimeShow")
'be careful of the possibility that the value saved on the
'database does not exist in the valid selections that are
displayed
'on the list
ddl.ClearSelection()
Dim li As ListItem = ddl.Items.FindByValue(strTimeShow)
If Not li Is Nothing Then li.Selected = True
End If

In which case you would also have to save the selected value upon update by
consuming the GridViewRowUpdating, like this:

Protected Sub grdActivity_RowUpdating (ByVal sender As Object, ByVal e As
GridViewUpdateEventArgs)
Dim strTimeShow As String = CType(CType(sender,
GridViewRow).FindControl("cboActivityTime"), DropDownList).SelectedValue
e.NewValues("ActivityTime") = strTimeShow
e.Cancel = False
End Sub
Regarding your question on how to find the dropdownlist within the
GridViewRow while handling the RowEditing event…

The RowEditing event is raised when a row's Edit button is clicked, but
before the GridView control enters edit mode.
http://msdn2.microsoft.com/en-us/lib...ng(VS.80).aspx

Which means that during this event processing the dropdownlist has not yet
been rendered. You can find that dropdownlist after the edit is complete
and the user pressed on the update command which will trigger the RowUpdating
event.
--
HTH,
Phillip Williams
http://www.societopia.net
http://www.webswapp.com
"Jakob Lithner" wrote:
Thanks Phillip, I appreciate your effort!

1) I tried hard to get this working but one remaining stumblingblock is this
line:

<asp:DropDownList ID="cboActivityTime" runat="server"
DataSourceID="objTimes" DataValueField="TimeShow" DataTextField="TimeShow"
SelectedValue='<%# Bind("ActivityTime") %>' ></asp:DropDownList>

It will cause this error:
"'cboActivityTime' has a SelectedValue which is invalid because it does not
exist in the list of items.
Parameter name: value"

Possible workaoround?
Your solution obviously works. What is the difference? My ObjectDatasource
retrieves a DataView, will that be a problem?
2) And I am still VERY eager to manipulate the DropDownList in code behind
(Load, set SelectedValue, etc). I am much more used to plain code than these
ObjectSource objects, and find it more flexible.

In the GridView RowEditing Event I can easily get hold of the Literal
control of the TemplateField. Is it impossible to get hold of the
DropDownList control in a similar way?

<asp:TemplateField HeaderText="ActivityTime">
<ItemTemplate>
<asp:Literal ID="litActivityTime" runat="server"
Text='<%# Eval("ActivityTime") %>'></asp:Literal>
</ItemTemplate>
<EditItemTemplate>
<asp:ObjectDataSource ID="objTimes" runat="server"
TypeName="SKF.BusinessLogic.StaticInfo"
SelectMethod="GetNormalTimes"
DataObjectTypeName="SKF.BusinessLogic.StaticInfo"> </asp:ObjectDataSource>
<asp:DropDownList ID="cboActivityTime" runat="server"
DataSourceID="objTimes" DataValueField="TimeShow" DataTextField="TimeShow"
SelectedValue='<%# Bind("ActivityTime") %>' ></asp:DropDownList>
</EditItemTemplate>
</asp:TemplateField>
Protected Sub grdActivity_RowEditing(ByVal sender As Object, ByVal e As
System.Web.UI.WebControls.GridViewEditEventArgs) Handles
grdActivity.RowEditing
Dim grd As GridView
Dim row As GridViewRow
Dim lit As New Literal
Dim cbo As DropDownList

grd = DirectCast(sender, GridView)
row = DirectCast(sender, GridView).Rows(e.NewEditIndex)
lit = DirectCast(row.FindControl("litActivityTime"), Literal)
'cbo = DirectCast(row.FindControl("cboActivityTime"), DropDownList)
End Sub

Mar 24 '06 #7

P: n/a
Sorry I didn't answer before, but for some reason I was not notified of your
reply.

I am ashamed to tell you but I found out today(!) that all the problem was
caused by a totally different reason: the combobox was loaded with times of
the format "11.00" but the database contained times formatted as "11:00", and
I didn't notice!!!

As for combobox not being reachable in the RowEditing event, it makes sense :)

It all works by now and I am happy, Thanks!

Apr 1 '06 #8

P: n/a
Sorry I didn't answer before, but for some reason I was not notified of your
reply and didn't see it until today.

I am ashamed to confess that the main problem had a totally different
reason: the combobox was loaded with values on the form "11.00" but the
database held values on the form "11:00" and I was totally blind for the
difference all the time ... !

I understand that the combobox is not created yet in the RowEditing event,
it makes sense :)

It all works by now so I am all happy again, Thanks!

Apr 1 '06 #9

P: n/a
Thanks Jakob for the feed-back. I am glad you managed to get the
dropdownlist/gridview working.
--
Phillip Williams
http://www.societopia.net
http://www.webswapp.com
"Jakob Lithner" wrote:
Sorry I didn't answer before, but for some reason I was not notified of your
reply and didn't see it until today.

I am ashamed to confess that the main problem had a totally different
reason: the combobox was loaded with values on the form "11.00" but the
database held values on the form "11:00" and I was totally blind for the
difference all the time ... !

I understand that the combobox is not created yet in the RowEditing event,
it makes sense :)

It all works by now so I am all happy again, Thanks!

Apr 2 '06 #10

This discussion thread is closed

Replies have been disabled for this discussion.