GridViewRow.DataItem is null

J

Jason

I have a page that dynamically generates controls based on a querystring. the
dynamic controls are:
a Wizard
a Wizard Step for each description selected by querystring.
an ObjectDataSource and GridView on each Step based on querystring.

Everything is working great until I click "finish" on the Wizard.
When I click finish I want to cycle through each Wizard Step and Save the
changes to each row in the GridView.

I can cycle through the Steps and find the GridView. I can cycle through
the GridViewRows and call UpdateRow using:
foreach (WizardStep step in frame.WizardSteps)
{
//not the final step
if (!step.StepType.Equals(WizardStepType.Finish))
{
GridView grid = (GridView)step.FindControl("grid_" +
frame.WizardSteps.IndexOf(step).ToString());
//ObjectDataSource ods =
(ObjectDataSource)step.FindControl("ods_" +
frame.WizardSteps.IndexOf(step).ToString());
foreach (GridViewRow row in grid.Rows)
{
if (row.RowType.Equals(DataControlRowType.DataRow))
grid.UpdateRow(row.RowIndex, false);
}
}
}
However when I do this I get "Object Instance not set to an Instance of the
Object." After some trial & error I have deteremined that the
GridViewRow.DataItem is null. This is because the GridView.DataSource is
null.

I don't know why it is null though, because if I go back to any step in the
wizard the grid is displayed and the updated values are displayed and ready
to be saved.

Any ideas why the DataItem is null when I cycle through the grid on the
finish command?
 
S

Steven Cheng[MSFT]

Hi Jason,

As for the GridView's UpdateRow method, it is designed for external
control(outside the GridView) to programmatically perform update operation
on the current EditRow in the Gridview. In other words, this method can
only accept the RowIndex of the current Row in EditMode. You can have a
look at the MSDN document on this method:

#GridView.UpdateRow Method
http://msdn2.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.
updaterow(VS.80).aspx

For example, we can use following method to update the GridView's EditRow
in each WizardStep:

=====================
protected void Wizard1_FinishButtonClick(object sender,
WizardNavigationEventArgs e)
{
foreach (WizardStep step in Wizard1.WizardSteps)
{

GridView gv = step.FindControl("GridView" +
(Wizard1.WizardSteps.IndexOf(step)+1)) as GridView;

if(gv != null)
{
gv.UpdateRow(gv.EditIndex, false);
gv.EditIndex = -1;
gv.DataBind();

}
}
}
===========================

BTW, if you want to update single row in each WizardStep, we can consider
using FormView or DetailsView control.

Anyway, it'll be more helpful if you can provide some further detailed
context info on the page you're developing so that we can try looking for
some other ideas or approachs.

Regards,

Steven Cheng
Microsoft Online Community Support


==================================================

When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.

==================================================


This posting is provided "AS IS" with no warranties, and confers no rights.



Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
J

Jason

Here is my code so far. I removed all the using statements except my custom
name spaces which hold business objects:

As you will see in the code. I want to add a gridview to each wizard step
for each item selected from the database. Each gridview has a template
column with a checkbox to mark the record "omit" or not. when I finish the
wizard I then want to save each record as omitted = true or false.

using SBI.RetailLink.BusinessLogic;
using SBI.RetailLink.DataAccess;

