One-way databind gridview - Update only? - c#

I'm doing some complicated things with a gridview and the only thing standing between me and completion is the fact that I can't set the databinding programmatically. I've made it most of the way around this issue except that I still cannot get the datasource to update.
I've replaced one input field with a dependent dropdownlist and gotten it to retain the value of the field on databind. I can't databind it directly because I get 'Selected Value not in list of items' or something, so I have to find a way to get the grid or the datasource to take the value from this dependent drop down and apply it to the table.
Any help?
<asp:GridView ID="gvManager" runat="server"
AutoGenerateColumns="False" DataSourceID="ldsCampaigns"
ondatabound="gvManager_DataBound"
onrowediting="gvManager_RowEditing" DataKeyNames="ContentID">
<Columns>
<asp:CommandField ShowEditButton="True" />
<asp:BoundField DataField="ContentID" HeaderText="ContentID"
SortExpression="ContentID" />
<asp:BoundField DataField="CampaignName" HeaderText="CampaignName"
SortExpression="CampaignName" />
<asp:BoundField DataField="CampaignTitle" HeaderText="CampaignTitle"
SortExpression="CampaignTitle" />
<asp:BoundField DataField="CampaignTagLine" HeaderText="CampaignTagLine"
SortExpression="CampaignTagLine" />
<asp:TemplateField HeaderText="CampaignData" SortExpression="CampaignData">
<EditItemTemplate>
<asp:DropDownList ID="DropDownList1" runat="server" DataSourceID="ldsTables"
DataTextField="CMSTables" DataValueField="CMSTables"
SelectedValue='<%# Bind("CampaignData") %>' onload="DropDownList1_Load">
</asp:DropDownList>
<asp:LinqDataSource ID="ldsTables" runat="server"
ContextTypeName="DataContext"
onselecting="ldsTables_Selecting" Select="new (CMSTables)"
TableName="CampaignTables">
</asp:LinqDataSource>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Bind("CampaignData") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="DataColumn"
SortExpression="DataColumn">
<EditItemTemplate>
<asp:DropDownList ID="DropDownList2" runat="server" style="margin-bottom: 0px"
SelectedValue='<%# Bind("DataColumn") %>' Visible="False">
</asp:DropDownList>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label2" runat="server"
Text='<%# Bind("DataColumn") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="CampaignLink" HeaderText="CampaignLink"
SortExpression="CampaignLink" />
<asp:BoundField DataField="Sunrise" HeaderText="Sunrise"
SortExpression="Sunrise" />
<asp:BoundField DataField="Sunset" HeaderText="Sunset"
SortExpression="Sunset" />
<asp:BoundField DataField="OwnerID" HeaderText="OwnerID"
SortExpression="OwnerID" />
<asp:CheckBoxField DataField="Enabled" HeaderText="Enabled"
SortExpression="Enabled" />
</Columns>
</asp:GridView>

If i understood you question right, you have a gridview and inside the gridview there is a dropdownlist, on changing the dropdownlist you want to get it's value and fetch some data or whatever you want with it, if that is the case then what you haved is the following:
1-Set your dropdownlist property AutoPostBack = "true".
2-On the dropdownlist_indexchanged event for the dropdownlist do the following:
protected void dropdownlist1_indexchanged(sender object,eventargs e)
{
//Because the dropdownlist is inside the gridview you can't get data directly
//You will have to parse the sender object which will retrieve the dropdownlist
DropdownList ddl = (DropdownList)sender;
//You can then extract the data from the dropdownlist
}

For any future desperate programmer, I had to update the linq data source code on the updated event:
protected void ldsCampaigns_Updated(object sender, LinqDataSourceStatusEventArgs e)
{
using (DashboardDataContext c = new DashboardDataContext())
{
Label Label3 = gvManager.Rows[gvManager.EditIndex].FindControl("Label4") as Label;
List<CMSCampaigns> change = c.CMSCampaigns.Where(s => s.ContentID == Convert.ToInt16(Label3.Text)).ToList();
DropDownList DropDownList2 = gvDashboardManager.Rows[gvDashboardManager.EditIndex].FindControl("DropDownList2") as DropDownList;
change[0].DataColumn = DropDownList2.SelectedValue.ToString();
c.SubmitChanges();
}
}
This is the clusteriest clusterkludge I've ever kludgestergrammed.

Related

Gridview value to a parameter

