OnItemDataBound to set row values - data-binding

I need to set a cell value to something dependant on other values which are only available during data binding so I'm using OnItemDataBound but it says I can't set the dataitem value.
Any ideas how to do this?
protected override void OnItemDataBound(RepeaterItemEventArgs e) {
base.OnItemDataBound(e);
DateTime date = (DateTime)DataBinder.Eval(e.Item.DataItem, "date");
string year = String.Format("{0:yyyy}", date);
string month = String.Format("{0:MM}", date);
((DataRowView)e.Item.DataItem)["url"] = "/" + year + "/" + month;
}
Results in the exception:
System.Data.DataException: Cannot set url.

Well I guess this isn't possible then. I've gotten around the problem by setting the values in the underlying datatable before binding to the repeater.

Related

C#/ASP.Net - Extract bit value of column in a gridview

I have a gridview that is SQL bound. In some of the columns there are bit values. When I use C# to get the values into the gridview, checkboxes are displayed. I need to extract the value of that column into text.
SqlConnection sConnection = new SqlConnection(MyConnectionString);
SqlCommand sCommand = new SqlCommand();
using (sConnection)
{
sCommand.Connection = sConnection;
sCommand.CommandText = "MyStoredProcedure";
sCommand.CommandType = CommandType.StoredProcedure;
sCommand.Connection.Open();
SqlDataReader reader = sCommand.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
gridView.DataSource = reader;
gridView.DataBind();
}
for (int i = 0; i < gridView.Rows.Count; i++)
{
ListBox1.Items.Add(gridView.Rows[i].Cells[3].Text);
}
}
}
The gridview column data type is 'bit'. I do not have access to the database or stored procedure to change anything there. I need to somehow extract the '0' or '1' value, but when I do it like above, the text is blank.
I also tried to use 'GetOrdinal'. It returned a True/False value from the database, but I could not figure out how to get the value for each item in the gridview.
if (!reader.IsDBNull(reader.GetOrdinal("MyColumn1")))
{
ListBox1.Items.Add(reader.GetOrdinal("MyColumn1").ToString());
}
General overview:
You need to be able to find the CheckBox that's generated and get the value of it's "Checked" property.
To do this, you need to be able to use the FindControl() method on the GridViewRow.
To use FindControl, the CheckBox needs a predictable name.
To get a predictable name, you need to have that column be a TemplateColumn so that you can specify the name of the CheckBox in the markup on the ASPX page.
There's a full working set of code here: http://www.codeproject.com/Articles/25056/The-RIGHT-Way-to-Use-Checkboxes-in-a-NET-Repeater
This shows the code for a Repeater, but it's the same principle and general code for any DataBound control.
The code below should work with modifications to match your DB names:
<asp:TemplateField>
<ItemTemplate >
<asp:checkbox id="MyColumnNameCheckbox" runat="server" />
</ItemTemplate>
</asp:TemplateField>
string defaultvalue = "0"; // To be used to display the value of the original bit field.
foreach (GridViewRow row in GridView1.Rows)
{
CheckBox chkBx = (CheckBox)row.FindControl("MyColumnNameCheckbox");
if (chkBx != null && chkBx.Checked)
{
defaultvalue = "1";
}
}
I was able to figure it out. Thanks, David Stratton, for pointing me in the right direction.
I did it by assigning an id to the dynamically created control first. then did the FindControl()...
Control ctrl = GridView1.SelectedRow.Cells[4].Control[0];
ctrl.ID = "ctrl";
Boolean result = Convert.ToBoolean(((Checkbox)GridView1.Rows[0].Cells[4].FindControl("ctrl")).Checked);
TextBox1.Text = result.ToString();
This returns a value of "True" or "False"...
Thanks again.
Another way to resolve it:
bool result = (GridView1.SelectedRow.Cells[4].Control[0] as Checkbox).Checked;
TextBox1.Text = result.ToString();
it resolve the problem with less code :)

How to bind data column to textbox?

