Question

I have the following code in the EditItemTemplate of my FormView:

<tr id="primaryGroupRow" runat="server">
  <td class="Fieldname">Primary Group:</td>
  <td><asp:DropDownList ID="iPrimaryGroupDropDownList" runat="server" DataSourceID="GroupDataSource" CssClass="PageText" 
DataTextField="sGroupName" DataValueField="iGroupID" SelectedValue='<%# Bind("iPrimaryGroup") %>'></asp:DropDownList></td>
</tr>

If I remove the runat="server" for the table row, then the iPrimaryGroup field is bound 100% and passed to the business logic layer properly. However in the case of the code above, it is passed with a value of zero.

Can anyone tell me why this is or how to get around it? This is in a control that needs to hide this table row, based on whether or not an administrator or a regular user is editing it. ie: some fields are admin writeable only and I'd like to hide the controls from the view if the user isn't an admin.

Was it helpful?

Solution 3

It appears that this functionality is by design, although that's not exactly confirmed.

http://weblogs.asp.net/rajbk/archive/2009/08/03/formview-binding-gotcha.aspx

When using the FormView object, if you have a nested control, then two-way databinding isn't going to work properly. You can access the controls in code, and you can get at the data, but it's just not going to automatically update the value in the back end of your Business Logic Layer(BLL) like it's supposed to.

Fortunately, there's a workaround. The way to get it working is to create an event for ItemUpdating. It will have a signature like this:

protected void frmProfile_ItemUpdating(object sender, FormViewUpdateEventArgs e)

This gives you access to the FormViewUpdateEventArgs, which in turn allows you to make changes to the ObjectDataSource values while they are in flight and before they hit your BLL code, as follows:

protected void frmProfile_ItemUpdating(object sender, FormViewUpdateEventArgs e)
{
    if (frmProfile.FindControl("iPrimaryGroupDropDownList") != null)
    {
        DropDownList iPrimaryGroupDropDownList = ((DropDownList)frmProfile.FindControl("iPrimaryGroupDropDownList"));
        e.NewValues["iPrimaryGroup"] = iPrimaryGroupDropDownList.Text;
    }
}

OTHER TIPS

If security is a concern perhaps this might work better

<tr>
  <td colspan='2'>
    <asp:panel runat='server' visible='<%= IsUserAdmin %>'>
      <table>
        <tr>
          <td class="Fieldname">Primary Group:</td>
          <td><asp:DropDownList ID="iPrimaryGroupDropDownList" runat="server" DataSourceID="GroupDataSource" CssClass="PageText" DataTextField="sGroupName" DataValueField="iGroupID" SelectedValue='<%# Bind("iPrimaryGroup") %>'></asp:DropDownList>
          </td>
        </tr>
      </table>
   </asp:panel>
 </td>

If I'm not mistaken any markup within the panel will not be rendered if visible=false

Have a shot at this:

Remove the runat=server attribute

Define a css class

.hidden{ display:hidden;}

Then set the class attribute based on whether or not the user is an admin

<tr class='<%= if(IsUserAdmin) "" else "hidden" %>' >
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top