I have a Home.aspx and Home.aspx.cs
I have a gridview in my Home.aspx >>>
<asp:GridView ID="DataGridView" runat="server" AutoGenerateColumns="False" ShowFooter="True"
CellPadding="4" ForeColor="#333333" GridLines="None" Height="281px" style="margin-top: 0px" Width="100%"
OnRowCancelingEdit="DataGridView_RowCancelingEdit"
OnRowEditing="DataGridView_RowEditing" OnRowUpdating="DataGridView_RowUpdating" HorizontalAlign="Center"
onrowdatabound="DataGridView_RowDataBound">
<AlternatingRowStyle BackColor="Lavender" ForeColor="#284775" />
<Columns>
<asp:TemplateField>
<HeaderTemplate>Data 1</HeaderTemplate>
<ItemStyle HorizontalAlign="Center"></ItemStyle>
<ItemTemplate><asp:Label ID="description" runat="server" Text='<%# Bind("description")%>'></asp:Label></ItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="Editdescription" runat="server">
<asp:ListItem>--Select--</asp:ListItem>
<asp:ListItem>SINGLE</asp:ListItem>
<asp:ListItem>DOUBLE</asp:ListItem>
</asp:DropDownList>
</EditItemTemplate>
<%-- <FooterTemplate>
</FooterTemplate>--%>
</asp:TemplateField>
<asp:TemplateField>
<HeaderTemplate>Data 2</HeaderTemplate>
<ItemStyle HorizontalAlign="Center"></ItemStyle>
<ItemTemplate><asp:Label ID="pkgcode" runat="server" Text='<%# Bind("pkgcode") %>'></asp:Label></ItemTemplate>
<EditItemTemplate><asp:TextBox ID="Editpkgcode" runat="server" Text='<%# Bind("pkgcode") %>'></asp:TextBox></EditItemTemplate>
<%--<FooterTemplate><asp:TextBox ID="pkgcode" runat="server"></asp:TextBox></FooterTemplate>--%>
</asp:TemplateField>
<asp:TemplateField>
<HeaderTemplate>Data 3</HeaderTemplate>
<ItemStyle HorizontalAlign="Center"></ItemStyle>
<ItemTemplate><asp:Label ID="oprcode" runat="server" Text='<%# Bind("oprcode") %>'></asp:Label></ItemTemplate>
<EditItemTemplate><asp:TextBox ID="Editoprcode" runat="server" Text='<%# Bind("oprcode") %>' ></asp:TextBox></EditItemTemplate>
<%--<FooterTemplate><asp:TextBox ID="oprcode" runat="server"></asp:TextBox></FooterTemplate>--%>
</asp:TemplateField>
</Columns>
</asp:GridView>
In my Home.aspx.cs, I have this >>
protected void DataGridView_RowUpdating(object sender, GridViewUpdateEventArgs e)
{ }
This is where I plan to update my data from my gridview, but before updating I want to pass the old data to a parameter so user can compare/see the changes he made. For checking purposes so I can see if it really get the data, I put the following inside DataGridView_RowUpdating (and I don't know if it's wrong)>>
GridViewRow row = DataGridView.Rows[e.RowIndex];
string #editpkgcode = (row.FindControl("pkgcode") as Label).Text;
Literal1.Text = "TEST: " + #editpkgcode;
It gives me the error : NullReferenceException was unhandled by user code
The reason why you get NullReferenceException is because when RowUpdating event fires then the EditItemTemplate exists but not ItemTemplate.
Since you defined pkgcode Label in ItemTemplate, therefore this label control is not existing when RowUpdating event fires. But, because the EditItemTemplate exists when this event fires, so you can access the Editpkgcode textbox defined in EditItemTemplate.
Therefore, you should be using the following code in your RowUpdating event in order access the textbox in EditItemTemplate.
GridViewRow row = DataGridView.Rows[e.RowIndex];
string #editpkgcode = (row.FindControl("Editpkgcode") as TextBox).Text;

GridView Row checkboxes