public partial class updaterecords : System.Web.UI.Page
{
private Wizard frame = new Wizard();
private int choice;
private DateTime week;

protected void Page_Init(object sender, EventArgs e)
{
Parameter p = new Parameter();
FinelineDescription fineline = new FinelineDescription();

choice = int.Parse(Request.QueryString["q"]);
week = DateTime.Parse(Request.QueryString["d"]);

p.Name = "data";
p.Direction = ParameterDirection.Input;
p.Type = TypeCode.Object;

frame.ID = "wzdfilterrecords";
frame.NavigationStyle.HorizontalAlign = HorizontalAlign.Left;
frame.NavigationStyle.VerticalAlign = VerticalAlign.Top;
frame.SideBarStyle.HorizontalAlign = HorizontalAlign.Left;
frame.SideBarStyle.VerticalAlign = VerticalAlign.Top;
frame.SideBarStyle.Width = Unit.Percentage(15);
frame.Width = Unit.Percentage(100);
frame.FinishButtonClick += new
WizardNavigationEventHandler(frame_FinishButtonClick);

foreach (FinelineDescription f in fineline.getDescriptions(choice,
week))
{
WizardStep step = new WizardStep();
GridView grid = new GridView();
ObjectDataSource ods = new
ObjectDataSource(getClassName(choice), "getRecords");

step.Title = f.Description;
step.ID = "step_" + frame.WizardSteps.Count;
step.StepType = (frame.WizardSteps.Count.Equals(0)) ?
WizardStepType.Start : WizardStepType.Step;

ods.ID = "ods_" + frame.WizardSteps.Count;
ods.SelectParameters.Add("weekBeginDate", week.ToString());
ods.SelectParameters.Add("finelineDescription", f.Description);
ods.UpdateMethod = "updateOmitStatus";
ods.UpdateParameters.Add(p);

grid.AutoGenerateColumns = false;
grid.DataSourceID = ods.ID;
grid.ID = "grid_" + frame.WizardSteps.Count;
grid.Columns.Add(addCheckBoxColumn());
grid.Columns.Add(addColumn("DistrobutionCenterID", "DC ID",
Unit.Pixel(45)));
grid.Columns.Add(addColumn("DistrobutionCenterName", "DC Name",
Unit.Percentage(25)));
grid.Columns.Add(addItemNumberTemplate("Item #", Unit.Pixel(50)));
grid.Columns.Add(addItemDescriptionTemplate("Item Description",
Unit.Percentage(20)));
grid.Columns.Add(addColumn("StoreOnHand", "Store OH",
Unit.Pixel(55)));
grid.Columns.Add(addColumn("InTransitOnHand", "In Transit OH",
Unit.Pixel(55)));
grid.Columns.Add(addColumn("WarehouseOnHand", "Warehouse OH",
Unit.Pixel(55)));
grid.Columns.Add(addColumn("CurrentOrder", "Current Order",
Unit.Pixel(55)));
grid.Width = Unit.Percentage(100);

step.Controls.Add(ods);
step.Controls.Add(grid);
frame.WizardSteps.Add(step);
}
if (frame.WizardSteps.Count > 0)
{
WizardStep finalstep = new WizardStep();
Literal lit = new Literal();

finalstep.Title = "Commit Changes";
finalstep.ID = "step_" + frame.WizardSteps.Count;
finalstep.Controls.Add(lit);
finalstep.StepType = WizardStepType.Finish;
lit.Text = "Click Finish to commit changes and generate a
report.";
frame.WizardSteps.Add(finalstep);
hldrwizard.Controls.Add(frame);
}
else
{
Literal norecords = new Literal();
norecords.Text = string.Format("There are no {0} on
{1}.",getRecordType(choice), week.ToShortDateString());
hldrwizard.Controls.Add(norecords);
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
lbldate.Text = week.ToShortDateString();
lblrecordtype.Text = getRecordType(choice);
if (frame.WizardSteps.Count > 0)
frame.ActiveStepIndex = 0;
}
}
protected void frame_FinishButtonClick(object sender,
WizardNavigationEventArgs e)
{
List<GridView> grids = new List<GridView>();
foreach (WizardStep step in frame.WizardSteps)
{
//not the final step
if (!step.StepType.Equals(WizardStepType.Finish))
{
GridView grid = (GridView)step.FindControl("grid_" +
frame.WizardSteps.IndexOf(step).ToString());
//ObjectDataSource ods =
(ObjectDataSource)step.FindControl("ods_" +
frame.WizardSteps.IndexOf(step).ToString());
foreach (GridViewRow row in grid.Rows)
{
if (row.RowType.Equals(DataControlRowType.DataRow))
{
grid.UpdateRow(row.RowIndex, false);
}
}
}
}
if (choice.Equals(3))
ScrubDataObject.transferToLiveData(week);
}

private string getRecordType(int choice)
{
switch (choice)
{
case 1:
return "Omit Records";
case 2:
return "Report Records";
case 3:
return "New Records";
default: return string.Empty;
}
}
private string getClassName(int choice)
{
switch (choice)
{
case 1:
return "SBI.RetailLink.DataAccess.OmitDataObject";
case 2:
return "SBI.RetailLink.DataAccess.ReportDataObject";
case 3:
return "SBI.RetailLink.DataAccess.ScrubDataObject";
default: return string.Empty;
}
}
private TemplateField addCheckBoxColumn()
{
TemplateField field = new TemplateField();

field.ItemTemplate = new GridViewCheckBoxTemplate();
field.ItemStyle.HorizontalAlign = HorizontalAlign.Center;
field.ItemStyle.VerticalAlign = VerticalAlign.Middle;
field.ItemStyle.Width = Unit.Pixel(20);
field.HeaderText = "Omit";
field.HeaderStyle.VerticalAlign = VerticalAlign.Bottom;
field.HeaderStyle.Width = Unit.Pixel(20);

return field;
}
private TemplateField addItemDescriptionTemplate(string header, Unit
width)
{
TemplateField field = new TemplateField();
field.ItemTemplate = new GridViewItemDescriptionTemplate();
field.ItemStyle.HorizontalAlign = HorizontalAlign.Center;
field.ItemStyle.VerticalAlign = VerticalAlign.Middle;
field.ItemStyle.Width = width;
field.HeaderText = header;
field.HeaderStyle.VerticalAlign = VerticalAlign.Bottom;
field.HeaderStyle.Width = width;

return field;
}
private TemplateField addItemNumberTemplate(string header, Unit width)
{
TemplateField field = new TemplateField();
field.ItemTemplate = new GridViewItemNumberTemplate();
field.ItemStyle.HorizontalAlign = HorizontalAlign.Center;
field.ItemStyle.VerticalAlign = VerticalAlign.Middle;
field.ItemStyle.Width = width;
field.HeaderText = header;
field.HeaderStyle.VerticalAlign = VerticalAlign.Bottom;
field.HeaderStyle.Width = width;

return field;
}
private BoundField addColumn(string dataField, string header, Unit width)
{
BoundField field = new BoundField();

field.DataField = dataField;
field.ItemStyle.VerticalAlign = VerticalAlign.Top;
field.ItemStyle.Width = width;
field.HeaderText = header;
field.HeaderStyle.VerticalAlign = VerticalAlign.Bottom;
field.HeaderStyle.Width = width;
field.ReadOnly = true;

return field;
}
}
// Create a template class to represent a dynamic template column.
public class GridViewCheckBoxTemplate : ITemplate
{
public GridViewCheckBoxTemplate()
{
}
public void InstantiateIn(System.Web.UI.Control container)
{
CheckBox check = new CheckBox();
check.AutoPostBack = false;
check.CausesValidation = false;
check.DataBinding += new EventHandler(check_DataBinding);
container.Controls.Add(check);
}

private void check_DataBinding(Object sender, EventArgs e)
{
CheckBox c = (CheckBox)sender;
GridViewRow row = (GridViewRow)c.NamingContainer;
c.Checked = (bool)DataBinder.Eval(row.DataItem, "OmitReport");
}
}
public class GridViewItemDescriptionTemplate : ITemplate
{
public GridViewItemDescriptionTemplate()
{
}
public void InstantiateIn(System.Web.UI.Control container)
{
Label lbl = new Label();
lbl.DataBinding += new EventHandler(lbl_DataBinding);
container.Controls.Add(lbl);
}

private void lbl_DataBinding(Object sender, EventArgs e)
{
Label l = (Label)sender;
GridViewRow row = (GridViewRow)l.NamingContainer;
l.Text = ((ItemDescription)DataBinder.Eval(row.DataItem,
"ItemDescription")).itemDescription;
}
}
public class GridViewItemNumberTemplate : ITemplate
{
public GridViewItemNumberTemplate()
{
}
public void InstantiateIn(System.Web.UI.Control container)
{
Label lbl = new Label();
lbl.DataBinding += new EventHandler(lbl_DataBinding);
container.Controls.Add(lbl);
}

private void lbl_DataBinding(Object sender, EventArgs e)
{
Label l = (Label)sender;
GridViewRow row = (GridViewRow)l.NamingContainer;
l.Text = ((ItemDescription)DataBinder.Eval(row.DataItem,
"ItemDescription")).itemNumber;
}
}
 
S

Steven Cheng[MSFT]

Thank you for the response Jason,

Due to the complex code logic, I think it'll be much more helpful if you
can provide me a complete aspx template+code behind, if the database is two
complex, you can just create a dummy datatable or Dataset to simulate it.
Then, I can try performing some tests upon them.

BTW, currently, you'll dynamically create Gridview and DataSource control
pairs and add them into each WizardStep, correct? I have one suggestion,
since most of the GridView and DataSource control pair and their
interactive and communication logic is reusable, you can consider creating
an ASP.NET ascx user control which contains such Gridview and DataSource
control pair, also you can define some custom properties on the usercontrol
for manipulation requirement. In addition, since we can dynamically load
Usercontrol into page, you can dynamically load the usercontrol and add
them into Wizardstep instead of add individual Gridview and datasource
controls, most of the code can be encapsulated in ascx usercontrol's code.

Hope this helps.

Regards,

Steven Cheng
Microsoft Online Community Support


==================================================

When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.

==================================================


This posting is provided "AS IS" with no warranties, and confers no rights.
 
J

Jason

The aspx file is fairly simple:

<%@ Page Language="C#" AutoEventWireup="true"
CodeFile="updaterecords.aspx.cs" Inherits="updaterecords" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Retail Link: Filter Records</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:panel ID="pnlheader" runat="server">
Selected Date:
<asp:Label ID="lbldate" runat="server"></asp:Label><br />
Record Type:
<asp:Label ID="lblrecordtype"
runat="server"></asp:Label></asp:panel>
</div>
<asp:placeHolder ID="hldrwizard" runat="server"></asp:placeHolder>
<br />
<br />
<asp:HyperLink ID="lnkmainmenu" runat="server"
NavigateUrl="~/Default.aspx">Return to Main Menu</asp:HyperLink>
</form>
</body>
</html>

then I have my custom business objects:
-------------------------------------------------------------------------------------------
using EX = Microsoft.Practices.EnterpriseLibrary.ExceptionHandling;
using DATA = Microsoft.Practices.EnterpriseLibrary.Data;

namespace SBI.RetailLink.DataAccess
{
public class ItemDescription
{
private int _itemnumber;
private string _description;

public int itemNumber
{
get { return _itemnumber; }
set { _itemnumber = value; }
}
public string itemDescription
{
get { return _description; }
set { _description = value; }
}

public ItemDescription()
{
}
}

public class ItemDescriptionObject
{
public ItemDescriptionObject()
{
}

public List<ItemDescription> getAllItemDescriptions()
{
DATA.Database db =
DATA.DatabaseFactory.CreateDatabase("RetailLinkReport");
List<ItemDescription> items = new List<ItemDescription>();

try
{
using (IDataReader reader =
db.ExecuteReader(db.GetStoredProcCommand("usp_item_description__select_all")))
{
while (reader.Read())
{
ItemDescription item = new ItemDescription();
item.itemNumber =
int.Parse(reader["item_number"].ToString());
item.itemDescription =
reader["item_description"].ToString();
items.Add(item);
}
}
}
catch (Exception e)
{
EX.ExceptionPolicy.HandleException(e, "DB");
}
return items;
}

public static void updateItemDescription(ItemDescription item)
{
DATA.Database db =
DATA.DatabaseFactory.CreateDatabase("RetailLinkReport");

DbCommand command =
db.GetStoredProcCommand("usp_item_description__update");
db.AddInParameter(command, "item_number", DbType.Int32,
item.itemNumber);
db.AddInParameter(command, "item_description", DbType.String,
item.itemDescription);

try
{
db.ExecuteNonQuery(command);
}
catch (DbException e) { EX.ExceptionPolicy.HandleException(e,
"DB"); }
}
}
}
-------------------------------------------------------------------------------------------
using DATA = Microsoft.Practices.EnterpriseLibrary.Data;
using EX = Microsoft.Practices.EnterpriseLibrary.ExceptionHandling;

namespace SBI.RetailLink.DataAccess
{
public class ScrubData
{
private DateTime _week_begin_date;
private int _dc_id;
private string _dc_name;
private string _fine_line_description;
private ItemDescription _itemdescription;
private int _point_of_sale;
private int _store_on_hand;
private int _in_transit_on_hand;
private int _warehouse_on_hand;
private int _current_order;
private bool _omit_report;

public DateTime WeekBeginDate
{
get { return _week_begin_date; }
set { _week_begin_date = value; }
}
public int DistrobutionCenterID
{
get { return _dc_id; }
set { _dc_id = value; }
}
public string DistrobutionCenterName
{
get { return _dc_name; }
set { _dc_name = value; }
}
public string FinelineDescription
{
get { return _fine_line_description; }
set { _fine_line_description = value; }
}
public ItemDescription ItemDescription
{
get { return _itemdescription; }
set { _itemdescription = value; }
}
public int PointOfSale
{
get { return _point_of_sale; }
set { _point_of_sale = value; }
}
public int StoreOnHand
{
get { return _store_on_hand; }
set { _store_on_hand = value; }
}
public int InTransitOnHand
{
get { return _in_transit_on_hand; }
set { _in_transit_on_hand = value; }
}
public int WarehouseOnHand
{
get { return _warehouse_on_hand; }
set { _warehouse_on_hand = value; }
}
public int CurrentOrder
{
get { return _current_order; }
set { _current_order = value; }
}
public bool OmitReport
{
get { return _omit_report; }
set { _omit_report = value; }
}

public ScrubData()
{
}
}

public class ScrubDataObject
{
public ScrubDataObject()
{
}

public static void clearExistingRecords(DateTime weekBeginDate)
{
DATA.Database db =
DATA.DatabaseFactory.CreateDatabase("RetailLinkReport");

DbCommand command =
db.GetStoredProcCommand("usp_scrub_data__delete");
db.AddInParameter(command, "date", DbType.Date, weekBeginDate);
try
{
db.ExecuteNonQuery(command);
}
catch (DbException e) { EX.ExceptionPolicy.HandleException(e,
"DB"); }
}
public static void configureFinelineDescriptions(DateTime
weekBeginDate)
{
DATA.Database db =
DATA.DatabaseFactory.CreateDatabase("RetailLinkReport");

DbCommand command =
db.GetStoredProcCommand("usp_scrub_data__update_fineline_description");
db.AddInParameter(command, "date", DbType.Date, weekBeginDate);
try
{
db.ExecuteNonQuery(command);
}
catch (DbException e) { EX.ExceptionPolicy.HandleException(e,
"DB"); }
}

public static List<ScrubData> getFinelineDescriptions(DateTime
weekBeginDate)
{
List<ScrubData> types = new List<ScrubData>();
DATA.Database db =
DATA.DatabaseFactory.CreateDatabase("RetailLinkReport");

DbCommand command =
db.GetStoredProcCommand("usp_scrub_data__select_fineline_description_distinct");
db.AddInParameter(command, "date", DbType.Date, weekBeginDate);
try
{
IDataReader reader = db.ExecuteReader(command);
while (reader.Read())
{
ScrubData rec = new ScrubData();
rec.FinelineDescription =
reader["fine_line_description"].ToString();
types.Add(rec);
}

}
catch (DbException e) { EX.ExceptionPolicy.HandleException(e,
"DB"); }
return types;
}
public static List<ScrubData> getRecords(DateTime weekBeginDate,
string finelineDescription)
{
bool value;
List<ScrubData> types = new List<ScrubData>();
DATA.Database db =
DATA.DatabaseFactory.CreateDatabase("RetailLinkReport");

DbCommand command =
db.GetStoredProcCommand("usp_scrub_data__select");
db.AddInParameter(command, "date", DbType.DateTime,
weekBeginDate);
db.AddInParameter(command, "fineline", DbType.String,
finelineDescription);
try
{
IDataReader reader = db.ExecuteReader(command);
while (reader.Read())
{
ScrubData rec = new ScrubData();
ItemDescription item = new ItemDescription();

item.itemNumber =
int.Parse(reader["item_number"].ToString());
item.itemDescription =
reader["item_description"].ToString();

rec.WeekBeginDate = weekBeginDate;
rec.FinelineDescription = finelineDescription;
rec.DistrobutionCenterID =
int.Parse(reader["dc_id"].ToString());
rec.DistrobutionCenterName = reader["dc_name"].ToString();
rec.PointOfSale =
int.Parse(reader["point_of_sale"].ToString());
rec.StoreOnHand =
int.Parse(reader["store_on_hand"].ToString());
rec.InTransitOnHand =
int.Parse(reader["in_transit_on_hand"].ToString());
rec.WarehouseOnHand =
int.Parse(reader["warehouse_on_hand"].ToString());
rec.CurrentOrder =
int.Parse(reader["current_order"].ToString());
bool.TryParse(reader["omit_report"].ToString(),out value);
rec.OmitReport = value;
rec.ItemDescription = item;

types.Add(rec);
}
}
catch (DbException e) { EX.ExceptionPolicy.HandleException(e,
"DB"); }
return types;
}
public static void updateOmitStatus(ScrubData data)
{
DATA.Database db =
DATA.DatabaseFactory.CreateDatabase("RetailLinkReport");

DbCommand command =
db.GetStoredProcCommand("usp_scrub_data__update_omit");
db.AddInParameter(command, "date", DbType.DateTime,
data.WeekBeginDate);
db.AddInParameter(command, "dc_id", DbType.Int16,
data.DistrobutionCenterID);
db.AddInParameter(command, "item_number", DbType.Int16,
data.ItemDescription.itemNumber);
db.AddInParameter(command, "omit", DbType.Boolean,
data.OmitReport);

try
{
db.ExecuteNonQuery(command);
}
catch (DbException e) { EX.ExceptionPolicy.HandleException(e,
"DB"); }
}
public static void transferToLiveData(DateTime weekBeginDate)
{
DATA.Database db =
DATA.DatabaseFactory.CreateDatabase("RetailLinkReport");

DbCommand command =
db.GetStoredProcCommand("usp_scrub_data__transfer");
db.AddInParameter(command, "date", DbType.DateTime,
weekBeginDate);

try
{
db.ExecuteNonQuery(command);
}
catch (DbException e) { EX.ExceptionPolicy.HandleException(e,
"DB"); }
}
}
}
-------------------------------------------------------------------------------------------

there are also business objects for ReportData and OmitData. These objects
have the same properties as ScrubData.

ScrubData is a table for staging data (xls downloads) before it is committed
to "active" db tables. ReportData is a table used to generate reports.
OmitData is a table used to store records that were on the xls, but we do not
want to use on the report. This way we can track what we downloaded and what
we are reporting on.

I though about using a ascx instead of straight code, but this form is the
only form that will need this dynamically generated form so i decided to
write the code from scratch.

If you need anything else let me know.
 
S

Steven Cheng[MSFT]

Thanks for your response and the detailed code,

I'll try perform some tests upon them. And there is still some helper
classes missed, such as the FinelineDescription. Anyway, I'll try creating
a hard code list to simulate it. Also, if you get any progress in the
meantime, please feel free to post here.

Regards,

Steven Cheng
Microsoft Online Community Support


==================================================

When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.

==================================================


This posting is provided "AS IS" with no warranties, and confers no rights.
 
J

Jason

here is the FinelineDescription code:

using SBI.RetailLink.DataAccess;
using IO = System.IO;
using XLS = Microsoft.Office.Interop.Excel;

namespace SBI.RetailLink.BusinessLogic
{
public class UploadDataDump : IDisposable
{
[Flags]
private enum _fields
{
Whse_Nbr = 1,
Whse_Name,
Item_Nbr,
Item_Flags,
Item_Desc_1,
Fineline,
Fineline_Desc,
VNPK_Qty,
POS_Qty,
Curr_Str_On_Hand_Qty,
Curr_Str_In_Transit_Qty,
Curr_Whse_On_Hand_Qty,
POS_Cases,
STROH_Cases,
INTRANS_Cases,
WHOH_Cases,
Curr_Whse_SS_Order_Cases
}

private bool disposed = false;
private string _filename, _errormessage, _wsname;
private XLS.Application _xl;
private XLS.Workbook _book;
private XLS.Worksheet _sheet;
private XLS.Range _range;

public string fileName
{
get { return _filename; }
set { _filename = value; }
}
public string errorMessage
{
get { return _errormessage; }
}
internal string newFile
{
get { return _filename.Replace(".xls", "_scrub.xls"); }
}

public UploadDataDump()
{
InitializeExcel();
}
public UploadDataDump(string FileName)
{
InitializeExcel();
fileName = FileName;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
public void ScrubHeader()
{
if (_xl == null)
return;

OpenFile();
SaveFileAs();
DeleteRows();
SaveFile();
}
public Boolean ValidateFile()
{
if (_xl == null)
return false;

int f_index;
string fieldname, enumname;
foreach (_fields f in Enum.GetValues(typeof(_fields)))
{
f_index = (int)f;
enumname = f.ToString().Replace("_", " ");
_range = (XLS.Range)_sheet.Cells[1, f_index];
fieldname = (string)_range.Text;
if (fieldname != enumname)
{
_errormessage = string.Format("column should be '{0}',
but is '{1}'.", enumname, fieldname);
CloseFile();
DeleteFile();
return false;
}
}
CloseFile();
return true;
}
public void TransferToDatabase( DateTime Date)
{
CloseFile();

//get records from excel
DataSet ds = new DataSet();
string cnnstr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source="
+ newFile + ";Extended Properties=\"Excel 8.0;IMEX=1;HDR=YES\";";
using (OleDbConnection cnn = new OleDbConnection(cnnstr))
{
OleDbCommand cmd = new OleDbCommand("Select * from [" +
_wsname + "$]", cnn);
OleDbDataAdapter adp = new OleDbDataAdapter(cmd);
adp.Fill(ds, "tbl");
}
//add the date field to the table so bulk copy will work
ds.Tables[0].Columns.Add("week_begin_date", typeof(DateTime));
foreach (DataRow row in ds.Tables[0].Rows)
row["week_begin_date"] = Date;

//bulk copy to server.
using (SqlConnection sqlcnn = new
SqlConnection(WebConfigurationManager.ConnectionStrings["RetailLinkReport"].ConnectionString))
{
sqlcnn.Open();
ScrubDataObject.clearExistingRecords(Date);
using (SqlBulkCopy bulk = new SqlBulkCopy(sqlcnn))
{
bulk.ColumnMappings.Add("week_begin_date",
"week_begin_date");
bulk.ColumnMappings.Add("Whse Nbr", "dc_id");
bulk.ColumnMappings.Add("Whse Name", "dc_name");
bulk.ColumnMappings.Add("Fineline Desc",
"fine_line_description");
bulk.ColumnMappings.Add("Item Nbr", "item_number");
bulk.ColumnMappings.Add("Item Desc 1",
"item_description");
bulk.ColumnMappings.Add("POS Cases", "point_of_sale");
bulk.ColumnMappings.Add("STROH Cases", "store_on_hand");
bulk.ColumnMappings.Add("INTRANS Cases",
"in_transit_on_hand");
bulk.ColumnMappings.Add("WHOH Cases",
"warehouse_on_hand");
bulk.ColumnMappings.Add("Curr Whse SS Order Cases",
"current_order");
bulk.BatchSize = 1000;
bulk.DestinationTableName = "[dbo].[scrub_data]";
bulk.WriteToServer(ds.Tables[0]);
}
ScrubDataObject.configureFinelineDescriptions(Date);
}
DeleteFile();
}

private void InitializeExcel()
{
_xl = new XLS.Application();
if (_xl == null)
_errormessage = "Excel could not be opened, please try
again.";
else
_xl.Visible = false;
}
private void OpenFile()
{
if (_book == null)
{
_book = _xl.Workbooks.Open(fileName, Missing.Value,
Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value,
Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value,
Missing.Value, Missing.Value, Missing.Value);
_sheet = (XLS.Worksheet)_book.ActiveSheet;
_wsname = (string)_sheet.Name;
}
}
private void CloseFile()
{
if (_book != null)
{
_book.Close(Missing.Value, Missing.Value, Missing.Value);
_book = null;
}
}
private void SaveFileAs()
{
DeleteFile();
_book.SaveAs(newFile, XLS.XlFileFormat.xlWorkbookNormal,
Missing.Value, Missing.Value, Missing.Value, Missing.Value,
XLS.XlSaveAsAccessMode.xlExclusive, Missing.Value, Missing.Value,
Missing.Value, Missing.Value, Missing.Value);
}
private void SaveFile()
{
_book.Save();
}
private void DeleteFile()
{
if (IO.File.Exists(newFile))
IO.File.Delete(newFile);
}
private void DeleteRows()
{
_range = _sheet.get_Range("A1", "Q23");
_range.Delete(XLS.XlDeleteShiftDirection.xlShiftUp);
}
private void Dispose(bool disposing)
{
if (!this.disposed)
{
// If disposing equals true, dispose all managed and
unmanaged resources.
if (disposing)
{
// Dispose managed resources.
//none in this code
}

// Call the appropriate methods to clean up unmanaged
resources here.
// If disposing is false, only the following code is executed.
if (_book != null)
{
try { _book.Close(Missing.Value, Missing.Value,
Missing.Value); } catch { }

System.Runtime.InteropServices.Marshal.ReleaseComObject(_book);
_book = null;
}
if (_xl != null)
{
_xl.Workbooks.Close();
_xl.Quit();

System.Runtime.InteropServices.Marshal.ReleaseComObject(_xl);
_xl = null;
}
if (_sheet != null)
{

System.Runtime.InteropServices.Marshal.ReleaseComObject(_sheet);
_sheet = null;
}
if (_range != null)

System.Runtime.InteropServices.Marshal.ReleaseComObject(_range);
GC.Collect();
}
disposed = true;
}
}

public class FinelineDescription
{
private string _fine_line_description;

public string Description
{
get { return _fine_line_description; }
set { _fine_line_description = value; }
}

public List<FinelineDescription> getDescriptions(int fromTable,
DateTime weekBeginDate)
{
List<FinelineDescription> list = new List<FinelineDescription>();
switch (fromTable)
{
case 1:
foreach (OmitData o in
OmitDataObject.getFinelineDescriptions(weekBeginDate))
{
FinelineDescription item = new FinelineDescription();
item.Description = o.FinelineDescription;
list.Add(item);
}
break;
case 2:
foreach(ReportData r in
ReportDataObject.getFinelineDescriptions(weekBeginDate))
{
FinelineDescription item = new FinelineDescription();
item.Description = r.FinelineDescription;
list.Add(item);
}
break;
case 3:
foreach (ScrubData s in
ScrubDataObject.getFinelineDescriptions(weekBeginDate))
{
FinelineDescription item = new FinelineDescription();
item.Description = s.FinelineDescription;
list.Add(item);
}
break;
}
return list;
}
}
}
 
J

Jason

I just ran a simple test to see if other control values would be null.

I added another WizardStep to my wizard. This step has a Texbox control. I
step through each WizardStep and look for the TextBox. I assign the value of
the text box to a string to check for the null error.

The TextBox retains the value and I can retrieve the value from the control.
There is no data binding that I am aware of with the text box. so why would
this control hold it's value, but the GridView not?
 
S

Steven Cheng[MSFT]

Thank you for the quick response Jason,

Nevermind, I've created a dummy FinelineDescription class to performed the
test and I've got your page running :). And after some test, I think the
problem here is still as mentioned in my first reply message. The
GridView.UpdateRow method will only update the current EditRow (the current
EditIndex row in the GridView) or those Rows which has Twoway databinding
Columns(the columns/template you created dyanmically are all one-way
databinding---just for display). So for your Gridview(dynamically created),
all the rows are in readonly/normal mode, so when you call update, the
dataobject's updatemethod did get executed, however, it passed Null into
the DataObject (ScrubDataObject).... Here is my modfied test page which
use a dummy finelineDescription class(I also use fake data for the
ScrubDataObject and its ItemDescription member...) :

============aspx==============
remain the same

======code behind=============
public partial class Common_DynamicWizardGridView : System.Web.UI.Page
{
private Wizard frame = new Wizard();
private int choice;
private DateTime week;

protected void Page_Init(object sender, EventArgs e)
{
Parameter p = new Parameter();
FinelineDescription fineline = new FinelineDescription();

//choice = int.Parse(Request.QueryString["q"]);
//week = DateTime.Parse(Request.QueryString["d"]);


choice = 3;
week = DateTime.Now;

p.Name = "data";
p.Direction = ParameterDirection.Input;
p.Type = TypeCode.Object;

frame.ID = "wzdfilterrecords";
frame.NavigationStyle.HorizontalAlign = HorizontalAlign.Left;
frame.NavigationStyle.VerticalAlign = VerticalAlign.Top;
frame.SideBarStyle.HorizontalAlign = HorizontalAlign.Left;
frame.SideBarStyle.VerticalAlign = VerticalAlign.Top;
frame.SideBarStyle.Width = Unit.Percentage(15);
frame.Width = Unit.Percentage(100);
frame.FinishButtonClick += new
WizardNavigationEventHandler(frame_FinishButtonClick);

foreach (FinelineDescription f in
FinelineDescription.getDescriptions(choice,
week))
{
WizardStep step = new WizardStep();
GridView grid = new GridView();
grid.EditIndex = 0;
ObjectDataSource ods = new
ObjectDataSource(getClassName(choice), "getRecords");

step.Title = f.Description;
step.ID = "step_" + frame.WizardSteps.Count;
step.StepType = (frame.WizardSteps.Count.Equals(0)) ?
WizardStepType.Start : WizardStepType.Step;

ods.ID = "ods_" + frame.WizardSteps.Count;
ods.SelectParameters.Add("weekBeginDate", week.ToString());
ods.SelectParameters.Add("finelineDescription", f.Description);
ods.UpdateMethod = "updateOmitStatus";
ods.UpdateParameters.Add(p);

grid.AutoGenerateColumns = false;
grid.DataSourceID = ods.ID;
grid.ID = "grid_" + frame.WizardSteps.Count;
grid.Columns.Add(addCheckBoxColumn());
grid.Columns.Add(addColumn("DistrobutionCenterID", "DC ID",
Unit.Pixel(45)));
grid.Columns.Add(addColumn("DistrobutionCenterName", "DC Name",
Unit.Percentage(25)));
grid.Columns.Add(addItemNumberTemplate("Item #",
Unit.Pixel(50)));
grid.Columns.Add(addItemDescriptionTemplate("Item Description",
Unit.Percentage(20)));
grid.Columns.Add(addColumn("StoreOnHand", "Store OH",
Unit.Pixel(55)));
grid.Columns.Add(addColumn("InTransitOnHand", "In Transit OH",
Unit.Pixel(55)));
grid.Columns.Add(addColumn("WarehouseOnHand", "Warehouse OH",
Unit.Pixel(55)));
grid.Columns.Add(addColumn("CurrentOrder", "Current Order",
Unit.Pixel(55)));
grid.Width = Unit.Percentage(100);

step.Controls.Add(ods);
step.Controls.Add(grid);
frame.WizardSteps.Add(step);
}
if (frame.WizardSteps.Count > 0)
{
WizardStep finalstep = new WizardStep();
Literal lit = new Literal();

finalstep.Title = "Commit Changes";
finalstep.ID = "step_" + frame.WizardSteps.Count;
finalstep.Controls.Add(lit);
finalstep.StepType = WizardStepType.Finish;
lit.Text = "Click Finish to commit changes and generate a
report.";

frame.WizardSteps.Add(finalstep);
hldrwizard.Controls.Add(frame);
}
else
{
Literal norecords = new Literal();
norecords.Text = string.Format("There are no {0} on
{1}.",getRecordType(choice), week.ToShortDateString());
hldrwizard.Controls.Add(norecords);
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
lbldate.Text = week.ToShortDateString();
lblrecordtype.Text = getRecordType(choice);
if (frame.WizardSteps.Count > 0)
frame.ActiveStepIndex = 0;
}
}
protected void frame_FinishButtonClick(object sender,
WizardNavigationEventArgs e)
{

Response.Write("<br/>frame_FinishButtonClick.............");
List<GridView> grids = new List<GridView>();
foreach (WizardStep step in frame.WizardSteps)
{
//not the final step
if (!step.StepType.Equals(WizardStepType.Finish))
{
GridView grid = (GridView)step.FindControl("grid_" +
frame.WizardSteps.IndexOf(step).ToString());
ObjectDataSource ods =
(ObjectDataSource)step.FindControl("ods_" +
frame.WizardSteps.IndexOf(step).ToString());

foreach (GridViewRow row in grid.Rows)
{
if (row.RowType.Equals(DataControlRowType.DataRow))
{
Response.Write("<br/>BeforeUpdate: " +
row.NamingContainer.ID + "__" + row.RowIndex);
grid.EditIndex = row.RowIndex;
grid.UpdateRow(row.RowIndex, false);

}
}
}
}
if (choice.Equals(3))
ScrubDataObject.transferToLiveData(week);
}

private string getRecordType(int choice)
{
switch (choice)
{
case 1:
return "Omit Records";
case 2:
return "Report Records";
case 3:
return "New Records";
default: return string.Empty;
}
}
private string getClassName(int choice)
{
switch (choice)
{
case 1:
return "SBI.RetailLink.DataAccess.OmitDataObject";
case 2:
return "SBI.RetailLink.DataAccess.ReportDataObject";
case 3:
return "SBI.RetailLink.DataAccess.ScrubDataObject";
default: return string.Empty;
}
}
private TemplateField addCheckBoxColumn()
{
TemplateField field = new TemplateField();

field.ItemTemplate = new GridViewCheckBoxTemplate();
field.ItemStyle.HorizontalAlign = HorizontalAlign.Center;
field.ItemStyle.VerticalAlign = VerticalAlign.Middle;
field.ItemStyle.Width = Unit.Pixel(20);
field.HeaderText = "Omit";
field.HeaderStyle.VerticalAlign = VerticalAlign.Bottom;
field.HeaderStyle.Width = Unit.Pixel(20);

return field;
}
private TemplateField addItemDescriptionTemplate(string header, Unit
width)
{
TemplateField field = new TemplateField();
field.ItemTemplate = new GridViewItemDescriptionTemplate();
field.ItemStyle.HorizontalAlign = HorizontalAlign.Center;
field.ItemStyle.VerticalAlign = VerticalAlign.Middle;
field.ItemStyle.Width = width;
field.HeaderText = header;
field.HeaderStyle.VerticalAlign = VerticalAlign.Bottom;
field.HeaderStyle.Width = width;

return field;
}
private TemplateField addItemNumberTemplate(string header, Unit width)
{
TemplateField field = new TemplateField();
field.ItemTemplate = new GridViewItemNumberTemplate();
field.ItemStyle.HorizontalAlign = HorizontalAlign.Center;
field.ItemStyle.VerticalAlign = VerticalAlign.Middle;
field.ItemStyle.Width = width;
field.HeaderText = header;
field.HeaderStyle.VerticalAlign = VerticalAlign.Bottom;
field.HeaderStyle.Width = width;

return field;
}
private BoundField addColumn(string dataField, string header, Unit
width)
{
BoundField field = new BoundField();

field.DataField = dataField;
field.ItemStyle.VerticalAlign = VerticalAlign.Top;
field.ItemStyle.Width = width;
field.HeaderText = header;
field.HeaderStyle.VerticalAlign = VerticalAlign.Bottom;
field.HeaderStyle.Width = width;
field.ReadOnly = true;

return field;
}
}
// Create a template class to represent a dynamic template column.
public class GridViewCheckBoxTemplate : ITemplate
{
public GridViewCheckBoxTemplate()
{
}
public void InstantiateIn(System.Web.UI.Control container)
{
CheckBox check = new CheckBox();
check.AutoPostBack = false;
check.CausesValidation = false;
check.DataBinding += new EventHandler(check_DataBinding);
container.Controls.Add(check);
}

private void check_DataBinding(Object sender, EventArgs e)
{
CheckBox c = (CheckBox)sender;
GridViewRow row = (GridViewRow)c.NamingContainer;
c.Checked = (bool)DataBinder.Eval(row.DataItem, "OmitReport");
}
}
public class GridViewItemDescriptionTemplate : ITemplate
{
public GridViewItemDescriptionTemplate()
{
}
public void InstantiateIn(System.Web.UI.Control container)
{
Label lbl = new Label();
lbl.DataBinding += new EventHandler(lbl_DataBinding);
container.Controls.Add(lbl);
}

private void lbl_DataBinding(Object sender, EventArgs e)
{
Label l = (Label)sender;
GridViewRow row = (GridViewRow)l.NamingContainer;
l.Text = ((ItemDescription)DataBinder.Eval(row.DataItem,
"ItemDescription")).itemDescription;
}
}
public class GridViewItemNumberTemplate : ITemplate
{
public GridViewItemNumberTemplate()
{
}
public void InstantiateIn(System.Web.UI.Control container)
{
Label lbl = new Label();
lbl.DataBinding += new EventHandler(lbl_DataBinding);
container.Controls.Add(lbl);
}

private void lbl_DataBinding(Object sender, EventArgs e)
{
Label l = (Label)sender;
GridViewRow row = (GridViewRow)l.NamingContainer;
l.Text = ((ItemDescription)DataBinder.Eval(row.DataItem,
"ItemDescription")).itemNumber.ToString();


}

}
==================================

======my customized dummy classes========
public class ScrubDataObject
{


.........................



public static List<ScrubData> getRecords(DateTime weekBeginDate,
string finelineDescription)
{
bool value;
List<ScrubData> types = new List<ScrubData>();

for (int i = 0; i < 5; i++)
{
ScrubData sd = new ScrubData();


sd.CurrentOrder = i * 1;
sd.DistrobutionCenterID = i * 6;
sd.DistrobutionCenterName = "dcenter_" + i;
sd.FinelineDescription = finelineDescription;
sd.InTransitOnHand = i * 2;
//sd.ItemDescription = null;
sd.OmitReport = i % 2== 0 ? true : false;
sd.PointOfSale = i * 3;
sd.StoreOnHand = i * 4;
sd.WarehouseOnHand = i * 5;
sd.WeekBeginDate = weekBeginDate;

sd.ItemDescription = new ItemDescription();

sd.ItemDescription.itemDescription = "ItemDesc_" +
sd.GetHashCode();
sd.ItemDescription.itemNumber = sd.GetHashCode();

types.Add(sd);
}




return types;
}





public static void updateOmitStatus(ScrubData data)
{

ScrubData olddata = data;

bool isNull = data == null;

HttpContext.Current.Response.Write("<br/>updateOmitStatus: " +
isNull);
HttpContext.Current.Response.Write("<br/>updateOmitStatus: " +
isNull);



}


......................
}




///////////////////////////////


public class FinelineDescription
{
public string Description;

public static List<FinelineDescription> getDescriptions(int choice,
DateTime week)
{
List<FinelineDescription> lines = new
List<FinelineDescription>();

for (int i = 0; i < 2; i++)
{
FinelineDescription line = new FinelineDescription();
line.Description = "Description_" + i;

lines.Add(line);
}

return lines;
}
}

=========================================

I didn't get "Null Reference" exception here( at least with these test
dummy classes...). Also, I've tested with Statically put a Gridview and
ObjectDataSource on a page, and use the Data Objects(I enable Editing for
the GridView), and when I programmtically call the GridView.UpdateRow, it
can update the Rows(passed a valid scurbDataObject to the data class's
updatemethod).

So I think the problem now is we need to use two-way databinding column for
the GridView so as to make it passed the value from GridView row to Data
object (when performing update operation). And the basic means of two-way
databinding is using boundfield. And I still recommend you consider
encapsulate the GridView+ObjectdataSource into a UserControl, since thus
you can define the columns statically in usercontrol template(usercontrol
can be dyanmically loaded into page/wizard). If you feel it ok, I can help
try creating a simple demo page on this.

Regards,

Steven Cheng
Microsoft Online Community Support


==================================================

When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.

==================================================


This posting is provided "AS IS" with no warranties, and confers no rights.
 
J

Jason

I'm trying to implement a user control instead of straight code behind for my
grid and ODS as you suggested.

I'm getting an object instance error when I attempt to set the properties of
the ODS in the user control. The error states ODS (the id of the datagrid) is
null.

here is the user control and code behind
---------------------------------------------------------------------------------
<%@ Control Language="C#" AutoEventWireup="true"
CodeFile="ScrubDataView.ascx.cs" Inherits="user_controls_ScrubDataView" %>
<asp:GridView ID="grid" runat="server" AutoGenerateColumns="False"
DataSourceID="ods" Width="100%">
<Columns>
<asp:BoundField DataField="WeekBeginDate" HeaderText="Week Date"
SortExpression="WeekBeginDate" Visible="False" />
<asp:TemplateField HeaderText="Omit" SortExpression="OmitReport">
<EditItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" Checked='<%#
Bind("OmitReport") %>' />
</EditItemTemplate>
<ItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" Checked='<%#
Bind("OmitReport") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="DistrobutionCenterID" HeaderText="DC ID"
SortExpression="DistrobutionCenterID" >
</asp:BoundField>
<asp:BoundField DataField="DistrobutionCenterName"
HeaderText="Distrobution Center" SortExpression="DistrobutionCenterName" >
</asp:BoundField>
<asp:TemplateField HeaderText="Item #"
SortExpression="ItemDescription">
<EditItemTemplate>
<asp:TextBox ID="TextBox1" runat="server" Text='<%#
Bind("ItemDescription") %>'></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%#
Bind("ItemDescription") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Item Description"
SortExpression="ItemDescription">
<EditItemTemplate>
<asp:TextBox ID="TextBox2" runat="server" Text='<%#
Bind("ItemDescription") %>'></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label2" runat="server" Text='<%#
Bind("ItemDescription") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="StoreOnHand" HeaderText="Store OH"
SortExpression="StoreOnHand" >
</asp:BoundField>
<asp:BoundField DataField="InTransitOnHand" HeaderText="In Transit
OH" SortExpression="InTransitOnHand" >
</asp:BoundField>
<asp:BoundField DataField="WarehouseOnHand" HeaderText="Warehouse
OH" SortExpression="WarehouseOnHand" >
</asp:BoundField>
<asp:BoundField DataField="CurrentOrder" HeaderText="Current Order"
SortExpression="CurrentOrder" >
</asp:BoundField>
</Columns>
</asp:GridView>
<asp:ObjectDataSource ID="ods" runat="server" SelectMethod="getRecords"
UpdateMethod="updateOmitStatus">
<SelectParameters>
<asp:parameter Name="weekBeginDate" Type="DateTime" />
<asp:parameter Name="finelineDescription" Type="String" />
</SelectParameters>
</asp:ObjectDataSource>
---------------------------------------------------------------------------------
public partial class user_controls_ScrubDataView : System.Web.UI.UserControl
{
private DateTime _weekdate;
private int _choice;
private string _fineline;

public DateTime WeekDate
{
get { return _weekdate; }
set { _weekdate = value; }
}
public int Choice
{
get { return _choice; }
set { _choice = value; }
}
public string FineLine
{
get { return _fineline; }
set { _fineline = value; }
}
public string TypeName
{
get
{
switch (Choice)
{
case 1: return "SBI.RetailLink.DataAccess.OmitDataObject";
case 2: return "SBI.RetailLink.DataAccess.ReportDataObject";
case 3: return "SBI.RetailLink.DataAccess.ScrubDataObject";
default: return string.Empty;
}
}
}

protected void Page_Init(object sender, EventArgs e)
{
//code fails on this line: ods is null
ods.TypeName = TypeName;
ods.DataObjectTypeName = TypeName;
ods.SelectParameters["weekBeginDate"].DefaultValue =
WeekDate.ToShortDateString();
ods.SelectParameters["finelineDescription"].DefaultValue = FineLine;
}
}
---------------------------------------------------------------------------------
//code from aspx Page_Init()
foreach (FinelineDescription f in fineline.getDescriptions(choice, week))
{
WizardStep step = new WizardStep();
user_controls_ScrubDataView ctrl = new
user_controls_ScrubDataView();

ctrl.FineLine = f.Description;
ctrl.Choice = choice;
ctrl.WeekDate = week;

step.Title = f.Description;
step.ID = "step_" + desccnt;
step.StepType = (desccnt.Equals(0)) ? WizardStepType.Start :
WizardStepType.Step;
step.Controls.Add(ctrl);

//this is where the Page_Init of the ascx is fired.
frame.WizardSteps.Add(step);

desccnt = frame.WizardSteps.Count;
}
 
J

Jason

I found how to correct the null object error
http://msdn2.microsoft.com/en-us/library/c0az2h86.aspx

Now I need to figure out why my complex business objects are not displaying
correctly.

--
Jason
Programmer
Specialty Bakers, Inc.


Steven Cheng said:
Thank you for the quick response Jason,

Nevermind, I've created a dummy FinelineDescription class to performed the
test and I've got your page running :). And after some test, I think the
problem here is still as mentioned in my first reply message. The
GridView.UpdateRow method will only update the current EditRow (the current
EditIndex row in the GridView) or those Rows which has Twoway databinding
Columns(the columns/template you created dyanmically are all one-way
databinding---just for display). So for your Gridview(dynamically created),
all the rows are in readonly/normal mode, so when you call update, the
dataobject's updatemethod did get executed, however, it passed Null into
the DataObject (ScrubDataObject).... Here is my modfied test page which
use a dummy finelineDescription class(I also use fake data for the
ScrubDataObject and its ItemDescription member...) :

============aspx==============
remain the same

======code behind=============
public partial class Common_DynamicWizardGridView : System.Web.UI.Page
{
private Wizard frame = new Wizard();
private int choice;
private DateTime week;

protected void Page_Init(object sender, EventArgs e)
{
Parameter p = new Parameter();
FinelineDescription fineline = new FinelineDescription();

//choice = int.Parse(Request.QueryString["q"]);
//week = DateTime.Parse(Request.QueryString["d"]);


choice = 3;
week = DateTime.Now;

p.Name = "data";
p.Direction = ParameterDirection.Input;
p.Type = TypeCode.Object;

frame.ID = "wzdfilterrecords";
frame.NavigationStyle.HorizontalAlign = HorizontalAlign.Left;
frame.NavigationStyle.VerticalAlign = VerticalAlign.Top;
frame.SideBarStyle.HorizontalAlign = HorizontalAlign.Left;
frame.SideBarStyle.VerticalAlign = VerticalAlign.Top;
frame.SideBarStyle.Width = Unit.Percentage(15);
frame.Width = Unit.Percentage(100);
frame.FinishButtonClick += new
WizardNavigationEventHandler(frame_FinishButtonClick);

foreach (FinelineDescription f in
FinelineDescription.getDescriptions(choice,
week))
{
WizardStep step = new WizardStep();
GridView grid = new GridView();
grid.EditIndex = 0;
ObjectDataSource ods = new
ObjectDataSource(getClassName(choice), "getRecords");

step.Title = f.Description;
step.ID = "step_" + frame.WizardSteps.Count;
step.StepType = (frame.WizardSteps.Count.Equals(0)) ?
WizardStepType.Start : WizardStepType.Step;

ods.ID = "ods_" + frame.WizardSteps.Count;
ods.SelectParameters.Add("weekBeginDate", week.ToString());
ods.SelectParameters.Add("finelineDescription", f.Description);
ods.UpdateMethod = "updateOmitStatus";
ods.UpdateParameters.Add(p);

grid.AutoGenerateColumns = false;
grid.DataSourceID = ods.ID;
grid.ID = "grid_" + frame.WizardSteps.Count;
grid.Columns.Add(addCheckBoxColumn());
grid.Columns.Add(addColumn("DistrobutionCenterID", "DC ID",
Unit.Pixel(45)));
grid.Columns.Add(addColumn("DistrobutionCenterName", "DC Name",
Unit.Percentage(25)));
grid.Columns.Add(addItemNumberTemplate("Item #",
Unit.Pixel(50)));
grid.Columns.Add(addItemDescriptionTemplate("Item Description",
Unit.Percentage(20)));
grid.Columns.Add(addColumn("StoreOnHand", "Store OH",
Unit.Pixel(55)));
grid.Columns.Add(addColumn("InTransitOnHand", "In Transit OH",
Unit.Pixel(55)));
grid.Columns.Add(addColumn("WarehouseOnHand", "Warehouse OH",
Unit.Pixel(55)));
grid.Columns.Add(addColumn("CurrentOrder", "Current Order",
Unit.Pixel(55)));
grid.Width = Unit.Percentage(100);

step.Controls.Add(ods);
step.Controls.Add(grid);
frame.WizardSteps.Add(step);
}
if (frame.WizardSteps.Count > 0)
{
WizardStep finalstep = new WizardStep();
Literal lit = new Literal();

finalstep.Title = "Commit Changes";
finalstep.ID = "step_" + frame.WizardSteps.Count;
finalstep.Controls.Add(lit);
finalstep.StepType = WizardStepType.Finish;
lit.Text = "Click Finish to commit changes and generate a
report.";

frame.WizardSteps.Add(finalstep);
hldrwizard.Controls.Add(frame);
}
else
{
Literal norecords = new Literal();
norecords.Text = string.Format("There are no {0} on
{1}.",getRecordType(choice), week.ToShortDateString());
hldrwizard.Controls.Add(norecords);
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
lbldate.Text = week.ToShortDateString();
lblrecordtype.Text = getRecordType(choice);
if (frame.WizardSteps.Count > 0)
frame.ActiveStepIndex = 0;
}
}
protected void frame_FinishButtonClick(object sender,
WizardNavigationEventArgs e)
{

Response.Write("<br/>frame_FinishButtonClick.............");
List<GridView> grids = new List<GridView>();
foreach (WizardStep step in frame.WizardSteps)
{
//not the final step
if (!step.StepType.Equals(WizardStepType.Finish))
{
GridView grid = (GridView)step.FindControl("grid_" +
frame.WizardSteps.IndexOf(step).ToString());
ObjectDataSource ods =
(ObjectDataSource)step.FindControl("ods_" +
frame.WizardSteps.IndexOf(step).ToString());

foreach (GridViewRow row in grid.Rows)
{
if (row.RowType.Equals(DataControlRowType.DataRow))
{
Response.Write("<br/>BeforeUpdate: " +
row.NamingContainer.ID + "__" + row.RowIndex);
grid.EditIndex = row.RowIndex;
grid.UpdateRow(row.RowIndex, false);

}
}
}
}
if (choice.Equals(3))
ScrubDataObject.transferToLiveData(week);
}

private string getRecordType(int choice)
{
switch (choice)
{
case 1:
return "Omit Records";
case 2:
return "Report Records";
case 3:
return "New Records";
default: return string.Empty;
}
}
private string getClassName(int choice)
{
switch (choice)
{
case 1:
return "SBI.RetailLink.DataAccess.OmitDataObject";
case 2:
return "SBI.RetailLink.DataAccess.ReportDataObject";
case 3:
return "SBI.RetailLink.DataAccess.ScrubDataObject";
default: return string.Empty;
}
}
private TemplateField addCheckBoxColumn()
{
TemplateField field = new TemplateField();

field.ItemTemplate = new GridViewCheckBoxTemplate();
field.ItemStyle.HorizontalAlign = HorizontalAlign.Center;
field.ItemStyle.VerticalAlign = VerticalAlign.Middle;
field.ItemStyle.Width = Unit.Pixel(20);
field.HeaderText = "Omit";
field.HeaderStyle.VerticalAlign = VerticalAlign.Bottom;
field.HeaderStyle.Width = Unit.Pixel(20);

return field;
}
private TemplateField addItemDescriptionTemplate(string header, Unit
width)
{
TemplateField field = new TemplateField();
field.ItemTemplate = new GridViewItemDescriptionTemplate();
field.ItemStyle.HorizontalAlign = HorizontalAlign.Center;
field.ItemStyle.VerticalAlign = VerticalAlign.Middle;
field.ItemStyle.Width = width;
field.HeaderText = header;
field.HeaderStyle.VerticalAlign = VerticalAlign.Bottom;
field.HeaderStyle.Width = width;

return field;
}
private TemplateField addItemNumberTemplate(string header, Unit width)
{
TemplateField field = new TemplateField();
field.ItemTemplate = new GridViewItemNumberTemplate();
field.ItemStyle.HorizontalAlign = HorizontalAlign.Center;
field.ItemStyle.VerticalAlign = VerticalAlign.Middle;
field.ItemStyle.Width = width;
field.HeaderText = header;
field.HeaderStyle.VerticalAlign = VerticalAlign.Bottom;
field.HeaderStyle.Width = width;

return field;
}
private BoundField addColumn(string dataField, string header, Unit
width)
{
BoundField field = new BoundField();

field.DataField = dataField;
field.ItemStyle.VerticalAlign = VerticalAlign.Top;
field.ItemStyle.Width = width;
field.HeaderText = header;
field.HeaderStyle.VerticalAlign = VerticalAlign.Bottom;
field.HeaderStyle.Width = width;
field.ReadOnly = true;

return field;
}
}
// Create a template class to represent a dynamic template column.
public class GridViewCheckBoxTemplate : ITemplate
{
public GridViewCheckBoxTemplate()
{
}
public void InstantiateIn(System.Web.UI.Control container)
{
CheckBox check = new CheckBox();
check.AutoPostBack = false;
check.CausesValidation = false;
check.DataBinding += new EventHandler(check_DataBinding);
container.Controls.Add(check);
}

private void check_DataBinding(Object sender, EventArgs e)
{
CheckBox c = (CheckBox)sender;
GridViewRow row = (GridViewRow)c.NamingContainer;
c.Checked = (bool)DataBinder.Eval(row.DataItem, "OmitReport");
}
}
public class GridViewItemDescriptionTemplate : ITemplate
{
public GridViewItemDescriptionTemplate()
{
}
public void InstantiateIn(System.Web.UI.Control container)
{
Label lbl = new Label();
lbl.DataBinding += new EventHandler(lbl_DataBinding);
container.Controls.Add(lbl);
}

private void lbl_DataBinding(Object sender, EventArgs e)
{
Label l = (Label)sender;
GridViewRow row = (GridViewRow)l.NamingContainer;
l.Text = ((ItemDescription)DataBinder.Eval(row.DataItem,
"ItemDescription")).itemDescription;
}
}
public class GridViewItemNumberTemplate : ITemplate
{
public GridViewItemNumberTemplate()
{
}
public void InstantiateIn(System.Web.UI.Control container)
{
Label lbl = new Label();
lbl.DataBinding += new EventHandler(lbl_DataBinding);
container.Controls.Add(lbl);
 
J

Jason

I replaced all my dynamic code with the user control method you suggested.
After some research I was able to load a new instance of the user control on
each wizard step.

I set the grid.EditItem and call grid.UpdateRow. The problem is my complex
object that is data bound to the control is returning null. I need a
property from the complex obect to update the database.

I have searched the web, haven't found a working solution to my problem
currently my data grid is bound like this
<asp:GridView ID="grid" runat="server" AutoGenerateColumns="False"
DataSourceID="ods" Width="100%">
<Columns>
<asp:BoundField DataField="WeekBeginDate" HeaderText="Week Date"
SortExpression="WeekBeginDate" Visible="False" />
<asp:TemplateField HeaderText="Omit" SortExpression="OmitReport">
<EditItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" Checked='<%#
Bind("OmitReport") %>' />
</EditItemTemplate>
<ItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" Checked='<%#
Bind("OmitReport") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="DistrobutionCenterID" HeaderText="DC ID"
SortExpression="DistrobutionCenterID" >
</asp:BoundField>
<asp:BoundField DataField="DistrobutionCenterName"
HeaderText="Distrobution Center" SortExpression="DistrobutionCenterName" >
</asp:BoundField>
<asp:TemplateField HeaderText="Item #"
SortExpression="ItemDescription">
<EditItemTemplate>
<asp:TextBox ID="TextBox1" runat="server" Text='<%#
((SBI.RetailLink.DataAccess.ItemDescription)((SBI.RetailLink.DataAccess.ScrubData)Container.DataItem).ItemDescription).itemNumber %>'></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%#
((SBI.RetailLink.DataAccess.ItemDescription)((SBI.RetailLink.DataAccess.ScrubData)Container.DataItem).ItemDescription).itemNumber %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Item Description"
SortExpression="ItemDescription">
<EditItemTemplate>
<asp:TextBox ID="TextBox2" runat="server" Text='<%#
((SBI.RetailLink.DataAccess.ItemDescription)((SBI.RetailLink.DataAccess.ScrubData)Container.DataItem).ItemDescription).itemDescription %>'></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label2" runat="server" Text='<%#
((SBI.RetailLink.DataAccess.ItemDescription)((SBI.RetailLink.DataAccess.ScrubData)Container.DataItem).ItemDescription).itemDescription %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="StoreOnHand" HeaderText="Store OH"
SortExpression="StoreOnHand" >
</asp:BoundField>
<asp:BoundField DataField="InTransitOnHand" HeaderText="In Transit
OH" SortExpression="InTransitOnHand" >
</asp:BoundField>
<asp:BoundField DataField="WarehouseOnHand" HeaderText="Warehouse
OH" SortExpression="WarehouseOnHand" >
</asp:BoundField>
<asp:BoundField DataField="CurrentOrder" HeaderText="Current Order"
SortExpression="CurrentOrder" >
</asp:BoundField>
</Columns>
</asp:GridView>

My guess is it's not binding because I'm not using the Bind keyword with
Item # and Item Description.

How would I go about 2 way binding a complex data object the GridView so I
can update the records.

Thank you for all your help with this problem. It has been very informative.
 
J

Jason

I believe I'm making good progress. I have narrowed down my null object
error to refer to the ItemDescription object which is part of the my
ScrubData object.

I think this is happening because I am not explictly calling Bind in the
template or code behind. I am now trying to set the value of the item number
and item description via the RowDataBound event on the grid view and using
the ODS_Updating event to get the values from the gridview row into the ods
update parameter. I am using this code:

using SBI.RetailLink.DataAccess;
public partial class user_controls_ScrubDataView : System.Web.UI.UserControl
{
private DateTime _weekdate;
private int _choice;
private string _fineline;

public DateTime WeekDate ...
public int Choice ...
public string FineLine ...
public string TypeName
{
get
{
switch (Choice)
{
case 1: return "SBI.RetailLink.DataAccess.OmitData";
case 2: return "SBI.RetailLink.DataAccess.ReportData";
case 3: return "SBI.RetailLink.DataAccess.ScrubData";
default: return string.Empty;
}
}
}

protected void Page_Init(object sender, EventArgs e)
{
ods.TypeName = TypeName;
ods.DataObjectTypeName = TypeName;
ods.SelectParameters["weekBeginDate"].DefaultValue =
WeekDate.ToShortDateString();
ods.SelectParameters["finelineDescription"].DefaultValue = FineLine;
}
protected void ods_Updating(object sender,
ObjectDataSourceMethodEventArgs e)
{
GridViewRow row = grid.Rows[grid.EditIndex];
ItemDescription item = new ItemDescription();

item.itemNumber =
int.Parse(((TextBox)row.Cells[4].FindControl("TextBox1")).Text);
item.itemDescription =
((TextBox)row.Cells[5].FindControl("TextBox2")).Text;

switch(Choice)
{
case 1:
OmitData omit = e.InputParameters[0] as OmitData;
omit.ItemDescription = item;
e.InputParameters["data"] = omit;
break;
case 2:
ReportData rpt = e.InputParameters[0] as ReportData;
rpt.ItemDescription = item;
e.InputParameters["data"] = rpt;
break;
case 3:
ScrubData scrub = e.InputParameters[0] as ScrubData;
scrub.ItemDescription = item;
e.InputParameters["data"] = scrub;
break;
}
}
protected void grid_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType.Equals(DataControlRowType.DataRow))
{
switch (e.Row.RowState)
{
case DataControlRowState.Normal:
switch (Choice)
{
case 1:
OmitData omitnormal = e.Row.DataItem as OmitData;

((Label)e.Row.Cells[4].FindControl("Label1")).Text =
omitnormal.ItemDescription.itemNumber.ToString();

((Label)e.Row.Cells[5].FindControl("Label2")).Text =
omitnormal.ItemDescription.itemDescription;
break;
case 2:
ReportData rptnormal = e.Row.DataItem as
ReportData;

((Label)e.Row.Cells[4].FindControl("Label1")).Text =
rptnormal.ItemDescription.itemNumber.ToString();

((Label)e.Row.Cells[5].FindControl("Label2")).Text =
rptnormal.ItemDescription.itemDescription;
break;
case 3:
ScrubData scrubnormal = e.Row.DataItem as
ScrubData;

((Label)e.Row.Cells[4].FindControl("Label1")).Text =
scrubnormal.ItemDescription.itemNumber.ToString();

((Label)e.Row.Cells[5].FindControl("Label2")).Text =
scrubnormal.ItemDescription.itemDescription;
break;
}
break;
case DataControlRowState.Edit:
switch (Choice)
{
case 1:
OmitData omitedit = e.Row.DataItem as OmitData;

((TextBox)e.Row.Cells[4].FindControl("TextBox1")).Text =
omitedit.ItemDescription.itemNumber.ToString();

((TextBox)e.Row.Cells[5].FindControl("TextBox2")).Text =
omitedit.ItemDescription.itemDescription;
break;
case 2:
ReportData rptedit = e.Row.DataItem as ReportData;

((TextBox)e.Row.Cells[4].FindControl("TextBox1")).Text =
rptedit.ItemDescription.itemNumber.ToString();

((TextBox)e.Row.Cells[5].FindControl("TextBox2")).Text =
rptedit.ItemDescription.itemDescription;
break;
case 3:
ScrubData scrubedit = e.Row.DataItem as ScrubData;

((TextBox)e.Row.Cells[4].FindControl("TextBox1")).Text =
scrubedit.ItemDescription.itemNumber.ToString();

((TextBox)e.Row.Cells[5].FindControl("TextBox2")).Text =
scrubedit.ItemDescription.itemDescription;
break;
}
break;
}
}
}

public void saveRecordStatus()
{
foreach (GridViewRow row in grid.Rows)
{
grid.EditIndex = row.RowIndex;
grid.DataBind();
grid.UpdateRow(row.RowIndex, false);
}
}
}

I'm now getting an "The OrderedDictionary is readonly and cannot be
modified." error when I attempt replace the existing update parameter with
the new one. I also tried InputParameters.Clear();
InputParameters.Add("data", [obj]); but this threw the same error.

I even databind the grid after setting the Row.EditIndex so the object is in
edit mode thinking this would allow me to write parmeters.

What would cause the InputParameters to be read-only?
 
S

Steven Cheng[MSFT]

Thank you for your continue followup.

Glad that you've made further progress, and based on code snippet and your
description, I think you're about to done the work.

As for the below things you mentioned:

==================
My guess is it's not binding because I'm not using the Bind keyword with
Item # and Item Description.
==================

Yes, you're completely right. Only the two-way databinding fields will
automatically populate the parameter values at update time. Also, the
built-in databinding approach only support "bind" keyword(or BoundField)
on one level property. And for your scenario, you "ItemDescription"
property is a property which contains other nested properties, we can not
directly use "bind" keyword or "BoundField", and I think your current
approach on using One-way databinding to display the value and use the
Updating event of objectDataSource to populate the paramter object is
reasonable.

BTW, you can also use the following expression to display nested property
value in template field(one-way):

<asp:Label ID="lblItemNumber" runat="server" Text='<%#
Eval("ItemDescription.itemNumber") %>'></asp:Label>

And as for your latest problem:

=============================
I'm now getting an "The OrderedDictionary is readonly and cannot be
modified." error when I attempt replace the existing update parameter with
the new one. I also tried InputParameters.Clear();
InputParameters.Add("data", [obj]); but this threw the same error.
================================

This is because for objectDatasource parameter, it is a class instance of
the DataTypeObject, and the ASP.NET runtime only create one INputParamter
object of this type and add it into the OrderedDictionary collection passed
in the ObjectDataSource.Updating event, and it also make the collection
"ReadOnly"(OrderedDictionary support this) so that the event subscriber can
not change the whole DataObect instance in it. However, we can still
modify the instance, and I've looked into your updating event handler, I
think you can just remove the line you assign the ItemDescription instance
back to the OrderedDictionary collection. like:


==============================
switch(Choice)
{
case 1:
OmitData omit = e.InputParameters[0] as OmitData;
omit.ItemDescription = item;
//remove the below line
//e.InputParameters["data"] = omit;
break;
case 2:
ReportData rpt = e.InputParameters[0] as ReportData;
rpt.ItemDescription = item;
//remove the below line
// e.InputParameters["data"] = rpt;
break;
case 3:
ScrubData scrub = e.InputParameters[0] as ScrubData;
scrub.ItemDescription = item;
//remove the below line
//e.InputParameters["data"] = scrub;
break;
}
==============================
#This is because e.InputParameters[0] is a reference type, any change on it
will be synchronized on the associated object instance, we do not need to
reassign it back


In addition, we can also use the GridView.RowUpdating event to add the
parameter value for "ItemDescription" property, e.g:

========================
protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs
e)
{
Response.Write("<br/>GridView1_RowUpdating..................");
Response.Write("<br/>GridView+RowUpdating " + e.RowIndex);


ItemDescription id = new ItemDescription();
id.itemNumber = 6;
id.itemDescription = "Desc6";

//"ItemDescription" is the property name
e.NewValues.Add("ItemDescription", id);


}
============================
# The advantage here is that you do not need to remember the "EditIndex" in
the GridView because the event's parameter has passed in the info which
contains the current Item's Index(which is being updating...) .


Hope this also helps. If there is anything unclear on the above items or
anything else we can help, please feel free to post here.

Regards,

Steven Cheng
Microsoft Online Community Support


==================================================

When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.

==================================================


This posting is provided "AS IS" with no warranties, and confers no rights.



Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
S

Steven Cheng[MSFT]

Hi Jason,

How are you doing on this. Does my further suggestion helped you some? If
there is still anything else we can help, please feel free to post here.

Regards,

Steven Cheng
Microsoft Online Community Support


==================================================

When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.

==================================================


This posting is provided "AS IS" with no warranties, and confers no rights.



Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top