views:

370

answers:

1

I have a series of GridViews in a Tab Panel - databound to a generic List of Business Objects.

The columns in the Gridview are all similar to the following:

<asp:TemplateField HeaderText="Company" SortExpression="Company.ShortName">
    <ItemTemplate>
        <asp:Label ID="lblCompany" runat="server" Text='<%# Bind("Company.ShortName") %>'></asp:Label>
    </ItemTemplate>
    <EditItemTemplate>
        <asp:DropDownList ID="ddlCompany" runat="server"></asp:DropDownList>
    </EditItemTemplate>
</asp:TemplateField>

The GridView generates the "Edit" link at the beginning of the row, all the events fire ok. The problem is that the data is getting long. When in 'display mode', it's fine because the GridView control is smart enough to break some text into multiple lines (in particular Project, Title and Worker names can get pretty long).

The problem come in editing mode. Drop-down lists DON'T break entries into multiple lines (for obvious reasons). Going into Edit ode on a row in the Gridview can make the Griview expand horizontally to twice the screen size (blowing through the width limits in the Master page and CSS but that's only a related problem).

What I need is something like the ModalPopup - but trying to tie it to an ID in an EditItemTemplate gives me errors when the page renders (because the 'ddlXXXX' doesn't exist at the time). In addition I don't know how to dynamically populate the panel so that I can get a response from it (like the ID of the Company they selected).

I'm also trying to avoid javascript and would like this to be a 'pure' aspx/code-behind solution (for simplicity's sake among others).

All the examples I find are of Modal Popups with the panels pre-defined. Even if it (the popup panel) were something like a list of checkboxes, it could be databound to the SortedList I have ready to go and an OK/Cancel button combination to accept or ignore things. I'm just not sure of what goes where.

I'm open to suggestions. Thanks in advance.

EDIT: Final solution looks as follows:

<asp:TemplateField HeaderText="Company" SortExpression="Company.ShortName">
    <ItemTemplate>
        <asp:Label ID="lblCompany" runat="server" Text='<%# Bind("Company.ShortName") %>'></asp:Label>
    </ItemTemplate>
    <EditItemTemplate>
        <asp:LinkButton ID="lnkCompany" runat="server" Text='<%# Bind("Company.ShortName") %>'></asp:LinkButton>
        <asp:Panel ID="pnlCompany" runat="server" style="display:none">
            <div> 
                <asp:DropDownList ID="ddlCompany" runat="server" ></asp:DropDownList>
                <br/> 
                <asp:ImageButton ID="btnOKCo" runat="server" ImageUrl="~/Images/greencheck.gif" OnCommand="PopupButton_Command" CommandName="SelectCO" /> 
                <asp:ImageButton ID="btnCxlCo" runat="server" ImageUrl="~/Images/RedX.gif" /> 
            </div> 
        </asp:Panel>
        <cc1:ModalPopupExtender ID="mpeCompany" runat="server" 
                TargetControlID="lnkCompany" PopupControlID="pnlCompany" 
                BackgroundCssClass="modalBackground" CancelControlID="btnCxlCo" 
                DropShadow="true" PopupDragHandleControlID="pnlCompany" />
    </EditItemTemplate>
</asp:TemplateField>

And in the code-behind, lstIDLabor is the generic List of data lines (of which Company is one of the properties that is also a business object) that is bound to the GridView:

Sub PopupButton_Command(ByVal sender As Object, ByVal e As CommandEventArgs)
    Dim intRow As Integer
    Dim intVal As Integer
    RestoreFromSessionVariables()
    Select Case e.CommandName
        Case "SelectCO"
            intRow = grdIDCostLabor.EditIndex
            Dim ddlCo As DropDownList = CType(grdIDCost.Rows(intRow).FindControl("ddlCompany"), DropDownList)
            intVal = ddlCo.SelectedValue
            lstIDLabor(intRow).CompanyID = intVal
            lstIDLabor(intRow).Company = Company.Read(intVal)
        Case Else
            '
    End Select
    MakeSessionVariables()
    BindGrids()
End Sub
A: 

What about this?

<asp:TemplateField HeaderText="Company" SortExpression="Company.ShortName">
<ItemTemplate>
    <asp:Label ID="lblCompany" runat="server" Text='<%# Bind("Company.ShortName") %>'></asp:Label>
</ItemTemplate>
<EditItemTemplate>
    <asp:LinkButton ID="EditBtn" runat="server" Text='<%# Eval("Company.ShortName") %>' />
      <asp:Panel ID="Panel1" runat="server" Style="display: none" CssClass="modalPopup">
        <div>
          <asp:DropDownList ID="ddlCompany" runat="server"  SelectedValue='<%# Bind("Company.ID")></asp:DropDownList><br/>
          <asp:ImageButton ID="OkButton" runat="server" ImageUrl="~/Images/OkBtn.png"  />
          <asp:ImageButton ID="CancelButton" runat="server" ImageUrl="~/Images/Cancel.png" />

          </div>
        </div>
      </asp:Panel>
      <act:ModalPopupExtender ID="ModalPopupExtender" runat="server" TargetControlID="EditBtn"
        PopupControlID="Panel1" BackgroundCssClass="modalBackground" CancelControlID="CancelButton"
        DropShadow="true" PopupDragHandleControlID="Panel1" />
</EditItemTemplate>

So when you edit you see the company as a linkButton and when you click you get the popup with the dropdown that is already binded to the company id

alejandrobog
I had all sorts of reasons why I thought it would be impractical but I had mis-read your code. Having re-read it, I almost can't wait for Monday to get into the office and try it. If this works as expected, it'll work almost exactly like the old application that I'm trying to replace who's only saving grace was the nice popups when editing some of the fields in the detail lines.
David
The popup works (just need to work on the style). One question - where do I trap the "OkButton.Select" event? Since it's in the EditItemTemplate, the code-behind doesn't know the button exists. I need to be able to grab the value in the drop-down list and re-bind the data so that the new text will appear in the LinkButton.
David
You should be able to bind the ddl from the EditTemplate to the company id. Review the answer I just edit it. About the select, I dont think you need it.What kind of datasource are you using?
alejandrobog
I'm using a generic List of custom business objects. I added the following to the OK Image Button: OnCommand="PopupButton_Command" CommandName="SelectCO" and it's now going there when I click it. I just have to figure out how to get the new value inserted into the List so that, the LinkButton reflects the new value when the popup goes away (and then the Label when the Gridview.RowUpdating event eventually fires)
David
You can use find it using:var ddl = YourGrid.FindControl("ddlCompany") as DropDownList;var companyId = ddl.SelectedValue
alejandrobog
@alejandrobog: I'd already put that in - was having some other issues but I've solved them. I'm going to put the final version of the sample code in another answer, but I'm going to accept this one so you get the proper credit for pointing me in the right direction.
David