I have a gridview in my .NET web app:-
<asp:GridView ID="gvwQueues" runat="server" AutoGenerateColumns="false" OnPageIndexChanging="gvwQueues_PageIndexChanging"
PageSize="5" Width="577px">
<Columns>
<asp:BoundField DataField="Text" HeaderText="Text">
<ItemStyle Width="150px"></ItemStyle>
</asp:BoundField>
<asp:BoundField DataField="ItemNumber" HeaderText="Item Number">
<ItemStyle Width="150px"></ItemStyle>
</asp:BoundField>
<asp:BoundField DataField="Directory" HeaderText="Directory">
<ItemStyle Width="150px"></ItemStyle>
</asp:BoundField>
<asp:TemplateField HeaderText="IsActive">
<ItemTemplate>
<asp:CheckBox ID="Yes" runat="server" Text = "Yes" />
<asp:CheckBox ID="No" runat="server" Text = "No"/>
<%-- <asp:CheckBoxList ID="IsActive" runat="server">
<asp:ListItem>Yes.</asp:ListItem>
<asp:ListItem>No.</asp:ListItem>
</asp:CheckBoxList>--%>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Now I want to use the checkboxes:- "yes" or "no" to call appropriate functions on the server side that would make each item on the gridview row "Active" or "inactive".
Active means the item shows up for all users, Inactive means the item doesnt show up for any users, except for the admin.
Two modifications might me needed to make your logic work.
a. Try using Radiobutton in the place of using Check Boxes so that the user will be able to select ONLY ONE OPTION either 'Yes' or 'No'. Also note you need group these radio buttons like below to let only one of these radio buttons selectable. So replace your 'IsActive' template field with below:
<asp:TemplateField HeaderText="IsActive">
<ItemTemplate>
<asp:RadioButton ID="yesRadioButton" runat="server" Text="Yes" GroupName="IsActiveGroup" OnCheckedChanged="RadioButtonIsActive_CheckedChanged" />
<asp:RadioButton ID="noRadioButton" runat="server" Text="No" GroupName="IsActiveGroup" OnCheckedChanged="RadioButtonIsActive_CheckedChanged" />
</ItemTemplate>
</asp:TemplateField>
And assign both of its CheckChanged event to RadioButtonIsActive_CheckedChanged method.
b. Below is the code for the Code behind mehtod RadioButtonIsActive_CheckedChanged
protected void RadioButtonIsActive_CheckedChanged(object sender, EventArgs e)
{
foreach (GridViewRow row in gvwQueues.Rows)
{
RadioButton yesRadioButton = (RadioButton)row.FindControl("yesRadioButton");
if (yesRadioButton.Checked)
{
//Make Items Active
}
else
{
//Make Items Inactive
}
}
}
Let me know in case of any queries.
Do you want the check box to call a function when it changes?
Then all you need to do is add OnCheckedChanged
<asp:CheckBox ID="chkStatus" runat="server" Text = "Yes"
OnCheckedChanged="chkStatus_OnCheckedChanged"/>
Serverside you write the function you want it to do
public void chkStatus_OnCheckedChanged(object sender, EventArgs e)
{
//Make active inactive
}
Out side of this are you asking about roles, or binding to a grid?
you can use DataKeyNames for the grid view.
try this once.
<asp:GridView ID="gvwQueues" runat="server" AutoGenerateColumns="false" OnPageIndexChanging="gvwQueues_PageIndexChanging"
PageSize="5" Width="577px" DataKeyNames="ItemNumber">
<Columns>
<asp:BoundField DataField="Text" HeaderText="Text">
<ItemStyle Width="150px"></ItemStyle>
</asp:BoundField>
<asp:BoundField DataField="ItemNumber" HeaderText="Item Number">
<ItemStyle Width="150px"></ItemStyle>
</asp:BoundField>
<asp:BoundField DataField="Directory" HeaderText="Directory">
<ItemStyle Width="150px"></ItemStyle>
</asp:BoundField>
<asp:TemplateField HeaderText="IsActive">
<ItemTemplate>
<asp:CheckBox ID="chkYes" runat="server" Text="Yes" OnCheckedChanged="YesOrNo_OnCheckedChanged"
AutoPostBack="true" />
<asp:CheckBox ID="chkNo" runat="server" Text="No" OnCheckedChanged="YesOrNo_OnCheckedChanged"
AutoPostBack="true" />
<%-- <asp:CheckBoxList ID="IsActive" runat="server">
<asp:ListItem>Yes.</asp:ListItem>
<asp:ListItem>No.</asp:ListItem>
</asp:CheckBoxList>--%>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
And you can catch the Item Number using ClientID of sender argument
protected void YesOrNo_OnCheckedChanged(object sender, EventArgs e)
{
CheckBox chkSender = (CheckBox)sender;
foreach (GridViewRow gvRow in gvwQueues.Rows)
{
if (gvRow.RowType == DataControlRowType.DataRow)
{
CheckBox chkYes = (CheckBox)gvRow.FindControl("chkYes");
CheckBox chkNo = (CheckBox)gvRow.FindControl("chkNo");
if (chkSender.ClientID == chkYes.ClientID || chkSender.ClientID == chkNo.ClientID)
{
int ItemId = Convert.ToInt32(gvwQueues.DataKeys[gvRow.RowIndex].Value);//here is the item number
if (chkNo.Checked)
{
chkYes.Checked = false;
//code to inactive
}
else if (chkYes.Checked)
{
chkNo.Checked = false;
//code to activate
}
}
}
}
}
One more suggestion is better to use Radiobuttons instead of Checkboxes.
You need to handle many conditions by using Checkboxes in your case.

