DataProvider in TestNG to pass data from excel - eclipse

I started learning Selenium2 (WebDriver) with Eclipse and TestNG. I have a question about DataProvider. I have a login page having user, password and login button for example. I have written a test in TestNG. I have used pageobject for UI objects (have separate class) and actual test in another class.
Here glogin is a class and login is the function where finding elements and sending keys is done and this is called in another class gtest(which is main test) which has TestNG annotations.
I access that class in main script which will take values.
#test(Dataprovide = "test")
public void glogin(String user, String pass)
{
glogin log1 = new login;
log1.login(user,pass);
}
I have the following excel sheet
user pass
John Smith
Carson Black
Carla ck23
test test4
When I use dataprovider and get data from the excel sheet as array and use it in Test then the following error is displayed:
org.testng.TestNGException:
The data provider is trying to pass 4 parameters but the method plus.gmail#glogin takes 2
at org.testng.internal.Invoker.injectParameters(Invoker.java:1337)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1225)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:128)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)
at org.testng.TestRunner.privateRun(TestRunner.java:767)
at org.testng.TestRunner.run(TestRunner.java:617)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:334)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:329)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:291)
at org.testng.SuiteRunner.run(SuiteRunner.java:240)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1203)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1128)
at org.testng.TestNG.run(TestNG.java:1036)
at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:111)
at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:204)
at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:175)
Any help is really appreciated.
Here is code for method annotated with Dataprovider and
#DataProvider(name="test")
public Object[][] createdata1()throws Exception
{
Object[][] retobj = getexcel();
return retobj;
}
private String[][] getexcel() throws Exception
{
// TODO Auto-generated method stub
String[][] tabarray = null;
try {
Workbook wb1 = Workbook.getWorkbook(new
File("F:/testdata.xls"));
Sheet sheet = wb1.getSheet("userlogin");
Cell tablestart = sheet.findCell("login");
int startrow = tablestart.getRow();
int startcol = tablestart.getColumn();
Cell tableend = sheet.findCell("login",startcol+1,startrow+1,
100, 64000, false);
int endrow = tableend.getRow();
int endcol = tableend.getColumn();
System.out.println("startRow="+startrow+", endRow="+endrow+",
" + "startCol="+startcol+", endCol="+endcol);
tabarray = new String[endrow - startrow + 1][endcol -
startcol + 1];
int ci = 0;
for(int i = startrow +1 ;i<endrow;i++,ci++)
{
int cj = 0;
for(int j = startcol + 1;j<endcol;j++,cj++)
{
tabarray[ci][cj] = sheet.getCell(j,
i).getContents();
System.out.println(tabarray[ci][cj]);
}
}
} catch (BiffException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return tabarray;
}
test(Dataprovider = "test")
public void glogins(String user, String pass)
{
glogin log1 = new glogin(driver);
log1.login(user,pass);
}
When I executed the test, I received data from excel as
john
smith
carson
Black
carla
ck23
test
test4
as output

Isn't the error message self-explanatory?
The data provider is trying to pass 4 parameters but the method plus.gmail#glogin takes 2
Use a debugger and figure out why your data provider is returning 4 parameters instead of just 2.

Use
tabarray = new String[endrow - 1][endcol - 1]; instead of //tabarray = new String[endrow - startrow + 1][endcol - startcol + 1];
Because you intended to return only 2*2 array

Replace the line
tabarray = new String[endrow - startrow + 1][endcol - startcol + 1];
with
tabarray = new String[endrow - startrow - 1][endcol - startcol - 1];

I agree with the response posted by Kalyan; the reason being the first and last column of the data provider excel sheet is also counted in as arguments / parameters by the function; therefore please use tabArray=new String[endRow-startRow-1][endCol-startCol-1]; Hope this helps and happy testing...

Related

Updating column in tableviwer

I have retrieved data from database and i am able to show it in Table of the Table Viewer but my task is on click of a row the data should be appear in another form from where i can edit it and on click of update the view should be updated with the new values.I am using viewer.addSelectionChangedListener to retrieve the selected row but i am not getting how to update the table .Please suggest me few ideas
I have written the below code in the constructor of my class so whenever object is created Table is generated and l1 is list of data which i am passing to another UI
input[i] = new MyModel(persons[i].getDateOfRegistration(), persons[i].getFirstName(),
persons[i].getMiddleName(), persons[i].getLastName(), persons[i].getGender(),
persons[i].getDob(), persons[i].getContactNumber(), persons[i].getMaritalStatus(),
persons[i].getAddress(), persons[i].getCountry(), persons[i].getBloodGroup(),
persons[i].getInsuranceDetails().getPolicyHolderName(),
persons[i].getInsuranceDetails().getPolicyNumber(),
persons[i].getInsuranceDetails().getSubscriberName(),
persons[i].getInsuranceDetails().getRelationshipToPatient());
viewer.setInput(input);
table.setHeaderVisible(true);
table.setLinesVisible(true);
GridData gridData = new GridData();
gridData.verticalAlignment = GridData.FILL;
gridData.horizontalSpan = 2;
gridData.grabExcessHorizontalSpace = true;
gridData.grabExcessVerticalSpace = true;
gridData.horizontalAlignment = GridData.FILL;
viewer.getControl().setLayoutData(gridData);
viewer.addSelectionChangedListener(new ISelectionChangedListener() {
public void selectionChanged(SelectionChangedEvent event) {
IStructuredSelection selection = (IStructuredSelection) event.getSelection();
StringBuffer sb = new StringBuffer("Selection - ");
int j = 0;
String[] s;
for (Iterator iterator = selection.iterator(); iterator.hasNext();) {
sb.append(iterator.next() + ", ");
System.out.println("Testing::" + sb);
}
System.out.println(sb);
String result[] = new String[18];
List l1 = new ArrayList(100);
String[] parts = sb.toString().split("=");
for (int i = 0; i < parts.length; i++) {
System.out.println("s" + parts[i]);
String[] s1 = parts[i].split(",");
l1.add(s1[0]);
}
SWTPatientRegistrationUpdatePageEventView swtPatientRegistrationUpdatePageEventView = new SWTPatientRegistrationUpdatePageEventView();
swtPatientRegistrationUpdatePageEventView.openParentUpdateShell(l1);
// viewer.refresh();
//flag=false;
//refreshingData(list);
}
});
Make sure we will follow table viewer MVC architecture all the time. Steps we can do to resolve your issue isas follow:
Create proper datastructure(Model Class) to hold the data. and use the same in array which you set in viewer.setInput()
When you click/double click on table row, fetch the data and save it in datastructure created(with new object).
Pass that data structure to your form dialog.
when you are done with update in form. Fill the updated data in new Model object again.
And after form close, pass that model object back to parent.
updated the corresponding array element with object received from Form Dialog and just refresh the tableviewer.
Please let me know if you need some code module. Thanks

Nesting Model Reports + Search Results

Seem like I'm not the first to investigate this. But not despairing yet :-)
The target state I'd like to reach is:
A recursion through Packages, where some of the nested Sub-Packages are glorified Linked Documents, and some are Grids rendering Search Results.
I like that Model Documents provide Search Tag values -- but I can't seem to nest the grids where I want them to show up.
Approach 1: Nested Model Documents
If I could nest Model Document elements, with their Search/Search Term tags, I would be sorted. I could have
Context:Package
Introduction:Package <- just renders a Linked Document attached to it
Systems Affected:Package <- just renders a Linked Document attached to it
Systems Affected:Model Document <- renders the results of a canned Search.
But EA appears to be designed to ignore the Model Document element.
Approach 2: SQL backed Template Fragment
I like the Model Document as it has Search/Search Term + all the Inclusion/Exclusion configuration options. But if I had to give that part up I am thinking of emulating as much as I can via SQL or script.
First attempt - using SQL and a nested set of Packages such as:
Context:Package
Introduction:Package <- just renders a Linked Document attached to it
Systems Affected:Package <- just renders a Linked Document attached to it
Systems Affected:Package<> <- renders the results of a SQL Search.
If the template uses a TemplateSelector it can spot the Package with a wellknown stereotype, and invoke a Template that is backed by SQL.
The SQL uses the Package's Keywords as the source of the Element type to search for.
SELECT
o.ea_guid AS [CLASSGUID],
o.Object_Type AS [CLASSTYPE],
o.PDATA5 AS [KEYWORDS],
o.Object_Type AS [Type],
o.Stereotype AS [Stereotype],
*
FROM t_object as O
WHERE O.Object_Type IN
(SELECT PDATA5 FROM t_object AS S where S.Object_ID = #OBJECTID#)
It works...barely.It's a bit hacky.
Searching off of Element Type is not going to be sufficient for production documents.
Approach 3: Script backed Template Fragment
If I can get a script running I suspect that I could leverage functionality that is already in the system.
Context:Package
Introduction:Package <- just renders a Linked Document attached to it
Systems Affected:Package <- just renders a Linked Document attached to it
Systems Affected:Package<> <- renders the results of a canned Search.
If the template uses a TemplateSelector it can spot the Package with a wellknown stereotype, and invoke a Template that is backed by a script.
The script I'm trying is:
var x = Repository.GetElementsByQuery("POC.Req", "Device");
return x;
But the report remains blank of those elements I need for the table.
Q: Does the returned Collection need transformation before it can be used?
Approach 4
I've heard that there is an approach to Render Document sections as PDF, and link to them as Linked Documents... Sounds Convoluted. Sounds like a wrong/magic approach.
Approach 5
Any other suggestions?
Thanks for the help.
Addendum
Just got approach 3 to work by converting the script results to xml before handing it back
The template's script now looks like
-- first pass ...I'll work on passing the ObjectId in a bit in order to get fancier.
ExecuteSearch("Simple", "Device")
and it invokes a script saved somewhere else as
!INC Local Scripts.EAConstants-JScript
/*
* Script Name:
* Author:
* Purpose:
* Date:
*/
function main()
{
return ExecuteSearch("Simple", "Device");
}
function ExecuteSearch(searchName, searchParam){
var x = Repository.GetElementsByQuery(searchName, searchParam);
//return x;
var xmlDOC = CreateReport(x);
var s = xmlDOC.xml;
Session.Output(s);
return s;
}
function CreateReport(entityCollection){
var xmlDOC = CreateXmlDOC();
var xmlRoot = AppendXmlChild(xmlDOC,"EADATA");
var xmlDataSet = AppendXmlChild(xmlDOC,"Dataset_0",xmlRoot);
var xmlData = AppendXmlChild(xmlDOC,"Data",xmlDataSet);
for(var i = 0;i<entityCollection.Count();i++){
var entity = entityCollection.GetAt(i);
var xmlRow = AppendXmlChild(xmlDOC,"Row",xmlData);
//AppendXmlChild(xmlDOC,"CLASSTYPE",xmlRow).Text = entity.Type;
AppendXmlChild(xmlDOC,"Guid",xmlRow).text = entity.ElementGUID;
AppendXmlChild(xmlDOC,"CLASSTYPE",xmlRow).text = entity.Type;
AppendXmlChild(xmlDOC,"CLASSGUID",xmlRow).text = entity.ElementGUID;
AppendXmlChild(xmlDOC,"Type",xmlRow).text = entity.Type;
AppendXmlChild(xmlDOC,"Stereotype",xmlRow).text = entity.Stereotype;
AppendXmlChild(xmlDOC,"Name",xmlRow).text = entity.Name;
AppendXmlChild(xmlDOC,"Object",xmlRow).text = entity.Name;
AppendXmlChild(xmlDOC,"Id",xmlRow).text = entity.ElementID;
AppendXmlChild(xmlDOC,"Scope",xmlRow).text = entity.Scope;
AppendXmlChild(xmlDOC,"Phase",xmlRow).text = entity.Phase;
AppendXmlChild(xmlDOC,"Status",xmlRow).text = entity.Status;
var noteElement = AppendXmlChild(xmlDOC,"Notes",xmlRow);//.text = entity.Notes;
noteElement.appendChild(xmlDOC.createCDATASection(entity.Notes));
AppendXmlChild(xmlDOC,"Keywords",xmlRow).text = entity.PDATA5;
}
return xmlDOC;
}
function CreateXmlDOC()
{
var xmlDOM;
try
{
xmlDOM = new ActiveXObject( "MSXML2.DOMDocument.4.0" );
}
catch(e)
{
xmlDOM = new ActiveXObject( "MSXML2.DOMDocument.6.0" );
}
xmlDOM.createProcessingInstruction("xml","version=\"1.0\"");
xmlDOM.validateOnParse = false;
xmlDOM.async = false;
return xmlDOM;
}
function AppendXmlChild(xmlDOM, xmlElementName, xmlParent, isCDATA){
if (!xmlParent){xmlParent = xmlDOM;}
var child = xmlDOM.createElement(xmlElementName);
xmlParent.appendChild(child);
return child;
}
main();
The script I used in the end is as follows. It now correctly investigates the element's tags for clues as how to proceed.
Hope it helps others.
!INC Local Scripts.EAConstants-JScript
/*
* Script Name:
* Author:
* Purpose:
* Date:
*/
//Only used for development
function devTest()
{
//With Child elements: {2255D8C8-F1BB-4069-BDAF-8B303D108C62}
//With SearchName: {919252E0-BDEB-4f26-A39F-C0E74382952A}
//With PackageGUID: {8543ED3B-EC39-4bf0-92C2-FD49A00C376B}
Session.Output ("DEVTEST");
var package = Repository.GetPackageByGuid("{8543ED3B-EC39-4bf0-92C2-FD49A00C376B}");
Session.Output("Package Name:" + package.Name);
Session.Output("Package Guid:" + package.PackageGUID);
Session.Output("Package Id:" + package.PackageID);
Session.Output("Package ElementId:" + package.Element.ElementID);
//Session.Output("Package Element Id:" + package.Element.ElementID);
//Use the Element associate to the Package, not the Package ID itself.
var packageElementId = package.Element.ElementID; //NOT: package.PackageID;
var xmlDoc=ExecuteSearch(packageElementId);
try {
Session.Output(xmlDoc.xml);
}catch (e){
Session.Output(e.message);
}
}
//Extracts from a given Package it's SearchName/SearchValue tags
//in order to do a search that mimicks a ModelDocument's way of
//generating a report.
function ExecuteSearch(elementId){
//Validation
if (!elementId){
Session.Output("Exiting: No elementId received.");
return;
}
var packageElement = Repository.GetElementByID(elementId);
if (!packageElement){
Session.Output("Exiting: No package with given elementId: " + elementId);
return;
}
try {
var xmlDOC = ExecuteSearch2(packageElement);
var xml = xmlDOC.xml;
return xml;
}catch (e){
Session.Output("ERROR: " + e.message);
}
return null;
}
function ExecuteSearch2(packageElement){
//Session.Output(packageElement.ElementGUID + ": '" + packageElement.Name + "' invoking ExecuteSearch(" + packageElement.ElementID + ")");
//Session.Output("Attribute 'Test': " + GetElementTaggedValue(packageElement,'Test'));
//Precendence is to search
//* Direct children,
//* by Package, recursively,
//* Package, single
//* Package
//First dibs: does this package have any direct elements?
//Get back to the package that is related to the Element before you count Elements:
var package = Repository.GetPackageByGuid(packageElement.ElementGUID);
var elementCollection = package.Elements;
if (elementCollection.Count()){
Session.Output("Package [" + packageElement.ElementGUID + "] has child Elements:"+ elementCollection.Count());
return CreateReportDoc(elementCollection);
}
//If package had no children, look at Attributes for reference to other package.
//At present, can't find an easy way to determine package Id from the EA GUI, so
//using the Guid.
var searchPackageGuid = GetElementTaggedValue(packageElement,'SearchPackageGUID');
if (!searchPackageGuid){
searchPackageGuid = GetElementTaggedValue(packageElement,'SearchPackageGuid');
}
if (searchPackageGuid){
//Session.Output("Package [" + packageElement.ElementGUID + "] has SearchPackageGuid:"+ searchPackageGuid);
return ExecuteSearchByPackageGuid(searchPackageGuid);
}
// //If I ever find a way to get a packageId:
var searchPackageId = GetElementTaggedValue(packageElement,'SearchPackageId');
if (searchPackageId){
//Session.Output("Package [" + packageElement.ElementGUID + "] has SearchPackageId:"+ searchPackageId);
return ExecuteSearchByPackageId(searchPackageId);
}
// //If searching by SQL:
var searchSQL = GetElementTaggedValue(packageElement,'SearchSQL');
if (searchSQL){
Session.Output("Package [" + packageElement.ElementGUID + "] has SearchSQL:"+ searchSQL);
return ExecuteSearchBySQL(searchSQL);
}
//Not pointing to a package, so maybe pointing to a canned search:
var searchName = GetElementTaggedValue(packageElement,'SearchName');
if (!searchName){
//Session.Output("No SearchName");
return;
}
var searchValue = GetElementTaggedValue(packageElement,'SearchValue');
//Session.Output("Package [" + packageElement.ElementGUID + "] has SearchName/Value:"+ searchName + "/" + searchValue);
return ExecuteSearchBySearchName(searchName, searchValue);
}
//Mimicks functionality of a ModelDocument that searches by canned SearchName/SearchValue.
function ExecuteSearchBySearchName(searchName, searchValue){
var elementCollection = Repository.GetElementsByQuery(searchName, searchValue);
//return x;
return CreateReportDoc(elementCollection);
}
function ExecuteSearchByPackageGuid(packageGuid){
var package = Repository.GetPackageByGuid(packageGuid);
return ExecuteSearch2(package.Element);
}
function ExecuteSearchBySQL(searchSQL){
var elementCollection = Repository.GetElementSet(searchSQL, 2);
}
function HOLD_ExecuteSearchBySet(idList){
var elementCollection = Repository.GetElementsSet(idList);
//return x;
return CreateReportDoc(elementCollection);
}
//Iterate through the elements and convert to an Xml Document
//suitable for use by a Script backed Template:
function CreateReportDoc(elementCollection){
var xmlDOC = CreateXmlDOC();
var xmlData = CreateXmlReport(xmlDOC);
for(var i = 0;i<elementCollection.Count();i++){
//For each Element, create a new row:
var xmlRow = AppendXmlChild(xmlData,"Row");
//And embed the specific element:
var element = elementCollection.GetAt(i);
CreateReportRow(xmlRow, element);
}
return xmlDOC;
}
function CreateReportRow(xmlRow, element){
//And attach child property elements.
//For hairy ones, add them as a CDATA.
//AppendXmlChild(xmlDOC,"CLASSTYPE",xmlRow).Text = element.Type;
AppendXmlChild(xmlRow,"Guid").text = element.ElementGUID;
AppendXmlChild(xmlRow,"CLASSTYPE").text = element.Type;
AppendXmlChild(xmlRow,"CLASSGUID").text = element.ElementGUID;
AppendXmlChild(xmlRow,"Type").text = element.Type;
AppendXmlChild(xmlRow,"Stereotype").text = element.Stereotype;
AppendXmlChild(xmlRow,"Name").text = element.Name;
AppendXmlChild(xmlRow,"Object").text = element.Name;
AppendXmlChild(xmlRow,"Id").text = element.ElementID;
AppendXmlChild(xmlRow,"Scope").text = element.Scope;
AppendXmlChild(xmlRow,"Phase").text = element.Phase;
AppendXmlChild(xmlRow,"Status").text = element.Status;
AppendXmlChild(xmlRow,"Keywords").text = element.PDATA5;
//Notes need wrapping as CDATA
var noteElement = AppendXmlChild(xmlRow,"Notes");//.text = entity.Notes;
noteElement.appendChild(xmlRow.ownerDocument.createCDATASection(element.Notes));
//Now get tags:
AppendXmlChild(xmlRow,"Tags.ID").text = GetElementTaggedValue(element,"ID");
AppendXmlChild(xmlRow,"Tags.Type").text = GetElementTaggedValue(element,"Type");
AppendXmlChild(xmlRow,"Tags.Category").text = GetElementTaggedValue(element,"Category");
AppendXmlChild(xmlRow,"Tags.Traceability").text = GetElementTaggedValue(element,"Traceability");
return xmlRow;
}
//helper function to create an empty xml document
function CreateXmlDOC()
{
var xmlDOM;
try
{
xmlDOM = new ActiveXObject( "MSXML2.DOMDocument.4.0" );
}
catch(e)
{
xmlDOM = new ActiveXObject( "MSXML2.DOMDocument.6.0" );
}
xmlDOM.createProcessingInstruction("xml","version=\"1.0\"");
xmlDOM.validateOnParse = false;
xmlDOM.async = false;
return xmlDOM;
}
//helper function to create the beginning of an xml document
//suitable to render the results of a search:
function CreateXmlReport(xmlDOC){
var xmlRoot = AppendXmlChild(xmlDOC,"EADATA");
var xmlDataSet = AppendXmlChild(xmlRoot,"Dataset_0");
var xmlData = AppendXmlChild(xmlDataSet,"Data");
return xmlData;
}
//helper function to attach a new child xml element to a parent xml element
function AppendXmlChild(xmlParent, xmlElementName, isCDATA){
var xmlDocument = xmlParent.ownerDocument;
if (!xmlDocument){xmlDocument = xmlParent}
var child = xmlDocument.createElement(xmlElementName);
xmlParent.appendChild(child);
return child;
}
//Gets an Element's tag. Eats exception if Tag does not exist.
function GetElementTaggedValue(element, tagName){
var tag;
try {
tag = element.TaggedValues.GetByName(tagName);
}
catch (e) {
}
if (!tag){return;}
var result = tag.Value;
return result;
}
function ConvertPackageIdToBranchId(packageId){
var package = Repository.GetPackageByID(objectId);
if (!package){return;}
var packages = [package];
packages.concat(ConvertPackageToBranch(package));
var result=[];
for(var i=0;i<packages.length;i++){
result.push(packages[i].PackageID);
}
return result;
}
function ConvertPackageToBranch(package){
var result = [];
for (var i=0;i<package.Packages.Count();i++){
var childPackage = package.Packages.GetAt(i);
result.push(childPackage);
result.concat(ConvertPackageToBranch(childPackage));
}
return result;
}
//devTest();

How to update a text file which always contains a single line?

I have the following code to read a line from a text file.
In the UpdateFile() method I need to delete the existing one line and update it with a new line.
Can anybody please provide any ideas?
Thank you.
FileInfo JFile = new FileInfo(#"C:\test.txt");
using (FileStream JStream = JFile.Open(FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None))
{
int n = GetNUmber(JStream);
n = n + 1;
UpdateFile(JStream);
}
private int GetNUmber(FileStream jstream)
{
StreamReader sr = new StreamReader(jstream);
string line = sr.ReadToEnd().Trim();
int result;
if (string.IsNullOrEmpty(line))
{
return 0;
}
else
{
int.TryParse(line, out result);
return result;
}
}
private int UpdateFile(FileStream jstream)
{
jstream.Seek(0, SeekOrigin.Begin);
StreamWriter writer = new StreamWriter(jstream);
writer.WriteLine(n);
}
I think the below code can do your job
StreamWriter writer = new StreamWriter("file path", false); //false means do not append
writer.Write("your new line");
writer.Close();
If you're just writing a single line, there's no need for streams or buffers or any of that. Just write it directly.
using System.IO;
File.WriteAllText(#"C:\test.txt", "hello world");
var line = File.ReadLines(#"c:\temp\hello.txt").ToList()[0];
var number = Convert.ToInt32(line);
number++;
File.WriteAllText(#"c:\temp\hello.txt", number.ToString());
Manage the possible exceptions, file exists, file has lines, the cast......

Ajax Popupcontrolextender issues

I have a bizarre problem. I have followed the example here (http://www.4guysfromrolla.com/articles/071107-1.aspx) to display an ajax popup, but it is not working properly.
The problem I have is that the image attributes are not set properly, I checked with Firebug and this is what I get on page 1 after load.
<img src="StyleSheets/magglass.jpg" id="mainContent_TheGrid_MagGlass_0">
Now the bizarre, if I go to page 2, the onmouseover event is set properly for all images and if I come back to page 1, it is set properly too, e.g.
<img src="StyleSheets/magglass.jpg" onmouseover="$find('pce0').showPopup(); " id="mainContent_TheGrid_MagGlass_0">
I stepped through the code and confirmed that the rowcreated event is firing for my grid, for each row
Any Ideas?
My code is slightly different to the example, see below
protected void TheGrid_RowCreated(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
// Programmatically reference the PopupControlExtender
PopupControlExtender pce = e.Row.FindControl("TheGrid_PopupControlExtender") as PopupControlExtender;
// Set the BehaviorID
string behaviorID = string.Concat("pce", e.Row.RowIndex);
pce.BehaviorID = behaviorID;
// Programmatically reference the Image control
Image i = (Image)e.Row.Cells[0].FindControl("MagGlass");
// Add the client-side attributes (onmouseover & onmouseout)
string OnMouseOverScript = string.Format("$find('{0}').showPopup(); ", behaviorID);
i.Attributes.Add("onmouseover", OnMouseOverScript);
}
}
The GetDynamicContent Method is below, which adds the hidepopup method.
[System.Web.Services.WebMethodAttribute(), System.Web.Script.Services.ScriptMethodAttribute()]
public static string GetDynamicContent(string contextKey)
{
GridView MyGrid = (GridView)HttpContext.Current.Session["TheGrid"];
var MyVar = from GridViewRow MyRow in MyGrid.Rows
where MyRow.Cells[MyRow.Cells.Count - 1].Text == contextKey
select MyRow;
//This is the selected row by the user
GridViewRow MyGridRow = MyVar.SingleOrDefault();
//MyGridRow.Cells[3].Text is the log entry.
string MyTable = #"<table class=""PopUpTable""><tr><td><textarea class=""textarea"">"
+ MyGridRow.Cells[3].Text + "</textarea></td>";
//MyGridRow.RowIndex is used to determine the name of popup control for the hidepopup script
MyTable += "<td><button type=\"button\" class=\"PopUpButton\" onclick=\"$find('pce" + MyGridRow.RowIndex.ToString() + "').hidePopup();\">Close</button></td></tr></table>";
return MyTable;
}
This is the pageIndexChanging event
protected void TheGrid_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
TheGrid.PageIndex = e.NewPageIndex;
LoadFromDB();
}
The LoadFromDB method here:
private void LoadFromDB()
{
try
{
LOGDBDataContext LDC = new LOGDBDataContext(ConfigurationManager.ConnectionStrings[Constants.ConnectionStringName].ConnectionString);
string Query = #"DateTimeStamp >= #0 and DateTimeStamp <= #1";
var Tolo = LDC
.Logs
.Where(Query, this.FromCalendar.SelectedDate, this.ToCalendar.SelectedDate)
.OrderBy("DateTimeStamp desc")
.Select("new (LogID, DateTimeStamp, Organization, LogEntry, ServerHostname)");
TheGrid.DataSource = Tolo;
TheGrid.DataBind();
}
catch (Exception ex)
{
//do something here
}
}
Never Mind, found the answer.
Poor Debugging
A poor attempt at
clearing the gridview that was not
invoked by the pagechanging event
Incompetence thy name is yomismo

ADO.net Question - How can I update a column in a Row of a DataTable with RowChanged without triggering infinite loop?

How can I update the column value (programmatically) in a Row of a DataTable via use of the RowChanged event, without triggering infinite loop? (which I currently get)
Note I do not want to use the DataColumn.Expression property.
For example the following gives me a recursive loop and stack overflow error:
DataColumn dc = new DataColumn("OverallSize", typeof(long));
DT_Webfiles.Columns.Add(dc);
DT_Webfiles.RowChanged += new DataRowChangeEventHandler(DT_Row_Changed);
private static void DT_Row_Changed(object sender, DataRowChangeEventArgs e)
{
Console.Out.WriteLine("DT_Row_Changed - Size = " + e.Row["OverallSize"]);
e.Row["OverallSize"] = e.Row["OverallSize"] ?? 0;
e.Row["OverallSize"] = (long)e.Row["OverallSize"] + 1;
}
thanks
PS. In fact using the RowChanging event (rather than RowChanged) makes sense to me (i.e. change the value before it saves so to speak) however when I try this I get a "Cannot change a proposed value in the RowChanging event" at the following line in the handler:
e.Row["OverallSize"] = e.Row["OverallSize"] ?? 0;
You could unsubscribe when within the event handler, though that would make your code not thread-safe.
DataColumn dc = new DataColumn("OverallSize", typeof(long));
DT_Webfiles.Columns.Add(dc);
DT_Webfiles.RowChanged += new DataRowChangeEventHandler(DT_Row_Changed);
private static void DT_Row_Changed(object sender, DataRowChangeEventArgs e)
{
e.RowChanged -= new DataRowChangeEventHandler(DT_Row_Changed);
Console.Out.WriteLine("DT_Row_Changed - Size = " + e.Row["OverallSize"]);
e.Row["OverallSize"] = e.Row["OverallSize"] ?? 0;
e.Row["OverallSize"] = (long)e.Row["OverallSize"] + 1;
e.RowChanged += new DataRowChangeEventHandler(DT_Row_Changed);
}
Try with this
e.Row.Table.RowChanged -= new DataRowChangeEventHandler(DT_Row_Changed);
And
e.Row.Table.RowChanged += new DataRowChangeEventHandler(DT_Row_Changed);