I have a gridview in which i am showing values to be checked or unchecked in gridview rows checkboxes..Now i want to these values dynamically in gridview rows but its not going to happen ..All of the checkboxes are coming checked whereas result should be different ..
here is my hardcoded code condition to show the result which is coming fine...
string[] rolesarr = Roles.GetAllRoles();
DataTable dTable = new DataTable();
dTable.Columns.Add("Select", typeof(bool));
dTable.Columns.Add("Username", typeof(string));
Array.ForEach(rolesarr, r => dTable.Columns.Add(r, typeof(bool)));
foreach (MembershipUser u in Membership.GetAllUsers())
{
DataRow dRow = dTable.NewRow();
dRow[0] = false;
dRow[1] = u.UserName;
string[] roles = Roles.GetRolesForUser(u.UserName);
dRow[2] = roles.Contains("Admin") ? true : false;
dRow[3] = roles.Contains("DPAO User") ? true : false;
dRow[4] = roles.Contains("GeneralUser") ? true : false;
dTable.Rows.Add(dRow);
}
GridView1.DataSource = dTable;
GridView1.DataBind();
Now i want to make this condition dynamic for which i have written code..
string[] rolesarr = Roles.GetAllRoles();
DataTable dTable = new DataTable();
dTable.Columns.Add("Select", typeof(bool));
dTable.Columns.Add("Username", typeof(string));
Array.ForEach(rolesarr, r => dTable.Columns.Add(r, typeof(bool)));
foreach (MembershipUser u in Membership.GetAllUsers())
{
DataRow dRow = dTable.NewRow();
dRow[0] = false;
dRow[1] = u.UserName;
string[] roles = Roles.GetRolesForUser(u.UserName);
for (int i = 0; i < roles.Length; i++)
{
string rol = roles[i];
for (int j = 2; j < dTable.Columns.Count; j++)
{
dRow[j] = roles.Contains(rol) ? true : false;
}
}
dTable.Rows.Add(dRow);
}
GridView1.DataSource = dTable;
GridView1.DataBind();
And Here is my RowDatabound event for checkboxes ..
protected void GridView1_RowDataBound1(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
CheckBox c0 = (CheckBox)e.Row.Cells[0].Controls[0];
CheckBox c2 = (CheckBox)e.Row.Cells[2].Controls[0];
CheckBox c3 = (CheckBox)e.Row.Cells[3].Controls[0];
CheckBox c4 = (CheckBox)e.Row.Cells[4].Controls[0];
c0.Enabled = c2.Enabled = c3.Enabled = c4.Enabled = true;
}
}
Please guys help me ..Thanks in advance...
the problem should be the double loops you provided.
According to your hardcoded code, you want to map between roles in the array rolesarr and roles of users, to show which roles is checked for each user.
To set values for data row at indext 2 - 4, you will have two loops, first loop to repeat rolesarr array and second loop to repeat roles array and compare them in the second loop
This is the code I mean:
string[] rolesarr = Roles.GetAllRoles();
DataTable dTable = new DataTable();
dTable.Columns.Add("Select", typeof(bool));
dTable.Columns.Add("Username", typeof(string));
Array.ForEach(rolesarr, r => dTable.Columns.Add(r, typeof(bool)));
foreach (MembershipUser u in Membership.GetAllUsers())
{
DataRow dRow = dTable.NewRow();
dRow[0] = false;
dRow[1] = u.UserName;
string[] roles = Roles.GetRolesForUser(u.UserName);
for (int i = 0; i < rolesarr.Length; i++)
{
for (int j = 0; j < roles.Length; j++)
{
if (rolesarr[i] == roles[j])
{
dRow[i + 2] = true;
break;
}
}
}
dTable.Rows.Add(dRow);
}
GridView1.DataSource = dTable;
GridView1.DataBind();
Please notice that I use data row index as i + 2 (dRow[i + 2]) in the second loop, because your role columns start at index=2, not 0, and the length must equal rolesarr.Length which you use them as role colums.
Related
I tried this solution below:
This Row already belongs to another table error when trying to add rows?
I have a Datatable that contains 597 Columns and 20 Rows and are trying to export the data to excel. However, Excel has a maximum column count 256 and so I need to divide the source data into 3 datatables to make the export work.
Below is the code I have written.
var dtmasterdata = data.Tables[name];
for (int j = 1; j < datatableNumberCount; j++)
{
DataTable dt2 = new DataTable();
dt2.TableName = "Master_" + j;
dt2 = dtmasterdata.Copy();
foreach (DataColumn col in dtmasterdata.Columns)
{
DataColumn dtcol = new DataColumn();
dtcol = col;
dt2.Columns.Add(dtcol.ColumnName, dtcol.DataType);
}
for (int k = 0; k < dtmasterdata.Rows.Count; k++)
{
DataRow dr = dt2.NewRow();
dr = dtmasterdata.Rows[k];
dt2.ImportRow(dtmasterdata.Rows[k]);
//dt2.Rows.Add(dr.ItemArray);
}
After that I need to delete few columns like below and I want to create 3 datatables
foreach (DataColumn col in dtmasterdata.Columns)
{
if (j == 1)
{
// condition 1
if (col.Ordinal >= 255)
{
dt2.Columns.RemoveAt(col.Ordinal);
}
}
if (j == 2)
{
// condition 2.
if (col.Ordinal < 255 || col.Ordinal >= 510)
{
dt2.Columns.RemoveAt(col.Ordinal);
}
}
if (j == 3)
{
// condition 3.
if (col.Ordinal <= 510 || col.Ordinal >= 765)
{
dt2.Columns.Add(col);
}
}
}
int worksheetNumber = 1;
string worksheetNameWithNumber = "Master Data";
if (worksheetNumber > 1)
worksheetNameWithNumber = String.Format("{0}_{1}", ws1, worksheetNumber.ToString());
Infragistics.Excel.Worksheet worksheet = wb.Worksheets.Add(worksheetNameWithNumber);
Infragistics.WebUI.UltraWebGrid.UltraWebGrid masterData1 = new Infragistics.WebUI.UltraWebGrid.UltraWebGrid("masterDataGrid");
masterData1.Browser = Infragistics.WebUI.UltraWebGrid.BrowserLevel.UpLevel;
masterData1.DataSource = dt2;
masterData1.DataMember = "Master_" + j;
masterData1.DisplayLayout.HeaderStyleDefault.Font.Bold = true;
masterData1.DisplayLayout.HeaderStyleDefault.Font.Name = "Arial";
masterData1.DisplayLayout.HeaderStyleDefault.Font.Size = FontUnit.Parse("10px");
masterData1.DisplayLayout.HeaderStyleDefault.BackColor = System.Drawing.Color.LightGray;
masterData1.DisplayLayout.RowStyleDefault.Font.Name = "Arial";
masterData1.DisplayLayout.RowStyleDefault.Font.Size = FontUnit.Parse("10px");
Infragistics.WebUI.UltraWebGrid.UltraGridBand masterBand1 = new Infragistics.WebUI.UltraWebGrid.UltraGridBand();
masterData1.Bands.Add(masterBand1);
dgResults.Controls.Add(masterData1);
masterData1.DataBind();
wb.ActiveWorksheet = worksheet;
this.ugWebGridExporter.Export(masterData1, worksheet);
worksheetNumber++;
Your error is because you are trying to add a column to a datatable that already belongs to your source datatable.
dt2.Columns.Add(col);
You can't just iterate through the columns of a datatable and add them to another.
I've a solution to this, which involves cloning the source data and removing what you don't need.
1st, make 3 clones of the datatables you need. Below is an example with me creating my own source table with 596 columns. Notice that clone only takes the data table structure, no data!
var source597ColsTable = new DataTable("Source");
for (var i = 0; i <= 596; i++)
{
source597ColsTable.Columns.Add(new DataColumn("Column" + i , typeof(string)));
}
DataRow newRow = source597ColsTable.NewRow();
source597ColsTable.Rows.Add(newRow);
var cols0To199Table = source597ColsTable.Clone();
var cols200To399Table = source597ColsTable.Clone();
var cols400To596Table = source597ColsTable.Clone();
Next copy all the rows from the source table into the clones. The below is a simple function to do so.
private DataTable CopyRowsFromSource(DataTable sourceTable, DataTable destinationTable)
{
foreach (DataRow row in sourceTable.Rows)
{
destinationTable.Rows.Add(row.ItemArray);
}
return destinationTable;
}
Then call this function for each of your tables.
cols0To199Table = CopyRowsFromSource(source597ColsTable, cols0To199Table);
cols200To399Table = CopyRowsFromSource(source597ColsTable, cols200To399Table);
cols400To596Table = CopyRowsFromSource(source597ColsTable, cols400To596Table);
Finally, remove all the columns from the datatables to give you your split.
private DataTable RemoveColumns(DataTable table, int startCol, int endCol)
{
var colsToRemove = new List<DataColumn>();
for (var colCount = startCol; colCount <= endCol; colCount++)
{
colsToRemove.Add(table.Columns[colCount]);
}
foreach (DataColumn col in colsToRemove)
{
table.Columns.Remove(col);
}
return table;
}
Then call.. again for each cloned table.
cols0To199Table = RemoveColumns(cols0To199Table, 200, 596);
cols200To399Table = RemoveColumns(cols200To399Table, 0, 199);
cols200To399Table = RemoveColumns(cols200To399Table, 200, 396);
cols400To596Table = RemoveColumns(cols400To596Table, 0, 399);
After running this, you will have 3 datatables, columns 0-199, 200-399 and 400-596.
Hope that helps.
I am not sure to have really understood all of your code, but to copy a subset of columns to another datatable there is a very simple method in the DataView class named ToTable where you can list the columns you want in the new table. As added bonus, this method copies also the data in the 20 rows of your original table.
So the only difficult is to list these columns to the method.
You can proceed in this way using linq over the DataColumn collection
string[] firstCols = dtmasterdata.Columns
.Cast<DataColumn>()
.Take(255)
.Select(x => x.ColumnName).ToArray();
string[] secondCols = dtmasterdata.Columns
.Cast<DataColumn>()
.Skip(255)
.Take(255)
.Select(x => x.ColumnName).ToArray();
string[] thirdCols = dtmasterdata.Columns
.Cast<DataColumn>()
.Skip(510)
.Select(x => x.ColumnName).ToArray();
DataTable t1 = dtmasterdata.DefaultView.ToTable("Master_1", false, firstCols);
DataTable t2 = dtmasterdata.DefaultView.ToTable("Master_2", false, secondCols);
DataTable t3 = dtmasterdata.DefaultView.ToTable("Master_3", false, thirdCols);
This is my code to remove row from datatable:
DataTable dtapple = dt;
foreach (DataRow drapplicant in dtapple.Rows)
{
int iapp = Convert.ToInt32(drapplicant["SrNo"].ToString());
if (drapplicant["PassportExpDate"].ToString().Trim() != "")
{
//ViewState["iapp"] = drapplicant;
dtapple.Rows.Remove(drapplicant);
}
}
Now when I use above code the row is removed, but after that I get an error
Collection was modified; enumeration operation might not execute
I don't know exact reason.
You get this error because a collection must not change while iterating it. To remove some items from a collection you usually need a second collection that you iterate without changing it.
For your DataTable you need to get the rows you want to remove first and put them in a new collection. One way to achieve this is with LINQ:
Let's create some test data:
DataTable dt = new DataTable();
dt.Columns.Add("Test", typeof(bool));
DataRow dr1 = dt.NewRow();
DataRow dr2 = dt.NewRow();
DataRow dr3 = dt.NewRow();
dr1["Test"] = true;
dr2["Test"] = false;
dr3["Test"] = false;
dt.Rows.Add(dr1);
dt.Rows.Add(dr2);
dt.Rows.Add(dr3);
then only get rows where value in the Test column is false and put them in a List<DataRow>:
var removeRows =
dt
.AsEnumerable()
.Where(r => (bool)r["Test"] == false)
.ToList();
now you can itereate the new removeRows list and remove its items from the first collection (here DataTable.Rows)
// Remove selected rows.
foreach (var row in removeRows)
{
dt.Rows.Remove(row);
}
In your this query should work:
var removeRows =
dtapple
.AsEnumerable()
.Where(r => string.IsNullOrEmpty(r["PassportExpDate"].ToString()) == false)
.ToList();
If you use string.IsNullOrEmpty() there's no need to Trim() it.
Try this :
for (int i = 0; i < dataTable.Rows.Count; i++)
{
var tempRow = dataTable.Rows[i];
var temp = dataTable.Rows[i][0];
for (int j = 0; j < dataTable.Rows.Count; j++)
{
DataRow rows = dataTable.Rows[j];
if (temp == rows[0].ToString())
{
tempdatatable.Rows.Add(tempRow[0], tempRow[1]);
dataTable.Rows.Remove(rows); //Update happen here
}
tempdatatable.DefaultView.Sort = "gscitations DESC";
dataGridView1.DataSource = tempdatatable;
}
}
Below code works for me :
for (int i = 0; i < dataTable.Rows.Count; i++)
{
var tempRow = dataTable.Rows[i];
var temp = dataTable.Rows[i][0];
for (int j = 0; j < dataTable.Rows.Count; j++)
{
DataRow rows = dataTable.Rows[j];
if (temp == rows[0].ToString())
{
tempdatatable.Rows.Add(tempRow[0], tempRow[1]);
dataTable.Rows.Remove(rows); //Update happen here
}
tempdatatable.DefaultView.Sort = "gscitations DESC";
dataGridView1.DataSource = tempdatatable;
}
}
I am trying to bind string array to grid view. While using the given below code showing the error "A data item was not found in the container. The container must either implement IDataItemContainer, or have a property named DataItem." Please help me to find a proper solution. Thank you.
Code:
protected void ddlCircle_SelectedIndexChanged(object sender, EventArgs e)
{
ShadingAnalysisDataSetTableAdapters.tbl_CadEngineersTeamTableAdapter cd;
cd = new ShadingAnalysisDataSetTableAdapters.tbl_CadEngineersTeamTableAdapter();
DataTable dt = new DataTable();
dt = cd.GetAvailableData(ddlCircle.SelectedValue); // Getting details of unassigned site
int x, y; //z;
DataTable dt3 = new DataTable();
dt3 = cd.GetTeam();
y = dt3.Rows.Count;
x = dt.Rows.Count; // counting the unassinged sites
DataTable dt2 = new DataTable();
dt2 = cd.GetAssignTeam(x); //Getting team based on count
string[] arr = new string[dt2.Rows.Count];
int i = 0;
foreach (DataRow r in dt2.Rows)
{
arr[i] = r["Team"].ToString(); // assigning available team to array
i++;
}
string[] strArr = new string[100]; // another array to copy arr values.
i = 0; int j = 0;
while (j <= x)
{
strArr[j]= arr[i] ; // copying the arr[] values into strArr[] based on count.
i++;
j++;
if (i == 3)
{
i = 0;
}
}
GridView2.DataSource = strArr;
GridView2.DataBind(); // error popup here
}
Define a GridView's column such that it binds to the Team column of your DataTable and assign the DataTable directly to the GridView as DataSource. Then DataBind to the DataTable.
Binding Array to DataGrid is just like putting bananas in egg tray. Please you have to bind a source having structure according to datagrid. As suggested by #Konstantin D - Infragistics
Now the gridview showing strArr[j] array values
protected void ddlCircle_SelectedIndexChanged(object sender, EventArgs e)
{
ShadingAnalysisDataSetTableAdapters.tbl_CadEngineersTeamTableAdapter cd;
cd = new ShadingAnalysisDataSetTableAdapters.tbl_CadEngineersTeamTableAdapter();
DataTable dt = new DataTable();
dt = cd.GetAvailableData(ddlCircle.SelectedValue); // Getting details of unassigned site
int x, y; //z;
DataTable dt3 = new DataTable();
dt3 = cd.GetTeam();
y = dt3.Rows.Count;
x = dt.Rows.Count; // counting the unassinged sites
DataTable dt2 = new DataTable();
dt2 = cd.GetAssignTeam(x); //Getting team based on count
string[] arr = new string[dt2.Rows.Count];
int i = 0;
foreach (DataRow r in dt2.Rows)
{
arr[i] = r["Team"].ToString(); // assigning available team to array
i++;
}
string[] strArr = new string[x+1]; // another array to copy arr values.
i = 0; int j = 0;
while (j <= x)
{
strArr[j]= arr[i] ; // copying the arr[] values into strArr[] based on count.
i++;
j++;
if (i == 3)
{
i = 0;
}
}
GridView2.DataSource = strArr;
GridView2.DataBind();
}
I searching for a easy method for adding new row to datagrid. So, what I have:
dataGridView2.ColumnCount = 4;
int w = 0;
foreach (var item in tInArr)
{...
dataGridView2.Rows.Add();
dataGridView2[0, w].Value = muTat3.ToString();
dataGridView2[1, w].Value = item.ToString();
....
w++;}
Where is my mistake? I've read some articles here, but there's no answers.
if you have no datasource, then you can go the following way:
int rowIndex = dataGridView1.Rows.Add();
dataGridView1[0, rowIndex].Value = "value1"; // 0 for first column
dataGridView1[1, rowIndex].Value = "value2"; // 1 for second column
rowIndex = dataGridView1.Rows.Add();
dataGridView1[0, rowIndex].Value = "value3";
dataGridView1[1, rowIndex].Value = "value4";
in your code it should be:
// dataGridView2.ColumnCount = 4;
int w = 0;
foreach (var item in tInArr)
{...
w = dataGridView2.Rows.Add();
dataGridView2[0, w].Value = muTat3.ToString();
dataGridView2[1, w].Value = item.ToString();
....
//w++; this is not required
}
Here you can use datable then iterate your loop like this way :
foreach (DataRow rows in dt.Rows)
{..
int w = dataGridView2.Rows.Add();
dataGridView2[0, w].Value = rows[0].ToString();
dataGridView2[1, w].Value = rows[1].ToString();
}
First You create the datatable and then you can set the datasource of datagrid its long but easy to maintain.
like this
DataTable table = new DataTable();
table.Columns.Add("Check", typeof(bool));
table.Columns.Add("Path", typeof(string));
table.Columns.Add("Date", typeof(DateTime));
table.Rows.Add(false, "", DateTime.Now);
dataGridView2.DataSource = table;
I have created a table in code behind file dynamically:
The code for creating this table is like this:
protected void BindGridviewNew(Guid SubscriptionID)
{
pnlreapeter.Visible = true;
gridviewnew.Visible = true;
List<string> plannig = new List<string>();
var s = m.bussinesCollection.BussinesPlanning.GetSingleSubVersionTrueFalse(SubscriptionID);
if (s != null)
{
if (s.T1.Value)
{
plannig.Add("T1");
}
if (s.T2.Value)
{
plannig.Add("T2");
}
if (s.T3.Value)
{
plannig.Add("T3");
}
if (s.T4.Value)
{
plannig.Add("T4");
}
if (s.T5.Value)
{
plannig.Add("T5");
}
if (s.T6.Value)
{
plannig.Add("T6");
}
if (s.T7.Value)
{
plannig.Add("T7");
}
if (s.T8.Value)
{
plannig.Add("T8");
}
if (s.T9.Value)
{
plannig.Add("T9");
}
if (s.T10.Value)
{
plannig.Add("T10");
}
}
DataTable PlanningDate = m.bussinesCollection.BussinesPlanning.GetRowOfPlanningDate(SubscriptionID);
DataTable Percentage = m.bussinesCollection.BussinesPlanning.GetAllStudentsForProgressForDocentNew(SubscriptionID);
DataTable dt = new DataTable();
DataRow newrow;
newrow = dt.NewRow();
DataRow Hiddenfield;
Hiddenfield = dt.NewRow();
DataRow percentage;
percentage = dt.NewRow();
int count = plannig.Count;
for (int j = 0; j < count; j++)
{
dt.Columns.Add(plannig[j], typeof(string));
string pl = plannig[j];
string c = pl.Substring(pl.Length - 1, 1);
int x = Convert.ToInt32(c);
DataRow dr = PlanningDate.Rows[0];
DateTime date = DateTime.Parse(dr[x-1].ToString());
newrow[plannig[j]] = date.ToShortDateString();
HiddenField hf = new HiddenField();
Hiddenfield[plannig[j]] = x;
DataRow dr1 = Percentage.Rows[0];
LinkButton link = new LinkButton();
link.Text = dr1[x].ToString();
percentage[plannig[j]] = (System.Web.UI.WebControls.LinkButton) link;
}
dt.Rows.Add(newrow);
dt.Rows.Add(percentage);
// dt.Rows.Add(Hiddenfield);
gridviewnew.DataSource = dt;
gridviewnew.DataBind();
}
The problem here is,as in screen shot I am trying to get link-buttond but the column type is string so that it shows "System.Web.UI.WebControls.LinkButton"
The table I want is like:
T1 | T2 | T3
3/01/2012| 3/03/2012| 3/05/2012
100 | 50 | -
where on clicking on 100 or 50 a new popup should be displayed.
Can any one help me to create this row..?
You can not add a LinkButton to a DataTable. What you should do is bind the DataTable to the GridView, and then manually add a new row to the grid view with the link buttons, I guess in the RowDataBound event, or if there is going to be just one row with link buttons, you can add a footer to the grid view.
Check this link How to programmatically insert a row in a GridView?