Update gridview row add the old value and the new

I have a Gridview and inside I have another one nested GridView. When I press a plus button the nested GridView expands using a JavScript. The nested GridView expands on edit mode using TextBox controls. So when the user types on a TextBox would have the ability to update the cell using an update button. My problem is that when I press the update button the update occurs but not how I would expected. If for example the initial value of a cell was “My name is Peter” and I have done the edit “I don’t have a name” The new value that will be saved is exactly this: “My name is Peter, I don’t have a name”. The databind of the nested GridView occurs on the parent GridView DataBound event.
My code:
<asp:GridView ID="GridView1" runat="server" AllowPaging="True" OnPageIndexChanging="gridView_PageIndexChanging"
AutoGenerateColumns="False" DataKeyNames="myitemID"
OnRowDataBound="GridView_RowDataBound">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<img alt = "" style="cursor: pointer" src="../plus.png" />
<asp:GridView ID="nestedGridView" runat="server"
AutoGenerateColumns="False"
DataKeyNames="mynestedID">
<Columns>
<asp:TemplateField HeaderText="nestedID" Visible="false" ItemStyle-Width="20%"
SortExpression="nesteditemID">
<ItemTemplate>
<asp:Label ID="nesteditemID" runat="server" Text='<%# Bind("nesteditemID") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Name" ItemStyle-Width="20%"
SortExpression="Name">
<ItemTemplate>
<asp:TextBox ID="name" TextMode="MultiLine" Width="80%" Rows="3" runat="server" Text='<%# Bind("Name") %>'></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:Panel ID="mypanel" runat="server">
<table>
<tr>
<td>
<asp:ImageButton ID="ImageButton2" OnClick="updatename_Click" ImageUrl="~/images/update.jpg" Width="15px" Height="15px" runat="server"></asp:ImageButton>
</td>
</tr>
</table>
</asp:Panel>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</asp:Panel>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="myitemID" InsertVisible="False"
SortExpression="myitemID" Visible="False">
<ItemTemplate>
<asp:Label ID="myitemID" runat="server" Text='<%# Bind("myitemID") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="ItemName" ItemStyle-Width="20%"
SortExpression="ItemName">
<ItemTemplate>
<asp:Label ID="ItemName" runat="server" Text='<%# Bind("ItemName") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
cs code:
protected void updatename_Click(object sender, EventArgs e)
{
GridViewRow masterrow = (GridViewRow)(sender as Control).Parent.Parent.Parent.Parent.Parent.Parent.Parent.Parent;
GridViewRow row = (GridViewRow)(sender as Control).Parent.Parent.Parent;
int index = row.RowIndex;
int mi = masterrow.RowIndex;
int i = index;
GridView nestedGridView = (GridView)GridView1.Rows[mi].FindControl("nestedGridView");
Label nestedID = (Label)nestedGridView.Rows[index].FindControl("nestedID");
int sbid = Convert.ToInt32(nestedID.Text);
TextBox name = (TextBox)nestedGridView.Rows[index].FindControl("name");
string myname = Convert.ToString(name.Text);
//update name with the new value
Nesteditem updatenesteditem = mylinqobjects.Nesteditems.Single(p => p.nesteditemID == sbid);
if (!string.IsNullOrEmpty(myname))
{
updatenesteditem.nesteditemName = myname;
mylinqobjects.SubmitChanges();
}
}
Replaced the current text by removing the old one.
string myname = name.Text.Substring(name.Text.LastIndexOf(",")+1);
Tried all possiblities, but due nested grid view rendering and its restrictions, we could do only like above.
Any others solutions, please provide.

Checkboxfield value controls button visibility

