views:

225

answers:

1

I've looked at a lot of similar questions here, but to no avail.

So here goes...

I'm creating a set of user controls that display a list of grid-like tables. Anyway, the objective is to list the grids, mess with the each grids data (client-side) and press save. The grids work great, but when I press save teh repeater in the VIEWER is always empty. Any help appreciated!

The Basic Layout Goes Like This

  1. PAGE
  2. ...updatePANEL
  3. ......usercontrolVIEWER
  4. .........saveBUTTON
  5. .........repeaterCONTROL
  6. ............usercontrolGRID
  7. ............usercontrolGRID
  8. ............ETC!

The PAGE Looks Like This

<asp:Content ID="Content2" ContentPlaceHolderID="body" runat="server">
    <asp:UpdatePanel id="udPanel" UpdateMode="Always" runat="server">
            <Triggers>
            </Triggers>
            <ContentTemplate>
               <uc:CommitImporterView ID="civData" runat="server" />
            </ContentTemplate>
    </asp:UpdatePanel>
</asp:Content>

public partial class CommitsAndActualsImporter : BaseForm
{
    #region EVENTS

    protected void Page_Init(object sender, EventArgs e)
    {
        setUpEventHandlers();

        if (!IsPostBack)
            initalize();
    }
    protected void Page_Load(object sender, EventArgs e)
    {
    }

    protected void myListOfGroups_DataBinding(object sender, EventArgs e)
    {
        //.. Code to bind the list goes here ...

        myListOfGroups.SelectedIndex = setSelectedIndex(collection);
    }
    protected void myListOfGroups_SelectedIndexChanged(object sender, EventArgs e)
    {
        myGroup = myListOfGroups.Find(selectedItem => selectedItem.Key == key);
        dataSource = buildViewDataSource(base.ProjectKey, base.AsOf, myGroup.FcrGroupKey, myGroup.ContractorKey, myGroup.WbsKey);

        civData.AsOf = base.AsOf;
        civData.ProjectKey = base.ProjectKey;
        civData.DataSource = dataSource;
        civData.DataBind();
    }

    #endregion

    #region METHODS

    private void initalize()
    {
        ContractorInviteItems dataSource = listGroups(ProjectKey, AsOf);
        myListOfGroups.DataSource = dataSource;
        myListOfGroups.DataBind();
    }
    private void setUpEvents()
    {
        myListOfGroups.DataBinding += new EventHandler(myListOfGroups_DataBinding);
        myListOfGroups.SelectedIndexChanged += new EventHandler(myListOfGroups_SelectedIndexChanged);
    }

    #endregion
}

The VIEWER User Control Looks Like This

<%@ Register Src="~/UserControls/CommitImporterGrid.ascx" TagName="CommitImporterGrid" TagPrefix="uc" %>

<asp:Button ID="btnSave" runat="server" Text="Save" />

<asp:HiddenField ID="hidAsOf" runat="server" Value="" />
<asp:HiddenField ID="hidProjectKey" runat="server" Value="0" />

<asp:Repeater ID="repCommitImporterView" runat="server">
    <ItemTemplate>
        <uc:CommitImporterGrid runat="server" />
    </ItemTemplate>
</asp:Repeater>

public partial class CommitImporterView : System.Web.UI.UserControl
{
    #region PROPERTIES & FIELDS

    private enum basisUsed
    {
        Dollars,
        Hours,
        IsInvalid
    }

    public Object DataSource { get; set; }

    public DateTime AsOf { get { return Convert.ToDateTime(hidAsOf.Value); } set { hidAsOf.Value = value.ToString(); } }
    public Int32 ProjectKey { get { return Convert.ToInt32(hidProjectKey.Value); } set { hidProjectKey.Value = value.ToString(); } }

    #endregion

    #region EVENTS

    protected override void OnInit(EventArgs e)
    {
        base.OnInit(e);
        setupEvents();
    }
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        this.DataBind();
    }
    protected override void OnPreRender(EventArgs e)
    {
        base.OnPreRender(e);
    }

    public override void DataBind()
    {
        base.DataBind();
    }

    protected void btnSave_Click(object sender, EventArgs e)
    {
        Int32 count = repCommitImporterView.Controls.Count;

        foreach (Control control in repCommitImporterView.Controls)
        {
            if (control is UserControls.CommitImporterGrid)
            {
                string stop = "";
            }

        }
    }

    protected void repCommitImporterView_DataBinding(object sender, EventArgs e)
    {
        if (DataSource == null)
            return;

        if (!IsPostBack)
        {
            Decimal totalSummaryCbudDollars = 0;
            Decimal totalSummaryCbudHours = 0;

            if (summaryValuesExist(out totalSummaryCbudDollars, out totalSummaryCbudHours))
                alignSummarizedRecords(totalSummaryCbudDollars, totalSummaryCbudHours);

            repCommitImporterView.DataSource = DataSource;
        }
    }
    protected void repCommitImporterView_ItemDataBound(object sender, RepeaterItemEventArgs e)
    {
        ContractorInviteCommitsAndActualsImport record = (ContractorInviteCommitsAndActualsImport)e.Item.DataItem;
        CommitImporterGrid grid = new CommitImporterGrid();
        grid = (UserControls.CommitImporterGrid)Page.LoadControl("~/UserControls/CommitImporterGrid.ascx") as UserControls.CommitImporterGrid;

        grid.AsOf = this.AsOf;
        grid.ProjectKey = this.ProjectKey;

        grid.DataSource = getDataSource(record);
        grid.DataBind();

        repCommitImporterView.Controls.Add(grid);
    }

    #endregion

    #region METHODS

    private void setupEvents()
    {
        btnSave.Click += new EventHandler(btnSave_Click);

        repCommitImporterView.DataBinding += new EventHandler(repCommitImporterView_DataBinding);
        repCommitImporterView.ItemDataBound += new RepeaterItemEventHandler(repCommitImporterView_ItemDataBound);
    }

    #endregion
}

The GRID User Control Lokks Like

A: 

It looks like you are only binding the Viewer control when the user changes a DropDownList, and it's not getting bound when the page/control loads, either on initial load or on postback. if you don't bind the repeater on postback, it won't have any of the data items you are expecting.

I would extract the contents of myListOfGroups_SelectedIndexChanged into a private method, and call it from myListOfGroups_SelectedIndexChanged and then also call it from Page_Load regardless of the state of IsPostBack (make sure it's called AFTER you databind myListOfGroups). when you call it from Page_Load, it will get the user's selection from the DropDownList and re-bind the Viewer control which binds the Repeater.

the key point here is that you always need to bind repeaters on every page load, regardless of the value of IsPostBack. otherwise there will be nothing in the repeater.

dave thieben