I have datagridview and textboxes on form. I load records from different tables when user clicks any one radiobutton. Data in grid is shown perfectly. I want to show values of the row in those textboxes.
One solution can be: binding data from dataset.
Second one can be: transfer values of each cell of row to respective textbox.
Please help me. And, please tell me which one is better or is there any other method which is even better than these two.
Thanks in advance.
Try using a BindingSource
BindingSource bindingSource = new BindingSource();
DataSet dataSet = new DataSet();
DataAdapter da1 = new DataAdapter("Select * from Customers", conn1);
DataAdapter da2 = new DataAdapter("Select * form Orders", conn1);
da1.Fill(dataSet,"Customers");
da2.Fill(dataSet,"Orders");
//Let we set Customers table as bindiningSource datasource
bindingSource.DataSource = dataSet.Tables["Customers"];
private void RadioButtonCustomers_CheckedChanged(object sender, EventArgs e)
{
if(radioButtonCustomers.Checked==true)
bindingSource.DataSource =dataSet.Tables["Customers"];
}
private void RadioButtonOrders_CheckedChanged(object sender, EventArgs e)
{
if(radioButtonOrders.Checked==true)
bindingSource.DataSource = dataSet.Tables["Orders"];
}
//First param of Binding is to which prop of TextBox to bind the value
//Second param is the data source
//Third param is the data member or the column name of the table as datasource, so
//we have to get that table from casting the bindingSource datasource prop and casting it
//to DataTable obj and after that to take the ColumnName prop of the desired column
textBox1.DataBindings.Add(new Binding("Text",bindingSource,((DataTable)bindingSource.DataSource).Columns[0].ColumnName));
textBox2.DataBindings.Add(new Binding("Text",bindingSource,((DataTable)bindingSource.DataSource).Columns[1].ColumnName));
etc...
Even if you change the datasource prop of bindingSource, textboxes will remain binded to rowvalue of first and second column
Hope this help.
Sir I done it making a simple WindowsForm with 2 radio buttons, 2 textboxes and datagridview
here is the sln file http://www13.zippyshare.com/v/98590888/file.html this must help u.
I tried many options to display value in textbox on the same form, but it was not working as datagridview could display records of two different tables.
Instead, I used the following event of datagridview:
private void dataGridView1_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
this.dataGridView1.SelectionChanged += new System.EventHandler(this.DisplayValueinTextBox);
}
In DisplayValueinTextBox, I wrote following code based on numbers of columns displayed for each table:
private void DisplayValueinTextBox(object sender, EventArgs e)
{
try
{
textBox1.Text = dataGridView1.SelectedCells[0].Value.ToString();
textBox2.Text = dataGridView1.SelectedCells[1].Value.ToString();
textBox3.Text = dataGridView1.SelectedCells[2].Value.ToString();
if (tblGrid == "Employee") //name of table which has more columns in grid
{
textBox4.Text = dataGridView1.SelectedCells[3].Value.ToString();
textBox5.Text = dataGridView1.SelectedCells[4].Value.ToString();
textBox6.Text = dataGridView1.SelectedCells[5].Value.ToString();
}
this.dataGridView1.SelectionChanged -= new System.EventHandler(this.DisplayValueinTextBox); //removed it as I was getting error.
}
catch (Exception exdisp)
{
MessageBox.Show(exdisp.Message);
}
}
I also changed SelectionMode property of dataGridView to FullRowSelect. This will ensure that textbox1 is displaying value of SelectedCells[0] even if user clicks any cell.
I still hope there is even a better option, so I wait for comments on this.

How to store cell value of an Asp.Net GridView row on click in a C# variable

I am having a GridView in my page , I want that when a particular row is clicked I want the cell value of that particular row.Currently I get that that value by using something like this ,
protected void SearchRecordGrid_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.Attributes.Add("onclick", "location='ModifyCustomerByCategory.aspx?ApplicationNo=" + e.Row.Cells[0].Text + "'");
}
}
Currently I am passing that value as a parameter to the page , can any body tell how can I store that value in a variable or , atleast on click I assign it to a hidden field.
Thanks for any suggestions.
Try this link.
It runs through everything you will need, and on the gridview selectedindexchanged event you can reference the value with GridView.SelectedRow.Cells[0].Text or the control containing the value Gridview.SelectedRow.FindControl("[Control Name]")
In row data bound simply save that value and use it
int appno = CInt(e.Row.Cells[0].Text)
and if you want to use this value to next page
int appno = CInt(Request.Querystring("ApplicationNo"))

ASP.Net Grid View rolling total in Gridview

