I'm Working on a c# projet (webform).
Is it possible to Hide the name of the column when I Bind my DataTable to the Gridview ?
This is my DataTable:
¤----------¤----------¤----------¤
| Column 1 | Column 2 | Column 3 |
¤----------¤----------¤----------¤
| Data 1 | Data 1 | Data 1 |
¤----------¤----------¤----------¤
| Data 4 | Data 5 | Data 6 |
¤----------¤----------¤----------¤
and I would like to reach this in my GridView
¤----------¤----------¤----------¤
| Data 1 | Data 1 | Data 1 |
¤----------¤----------¤----------¤
| Data 4 | Data 5 | Data 6 |
¤----------¤----------¤----------¤
Is it possible and How could I do it please ?
EDIT:
In The First Row,I have many datas which are the same. How Could I join my cells in C# on my DataTable please?
¤----------¤----------¤----------¤----------¤----------¤----------¤
| Data 1 | Data 2 |
¤----------¤----------¤----------¤----------¤----------¤----------¤
| Data 4 | Data 5 | Data 6 | Data 7 | Data 8 | Data 9 |
¤----------¤----------¤----------¤----------¤----------¤----------¤
I would Like to reach this if possible
Have you tried setting the GridView's ColumnHeadersVisible property to False?
EDIT:
DataView view = new DataView(table);
DataTable distinctValues = view.ToTable(true, "Column1", "Column2" ...);
in web form
<asp:GridView runat="server" HeaderStyle-CssClass="hide">
</asp:GridView>
in css
.hide { display: none; }
DataRow dr = dt.Rows[0];
dr.Delete();
dt.AcceptChanges();
After that bind your datatable to your grid.
Edit
protected void OnDataBound(object sender, EventArgs e)
{
GridViewRow row = new GridViewRow(0, 0, DataControlRowType.Header, DataControlRowState.Normal);
TableHeaderCell cell = new TableHeaderCell();
cell.Text = "Your text1";
cell.ColumnSpan = 3;
row.Controls.Add(cell);
cell = new TableHeaderCell();
cell.ColumnSpan = 3;
cell.Text = "Your text2";
row.Controls.Add(cell);
GridView1.HeaderRow.Parent.Controls.AddAt(0, row);
}
Related
I have two datatables, I am trying to copy row from one table to another, I have tried this. the thing is that my tables are not exactly the same, both tables have common headers, but to the second table have more columns, therefore I need "smart" copy, i.e to copy the row according to the column header name.
d1:
+--------+--------+--------+
| ID | aaa | bbb |
+--------+--------+--------+
| 23 | value1 | value2 | <----copy this row
d2:
+--------+--------+--------+--------+
| ID | ccc | bbb | aaa |
+--------+--------+--------+--------+
| 23 | | value2 | value1 | <----I need this result
but this code:
string rowID=23;
DataRow[] result = dt1.Select($"ID = {rowID}");
dt2.Rows.Add(result[0].ItemArray);
gives:
d2:
+--------+--------+--------+--------+
| ID | ccc | bbb | aaa |
+--------+--------+--------+--------+
| 23 | value1 | value2 | | <---- :( NOT what I need
I think this is your homework, but here you have some simple and not very smart solution:
private DataTable DTCopySample()
{
int cnt = 0;
DataTable dt1 = new DataTable();
dt1.Columns.Add("ID");
dt1.Columns.Add("aaa");
dt1.Columns.Add("bbb");
DataTable dt2 = new DataTable();
dt2.Columns.Add("ID");
dt2.Columns.Add("ccc");
dt2.Columns.Add("bbb");
dt2.Columns.Add("aaa");
dt1.Rows.Add();
dt1.Rows[0]["ID"] = "23";
dt1.Rows[0]["aaa"] = "val1";
dt1.Rows[0]["bbb"] = "val2";
dt1.Rows.Add();
dt1.Rows[1]["ID"] = "99";
dt1.Rows[1]["aaa"] = "val99";
dt1.Rows[1]["bbb"] = "val98";
string colName = string.Empty;
foreach (DataRow row in dt1.Rows)
{
dt2.Rows.Add();
foreach (DataColumn col in dt1.Columns)
{
dt2.Rows[cnt][col.ColumnName] = row[col.ColumnName].ToString();
}
cnt++;
}
return dt2;
}
There are more smart and better solutions, but this is fast-written (2 mins) and works.
Remeber, that you have not specified columns datatypes or anything else, so I assumed there are strings everywhere for creating simple sample.
I have a database with a table. What I want to do is programatically load values from a column of the table to a column of the DataGridView.
I have a table "Actions", with a field "Total", which has some data: 10, 20, 35, 50, etc.
I want to put this field into the DataGridView in the 2nd column.
So the DataGridView should look like this.(the other columns are already set).
| Name | Total | Something |
|:-----------|------------:|:------------:|
| adsad | 10 | This |
| sddssdf | 20 | column |
| name1 | 35 | will |
| name | 50 | be |
| nmas | 1 | center |
| gjghjhh | 67 | aligned |
You need to create the particular column in Gridview and try following code :
DataGridView dataGridView2 = new DataGridView();
BindingSource bindingSource2 = new BindingSource();
dataGridView2.ColumnCount = 2;
dataGridView2.Columns[0].Name = "FieldOne";
dataGridView2.Columns[0].DataPropertyName = "FieldOne";
dataGridView2.Columns[1].Name = "FieldTwo";
dataGridView2.Columns[1].DataPropertyName = "FieldTwo";
bindingSource1.DataSource = GetDataTable();
dataGridView1.DataSource = bindingSource1;
you can add a new column to your DataTable and then bind it to your DataGridView.
//call SQL helper class to get initial data
DataTable dt = sql.ExecuteDataTable("sp_MyProc");
dt.Columns.Add("NewColumn", typeof(System.Int32));
foreach(DataRow row in dt.Rows)
{
//need to set value to NewColumn column
row["NewColumn"] = 0; // or set it to some other value
}
// possibly save your Dataset here, after setting all the new values
dataGridView1.DataSource = dt;
I've seen this article http://asp.net-informations.com/gridview/newrow.htm and this post http://forums.asp.net/p/1534978/3725419.aspx#3725419 and I've done it for have that separator row collapsible with jquery and it's working great in display mode. The problems occuring when try to do something else with gridview, because there's a weird behaviour.. I've add a simple button that have just to set a radiobutton that's in every gridview row (except in the new added GroupHeaders rows). Then if I have added two new row he is skipping setting the last two rows in the GridView..
public void AddNewRow(object sender, GridViewRowEventArgs e)
{
GridView GridView1 = (GridView)sender;
GridViewRow NewTotalRow = new GridViewRow(-1, -1, DataControlRowType.Header, DataControlRowState.Normal);
TableCell HeaderCell = new TableCell();
HeaderCell.Attributes.Add("onclick", "collapsible('" + rowgroup + "')");
NewTotalRow.Cells.Add(HeaderCell);
TableCell HeaderCellIndex = new TableCell();
int indexCorrente = e.Row.RowIndex + index;
HeaderCellIndex.Text = indexCorrente.ToString();
NewTotalRow.Cells.Add(HeaderCellIndex);
GridView1.Controls[0].Controls.Add(NewTotalRow);
}
protected void gdDettaglio_RowCreated(object sender, GridViewRowEventArgs e)
{
bool newRow = false;
if ((DataBinder.Eval(e.Row.DataItem, "Stato") != null))
{
if (statoCorrente != Convert.ToInt32(DataBinder.Eval(e.Row.DataItem, "Stato").ToString()))
newRow = true;
}
if (newRow)
{
AddNewRow(sender, e);
}
}
Printing the row index (just to check it) next to each row I'm displaying this situation (with two GroupHeader rows added):
(The index are as they are printing them in gdDettaglio_RowCreated for GroupHeadrs rows and on gdDettaglio_OnDataBound for the other rows)
-----------------------------------------
| HEADER |
|---------------------------------------|
-----------------------------------------
| Gruppo 1 | index -1 |
|---------------------------------------|
| grp1 | x | blablabla | | index 0 |
| grp1 | y | blablabla | | index 1 |
| grp1 | z | blablabla | | index 2 |
| grp1 | x | blablabla | | index 3 |
| grp1 | x | blablabla | | index 4 |
|---------------------------------------|
| Gruppo 2 | index -1 |
|---------------------------------------|
| grp2 | x | blablabla | | index 5 |
| grp2 | y | blablabla | | index 6 |
| grp2 | z | blablabla | | index 7 |
| grp2 | z | blablabla | | index 8 |
| grp2 | z | blablabla | | index 9 |
| grp2 | z | blablabla | | index 10 |
-----------------------------------------
in the button code I've just:
foreach (GridViewRow riga in gdDettaglio.Rows)
{
if (riga.RowType == DataControlRowType.DataRow)
{
RadioButtonList rad = (RadioButtonList)riga.FindControl("rad");
rad.SelectedValue = "True";
}
}
UPDATE:
Doing the same thing on jquery work, it affects all the row:
function accettaTutte() {
$("#<%=gdDettaglio.ClientID%> tr:has(td)").each(function () {
var items = $(this).find("[id$='radDaPa'] input:radio'");
for (var i = 0; i < items.length; i++) {
if (items[i].value == 'True') {
if (!(items[i].checked)) {
items[i].checked = true;
}
break;
}
}
});
return false;
}
But I still need to do a foreach on that gridview, to update db, some idea on what could try to do? On every row I've also a "single row save" ImageButton, but clicking on it on the last two rows it's not firing the RowCommand event... It's like the two added GroupHeader rows are pushing out the last two data rows, no matter about the index.. If I click the ImageButton on the row with displayed (using Text='<%#Container.DataItemIndex%>') rowIndex 2, in the rowCommand it become rowIndex 3, but it modified the right row, the one I've clicked.. If i do the same on row 7, it become 9.. But if forced it to get value on rowIndex 11, U'm getting ArgumentOutOfRangeException, because Rows.Count It's still 11..
OK, now I am adding to the list that is GridView DataSource as many empty elements as are the GroupHeaders rows, so GridView.Rows.Count is enough to get all the rows..
I have a DataTable. I want to select the rows based on the Index/Row Number of the rows in DataTable.
Suppose below is the DataTable:
---------------- ---------------
| ID | Name | | Index/RowNo |
---------------- ---------------
| A001 | John | | 1 |
| A002 | Foo | | 2 |
| A003 | Rambo | | 3 |
| A004 | Andy | | 4 |
| ... | ... | | 5 |
---------------- ---------------
Now, i want to select the Rows from above shown DataTable using criteria say for example Index > 2, In that case First entry at Index 1, A001 | John, will not become part of the resultant DataTable. How can i do it efficiently?
Moreover, i want to have my result both in the form of DataTable and Linq query outcome.
I am trying to do something like this:
var result = dt.Select("RowNum > 1", "");
OR
var result = from row in dt.AsEnumerable()
where RowNum > 1
select row;
I am trying to do something like this:
var result = dt.Select("RowNum > 1", "");
You can use Enumerable.Skip even with a DataTable since it is an IEnumerable<DataRow>:
IEnumerable<DataRow> allButFirst = table.AsEnumerable().Skip(1);
get a new DataTable with:
DataTable tblAllButFirst = allButFirst.CopyToDataTable();
If your next question is how you can take only rows with given indices:
var allowedIndices = new[]{ 2, 4, 7, 8, 9, 10 };
DataTable tblAllowedRows = table.AsEnumerable()
.Where((r, i) => allowedIndices.Contains(i))
.CopyToDataTable();
var result = table.AsEnumerable()
.Where((row, index) => index > 1)
.CopyToDataTable()
I want to merge table but i don't know how. I have already tried many times but still can't get the right solution. Right now my gridview is like this :
Data 1 | Data 1 | Data 1 | Data 1
Data 1 | Data 1 | Data 1 | Data 1
Data 2 | Data 2 | Data 2 | Data 2
Data 2 | Data 2 | Data 2 | Data 2
And I want the gridview to be like this :
Data 1 | Data 1 | Data 1 | Data 1
| Data 1 | Data 1 |
Data 2 | Data 2 | Data 2 | Data 2
| Data 2 | Data 2 |
How to merge cells with equal values in a GridView
this will help you
The code that merges the cells is very short:
public class GridDecorator
{
public static void MergeRows(GridView gridView)
{
for (int rowIndex = gridView.Rows.Count - 2; rowIndex >= 0; rowIndex--)
{
GridViewRow row = gridView.Rows[rowIndex];
GridViewRow previousRow = gridView.Rows[rowIndex + 1];
for (int i = 0; i < row.Cells.Count; i++)
{
if (row.Cells[i].Text == previousRow.Cells[i].Text)
{
row.Cells[i].RowSpan = previousRow.Cells[i].RowSpan < 2 ? 2 :
previousRow.Cells[i].RowSpan + 1;
previousRow.Cells[i].Visible = false;
}
}
}
}
}
The last action is to add an OnPreRender event handler for the GridView:
protected void gridView_PreRender(object sender, EventArgs e)
{
GridDecorator.MergeRows(gridView);
}