I have a gridview which displays the contents of a database table in rows. There is a CheckboxField there and a Select button. I want to set button visibility to false when checkboxfield is checked.
this is my aspx page:
<asp:DetailsView ID="DetailsViewERgo" runat="server" Height="50px"
Width="100%" AutoGenerateRows="False" CellPadding="4"
DataSourceID="LinqDataSourceErgo" ForeColor="#333333" GridLines="None"
HeaderText="Σύντομη Περιγραφή Επιλεγμένου Έργου">
<Columns>
<asp:CheckBoxField DataField="Diekperewsi" HeaderText="Answered"
SortExpression="Diekperewsi" Visible="True"
ItemStyle-HorizontalAlign="Center">
<ItemStyle HorizontalAlign="Center" />
</asp:CheckBoxField>
<asp:TemplateField HeaderText="Insert Answer" ShowHeader="False">
<ItemTemplate>
<center>
<asp:Button ID="Button1" runat="server" CausesValidation="False"
CommandName="Select" Text="Επιλογή" Visible="true" >
</asp:Button>
</center>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
I have tried this but only works with checkboxes
protected void GridViewAitima_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
CheckBox cb = (CheckBox)e.Row.FindControl("Diekperewsi");
Button b = (Button)e.Row.FindControl("Button1");
if (!cb.Checked)
{
b.Visible = false;
}
else
{
b.Visible = true;
}
}
}
Your code will run on the server side but it looks as if the the AutoPostBack property for your checkbox is not set to true -
AutoPostBack="True"
so when the checkbox is checked the code will not run immediately, it will only run after another event has caused your page to postback.
CheckBoxField has no id thus you can't find it by id, moreover it has no value propertie.
I suggest you use template field just like you used for the button, but instead put a checkbox in it.
so instead of :
<asp:CheckBoxField DataField="Diekperewsi" HeaderText="Answered"
SortExpression="Diekperewsi" Visible="True"
ItemStyle-HorizontalAlign="Center">
<ItemStyle HorizontalAlign="Center" />
</asp:CheckBoxField>
put :
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox ID="Diekperewsi" Enabled="false" Checked='<%#Eval("Diekperewsi")%>' runat="server" />
</ItemTemplate>
</asp:TemplateField>
and you are good

How do I get the Data from the textboxes within the gridview, nested in the repeater?

I tried posting this before with only text...there was only one response the suggested I update onblur..which didn't seem like the best route as there could be a considerable amount of records: I have the following Gridview built during a repeater ItemDataBound event:
'>
<asp:GridView ID="gvBeneficiary" DataKeyNames="BeneficiaryKey" OnRowCommand="gvBeneficiary_RowCommand" runat="server" AutoGenerateColumns="false">
<Columns>
<asp:TemplateField HeaderText="Name">
<ItemTemplate>
<asp:HyperLink runat = "server" ID="hlEditBeneficiary" NavigateUrl='<%# "~/EditBeneficiary.aspx?bk=" + HttpUtility.UrlEncode(DataBinder.Eval(Container.DataItem, "BeneficiaryKey").ToString()) %>' Text='<%#Eval("FirstName") %>'></asp:HyperLink>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Relationship" HeaderText="Relationship" />
<asp:TemplateField HeaderText="Shares %">
<ItemTemplate>
<asp:TextBox ID="txtEditShares" runat="server" Text='<%#Bind("Shares") %>'></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Beneficiary Type">
<ItemTemplate>
<asp:DropDownList ID="ddlBeneficiaryType" runat="server" SelectedIndex='<%# GetSelectedBeneficiaryType(Eval("BeneficiaryType")) %>' DataSource='<%# BeneficiaryTypes %>' ></asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton Text="Delete" CommandName='DoDelete' CommandArgument='<%# string.Format("{0}|{1}", Eval("BeneficiaryKey"), Eval("PlanTypeKey")) %>' ID="lbDoDelete" runat="server"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:HyperLink ID="hlAddBeneficiary" runat="server" Text="Add Beneficiary" NavigateUrl='<%# "~/AddEditBeneficiary.aspx?PT=" + HttpUtility.UrlEncode(DataBinder.Eval(Container.DataItem, "PlanTypeKey").ToString()) + "&CPT=" + HttpUtility.UrlEncode(DataBinder.Eval(Container.DataItem, "CorePlanType").ToString()) %>'></asp:HyperLink>
This is the codebehind:
protected void rptPlanTypes_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
GridView gvBeneficiary = (GridView) e.Item.FindControl("gvBeneficiary");
gvBeneficiary.DataSource = ((PlanType) e.Item.DataItem).BeneficiaryCollection;
gvBeneficiary.DataBind();
}
I Have one onclick event from a button that I want to do all the updates from. Anyone have any idea how to drill down the the individual controls on the rows to pull the all the data at once or in a loop.
Thanks again for all of your suggestions.
Padawan
You will want to iterate over each row of the GridView and collect the data from each control in which you are interested. For example, the following snippet will grab each txtEditShares value per row.
foreach (GridViewRow row in gvBeneficiary.Rows)
{
var txtEditShares = (TextBox)row.FindControl("txtEditShares");
var shares = txtEditShares.Text;
///...
}
You'll need to put together the guts of the loop, but that's how move through each row of a GridView and grab control values. I hope it helps.

Categories

Resources