I have seen several tutorials on how to achieve this.
However in my opinion they require a lot of prior knowledge on how to programatically refer to each item.
Does anyone have a link to or can create a relatively basic example of how to achive a running total in the footer for an ASP:Gridview?
This is what I use:
protected void InvoiceGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
var invoice = (Invoice) e.Row.DataItem;
if (e.Row.RowType == DataControlRowType.Header)
{
totalAmt = 0;
}
else if (e.Row.RowType == DataControlRowType.DataRow)
{
totalAmt += invoice.Amount;
}
else if (e.Row.RowType == DataControlRowType.Footer)
{
var amountTotalLabel = (TextBox) e.Row.FindControl("AmountTotalTextBox");
amountTotalLabel.Text = totalAmt.ToString("0.00");
}
}
TotalAmt is protected instance variable on the page. Not sure if it's what you were looking for based on your comment about "programmatic knowledge." But it works and is fairly straight-forward. The gridview is bound to a List<Invoice> in this case.
Add the footer Template and on the RowDataBound, have a global variable to store the summation sum,
At the e.Row.RowType = DataControlRowType.DataRow type do the summation , and # the e.Row.RowType = DataControlRowType.Footer store the vale in the appropriate cell
for further info look # MSDN LINK
This is how I do it. Very easy. You just sum the row that has your numbers in it and place it in the footer.
((Label)GridView.FooterRow.Cells[1].FindControl("your_label")).Text = ds.Tables[0].Compute("sum(Column_name)", "").ToString();
I think the method I use is pretty basic and doesn't require programatically referring to columns in the Gridview, if that's what you mean. That's one of the nice parts is that once you get the back-end functions written, you can add totals to any Gridview by only editing the .aspx file.
In your GridView, make the column like this:
<asp:TemplateField HeaderText="Hours">
<ItemTemplate><%#DisplayAndAddToTotal(Eval("Hours").ToString(), "Hours")%></ItemTemplate>
<FooterTemplate><%#GetTotal("Hours")%></FooterTemplate>
</asp:TemplateField>
The second parameter to DisplayAndAddToTotal can be any string you want as long as you use the same string in GetTotal. I usually just use the field name again though. Here are the two functions used, DisplayAndAddToTotal and GetTotal. They use a Hashtable to store the totals so that it works with any number of columns you want to add up. And they also work with counting the number of "True"s for a Boolean field.
Protected total As Hashtable = New Hashtable()
Protected Function DisplayAndAddToTotal(itemStr As String, type As String) As Double
Dim item As Double
If itemStr = "True" Then
item = 1
ElseIf Not Double.TryParse(itemStr, item) Then
item = 0
End If
If total.ContainsKey(type) Then
total(type) = Double.Parse(total(type).ToString()) + item
Else
total(type) = item
End If
Return item
End Function
Protected Function GetTotal(type As String) As Double
Try
Dim result As Double = Double.Parse(total(type).ToString())
Return result
Catch
Return 0
End Try
End Function

Sorted gridview selects wrong row

I have a gridview (actually a SPgridview)
And i made the columnname clickable so the users can sort the rows using the data.
And that works fine.
The problem occurs when users try to select a row after they sorted the data.
I can see that the gridview kinda "forgets" how the rows were sorted and selects the row that was at the clicked index before it got sorted..
How do i fix that?
I tried sorting the row again after the user selects a row, but that doesnt seem to work.
And should the gridview remember the fact that it was just sorted?
Thanks in advance :)
When you handle the Sorting event set a session variable set it to the sort direction and use it when you rebind your datasource.
protected void gridview_Sorting()
{
// BIND DATA Function
BindData();
DataTable dt = gridview.DataSource as DataTable;
if (dt != null)
{
//Sort the data.
dt.DefaultView.Sort = e.SortExpression + " " + GetSortDirection(e.SortExpression);
Session["sort"] = dt.DefaultView.Sort;
gridview.DataSource = dt;
gridview.DataBind();
}
}
// bind data function//
private void BindData()
{
DataTable dt = GetDataTable();
if (Session["sort"] != null)
{
//Sort the data.
dt.DefaultView.Sort = Session["sort"].ToString();
}
gridview.DataSource = dt;
gridview.DataBind();
}
Make sure that you are not rebinding the grid after a postback.
if(!IsPostBack)
{
gridView.DataSource = yourDataSource;
gridView.DataBind();
}
Are you grabbing the selected row by it's row index or by the unique identifier of the data you are wanting to edit? If you're getting by row index, it may be 'forgetting' since you are recreating the Grid on OnPostBack. Try iterating through the data and select it by it's unique ID, not its row index.
Check Johans blog regarding SPGridView and LinqDataSource
I'd made a number of sortable GridViews, but none with row command interaction before today, when I stumbled on this problem. Mine is a "plain" GridView, not SPgridview. I found this works:
In bindData(), if we have not created a DataTable and put it in the Session object, do so. Otherwise, we'll use the existing, sorted DataTable:
if (Session["dtbl"] == null) {
Session["dtbl"] = method_to_fetch_datatable();
}
gv.DataSource = Session["dtbl"] as DataTable;
gv.DataBind();
In the GridView's handling of row commands that INSERT, UPDATE or DELETE underlying data, refresh the Session object, maintaining the sort, if there is one:
Session["dtbl"] = method_to_fetch_datatable();
if (ViewState["SortExpression"] != null) {
DataTable dt = Session["dtbl"] as DataTable;
dt.DefaultView.Sort = ViewState["SortExpression"] as string;
}
bindData();
I got it working. (kinda)
In the sorting event i saved the sortexpression (the name of the column used to sort by)
and the sortdirection ascending or descending.
Then i make the datasource for the gridview and databind, and after databinding it, i use the gridview.sort command to sort by the values i saved in viewstate.
That works fine, only one problem.
When sorting i made it switch direction after pressing the same column more than one time.
Now it thinks i keep pressing the column title, so it keeps reversing the sorting.
But i tempererarely made it only sort in one direction.
And now im playing with the sender object in the sorting event, im thinking that if i could get some info about whats causing the event i could tell it to only switch direction based on the sender.
Thanks :)

Resources