Reading selected ITEMS from Dynamically Created ListBox in asp.net - asp.net

i have created ListBox's Dynamically in a panel and i want to read the selected item from the Listbox created dynamically . below is the code that i used to create the Dynamic Listbox. can anyone please help me how to get the dynamically created listbox and then read the item selected. 'protected void GotoReport_Click(object sender, ImageClickEventArgs e)
{
foreach (TreeNode tndim in tvCubedef.CheckedNodes)
{
lbFilter.Items.Add(tndim.Text);
}
foreach (ListItem item in lbFilter.Items)
{
item.Selected = true;
}
panFilter.Controls.Clear();
connstr2 = System.Configuration.ConfigurationManager.ConnectionStrings["ConnString"].ConnectionString;
conn2.ConnectionString = connstr2;
conn2.Open();
CubeCollection CubeList = conn2.Cubes;
string cb = ddlCubeList.SelectedItem.Text;
foreach (ListItem li in lbFilter.Items)
{
ListBox listb = new ListBox();
ListItem Memlist = new ListItem();
listb.SelectionMode = System.Web.UI.WebControls.ListSelectionMode.Multiple;
listb.Height = 150;
listb.Width = 250;
string Repl1 = li.Value.Replace("[", "");
string Repl2 = Repl1.Replace("]", "");
string[] DimMember = Repl2.Split('.');
foreach (Member dimem in CubeList[cb].Dimensions[DimMember[0]].Hierarchies[DimMember[1]].Levels[DimMember[2]].GetMembers())
{
Memlist.Text = dimem.Name;
listb.Items.Add(Memlist);
panFilter.Controls.Add(listb);
}
}
} '

You need to add the event-handler dynamically:
listb.SelectedIndexChanged += new EventHandler(listb_SelectedIndexChanged);
Of course you also need to provide this method:
protected void listb_SelectedIndexChanged(Object sender, EventArgs e)
{
ListBox listb = (ListBox) sender;
}
Are you recreating this ListBox on every postback (as you should) in page_load at the latest and with same ID as before?

Related

Create TreeView with events programmatically

I am creating a tree programmatically inside a row in a table.
Works fine, but can not get the assigned event is called:
TreeView arbolCapas = new TreeView();
arbolCapas.ID = "capas";
foreach (String capa in servicio.Capas)
{
TreeNode childNodes = new TreeNode();
childNodes.Text = capa;
childNodes.ShowCheckBox = true;
childNodes.SelectAction = TreeNodeSelectAction.None;
arbolCapas.Nodes.Add(childNodes);
}
arbolCapas.SelectedNodeChanged +=new EventHandler(arbolCapas_TreeNodeCheckChanged);
tbC.Controls.Add(arbolCapas);
tbR.Cells.Add(tbC);
protected void arbolCapas_TreeNodeCheckChanged(Object sender, EventArgs e)
{
TreeView elemento = (TreeView)(((CheckBox)sender).Parent);
foreach (TreeNode node in elemento.CheckedNodes)
{ //if (node.Checked)
}
}
How I can call an event when the checkbox of a child node is checked?
Thanks a lot.
Kindly change
childNodes.SelectAction = TreeNodeSelectAction.None
to
childNodes.SelectAction = TreeNodeSelectAction.Select;
I found the solution by adding the event as follows:
arbolCapas.Attributes.Add("onclick", "OnCheckBoxCheckChanged(event)");
And then, in javascript:
function OnCheckBoxCheckChanged(evt) {
alert("check change");
}
Here the solution:
http://geekswithblogs.net/ranganh/archive/2009/01/21/updated-asp.net-treeview-checkboxes-ndash-check-all-ndash-javascript.aspx

asp.net gridview outside button to save

I have gridview built dynamically at run-time bind to datatable, and button to save gridview data placed outside gridview
1- Create GridView
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
CreateGrid();
}
}
void CreateGrid()
{
int nTransID = Convert.ToInt32(Session["trans_id"]);
//
string strSQL = #"EXEC [dbo].[sp_GetTransaction] " + nTransID;
DataTable dtData = clsGlobal.GetDataTable(strSQL);
//
if (ViewState["dtTransDetail"] == null) ViewState.Add("dtTransDetail", dtData);
else ViewState["dtTransDetail"] = dtData;
//
foreach (DataColumn dc in dtData.Columns)
{
if (dc.ColumnName.Contains("!;"))
{
TemplateField tField = new TemplateField();
tField.ItemTemplate = new AddTemplateToGridView(ListItemType.Item, dc.ColumnName);
//\\ --- template contain textbox
tField.HeaderText = dc.ColumnName;
GridView1.Columns.Add(tField);
}
}
}
This is my template class:
public class AddTemplateToGridView : ITemplate
{
ListItemType _type;
string _colName;
public AddTemplateToGridView(ListItemType type, string colname)
{
_type = type;
_colName = colname;
}
void ITemplate.InstantiateIn(System.Web.UI.Control container)
{
switch (_type)
{
case ListItemType.Item:
TextBox text = new TextBox();
text.ID = "txtAmount";
text.DataBinding += new EventHandler(txt_DataBinding);
container.Controls.Add(text);
break;
}
}
void txt_DataBinding(object sender, EventArgs e)
{
TextBox textBox = (TextBox)sender;
GridViewRow container = (GridViewRow)textBox.NamingContainer;
object dataValue = DataBinder.Eval(container.DataItem, _colName);
if (dataValue != DBNull.Value)
{
textBox.Text = dataValue.ToString();
}
}
}
So i have a gridview with textboxe's all open to edit at once
The problem is, when i click on Save button "which is outside gridview" all textboxe's gone
protected void btnSave_Command(object sender, CommandEventArgs e)
{
for (int nRow = 0; nRow < GridView1.Rows.Count; nRow++)
{
for (int nCol = 0; nCol < GridView1.Columns.Count; nCol++)
{
if (GridView1.Rows[nRow].Cells[nCol].Controls.Count == 0) continue;
//\\ --- Controls.Count always = 0
//\\ --- However each cell contain textbox
//\\ --- textbox disappear after save button clicked
TextBox txt = (TextBox)GridView1.Rows[nRow].Cells[nCol].Controls[0];
}
}
}
It looks like you are not creating the GridView after a postback, and the Save button is causing a postback. You need to dynamically create the GridView on each page load. Also, I have found this documentation on the ASP.NET page lifecycle helpful on numerous occasions.
In the documentation, you will see the slightly unintuitive reason why your code isn't working as you would like - btnSave_Command is not run until after a postback and Page_Load.

Gridview paging Show all Records

i have a gridview that has paging enabled. i also have a dropdown on the pager of the gridview where the user can select how many records per page they would like to retrieve. Once the dropdown is changed then an event is fired (shown below) to rerun the query with the updated results per page request. This works very well. I did however want to have a value "All" on the dropdown aswell and the method i used to impliment this is by disabling paging.
This all works brilliantly except for one issue. When the user selects "All" on the dropdown i would like to still show the pager once the gridview is updated. It doesnt show because i turned off paging but is there a way to show the pager again? See my code below for the event. (As you can see i renable the pager at the end but this has no effect)
thanks
damo
Code behind Event for Dropdown Change
void GridViewMainddl_SelectedIndexChanged(object sender, EventArgs e)
{
//changes page size
if ((((DropDownList)sender).SelectedValue).ToString() == "All")
{
GridViewMain.AllowPaging = false;
}
else
{
GridViewMain.PageSize = int.Parse(((DropDownList)sender).SelectedValue);
}
//binds data source
Result fAuditOverallStatusLatest = new Result(sConn);
GridViewMain.DataSource = Result.getAuditOverallStatusLatest();
GridViewMain.PageIndex = 0;
GridViewMain.DataBind();
GridViewMain.AllowPaging = true;
GridViewMain.BottomPagerRow.Visible = true;
GridViewMain.TopPagerRow.Visible = true;
}
DDL Code behind
protected void GridViewMain_RowCreated(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Pager)
{
DropDownList GridViewMainddl = new DropDownList();
//adds variants of pager size
GridViewMainddl.Items.Add("5");
GridViewMainddl.Items.Add("10");
GridViewMainddl.Items.Add("20");
GridViewMainddl.Items.Add("50");
GridViewMainddl.Items.Add("100");
GridViewMainddl.Items.Add("200");
GridViewMainddl.Items.Add("500");
GridViewMainddl.Items.Add("All");
GridViewMainddl.AutoPostBack = true;
//selects item due to the GridView current page size
ListItem li = GridViewMainddl.Items.FindByText(GridViewMain.PageSize.ToString());
if (li != null)
GridViewMainddl.SelectedIndex = GridViewMainddl.Items.IndexOf(li);
GridViewMainddl.SelectedIndexChanged += new EventHandler(GridViewMainddl_SelectedIndexChanged);
//adds dropdownlist in the additional cell to the pager table
Table pagerTable = e.Row.Cells[0].Controls[0] as Table;
TableCell cell = new TableCell();
cell.Style["padding-left"] = "15px";
cell.Controls.Add(new LiteralControl("Page Size:"));
cell.Controls.Add(GridViewMainddl);
pagerTable.Rows[0].Cells.Add(cell);
//add current Page of total page count
TableCell cellPageNumber = new TableCell();
cellPageNumber.Style["padding-left"] = "15px";
cellPageNumber.Controls.Add(new LiteralControl("Page " + (GridViewMain.PageIndex + 1) + " of " + GridViewMain.PageCount));
pagerTable.Rows[0].Cells.Add(cellPageNumber);
}
}
Put this in your Page_Init:
GridViewMain.PreRender += new EventHandler(GridViewMain_PreRender);
Then elsewhere in your Page class:
void GridViewMain_PreRender(object sender, EventArgs e)
{
var pagerRow = (sender as GridView).BottomPagerRow;
if (pagerRow != null)
{
pagerRow.Visible = true;
}
}
Then for your drop down event:
void GridViewMainddl_SelectedIndexChanged(object sender, EventArgs e)
{
MyServices fServices = new FAServices(sConn);
Result fAuditOverallStatusLatest = new Result(sConn);
var data = Result.getAuditOverallStatusLatest();
//changes page size
if ((((DropDownList)sender).SelectedValue).ToString() == "All")
{
GridViewMain.PageSize = data.Count();
}
else
{
GridViewMain.PageSize = int.Parse(((DropDownList)sender).SelectedValue);
}
//binds data source
GridViewMain.DataSource = data;
GridViewMain.PageIndex = 0;
GridViewMain.DataBind();
GridViewMain.AllowPaging = true;
}
In that PreRender event, you'll have to duplicate that code for the top pager.
Edit: To get All selected, make this change in GridViewMain_RowCreated:
if (li != null)
{
GridViewMainddl.SelectedIndex = GridViewMainddl.Items.IndexOf(li);
}
else
{
GridViewMainddl.SelectedIndex = GridViewMainddl.Items.Count - 1;
}

How to add an extra row (containing a Button and corresponding event handler) to the GridView

This must be something that a lot of people have done. Basically, it's a custom GridView (i.e. inherited control) with the ability to update all rows at once. I've tried putting the "update all" button in various places (footer, pager, outside the grid), but it looks neatest (to me) when the button is in an extra row as the last row of the GridView.
NB: The pager row is not a suitable place for this button because this custom control could be used in a situation where paging is false. Similarly, the normal footer may be required for some other purpose (e.g. totals).
Here's my code for putting the button in the correct place (with apologies for the terse variables etc.):
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
//Add an extra row to the table...
if (_updateAllEnabled)
{
GridViewRow r = base.CreateRow(-1, -1, DataControlRowType.Footer, DataControlRowState.Normal);
Button btn = new Button();
TableCell c = new TableCell();
btn.ID = "UpdateAllButton"; // tried with and without this line
btn.Text = "Update All";
btn.Click += new EventHandler(UpdateAll);
r.Cells.Add(c);
c.Controls.Add(btn);
Table t = this.Controls[0] as Table;
c.ColumnSpan = this.Columns.Count;
t.Rows.Add(r);
}
}
This gives the appearance that I want, but the click event (UpdateAll) does not fire.
I assume that the stuff is being added too late in the life cycle (PreRender), but where else can I do this to ensure that the row is at the end of the GridView? I also thought that there might be trouble identifying the button, so I tried setting the ID. In any case, the ID in the generated HTML looks OK (consistent with "working" buttons in the pager row.
Is there a way for me to achieve this or am I attempting the impossible?
The best place to create your footer-controls is RowCreated since that's early enough in the lifecycle and also ensures that their recreated on every postback:
Footer approach:
protected void Grid_RowCreated(Object sender, GridViewRowEventArgs e) {
if(e.Row.RowType == DataControlRowType.Footer) {
Button btn = new Button();
TableCell c = new TableCell();
btn.ID = "UpdateAllButton";
btn.Text = "Update All";
btn.Click += new EventHandler(UpdateAll);
var firstCell=e.Row.Cells[0];
firstCell.ColumnSpan =e.Row.Cells.Count;
firstCell.Controls.Add(btn);
while(e.Row.Cells.Count > 1)e.Row.Cells.RemoveAt(e.Row.Cells.Count-1);
}
}
Of course you have to set ShowFooter to true:
<asp:GridView ID="GridView1"
ShowFooter="true"
OnRowCreated="Grid_RowCreated"
runat="server"
</asp:GridView>
Pager approach:
In my opinion this is the purpose of the FooterRow. But if you really want to ensure that your Button is in the very last row of a GridView(even below Pager as commented), i would try my next approach.
Here I'm using the pager for your costom control(s) by adding another TableRow to the PagerTable which inherits from Table.
protected void Grid_RowCreated(Object sender, GridViewRowEventArgs e) {
switch(e.Row.RowType){
case DataControlRowType.Pager:
Button btnUpdate = new Button();
btnUpdate.ID = "UpdateButton";
btnUpdate.Text = "Update";
btnUpdate.Click += new EventHandler(UpdateAll);
var tblPager = (Table)e.Row.Cells[ 0 ].Controls[ 0 ];
var row = new TableRow();
var cell = new TableCell();
cell.ColumnSpan = tblPager.Rows[ 0 ].Cells.Count;
cell.Controls.Add(btnUpdate);
row.Cells.Add(cell);
tblPager.Rows.Add(row);
break;
}
}
To ensure that the pager is visible even if only one page is shown(note that the real pager is invisible if PageSize==1):
protected void Grid_PreRender(object sender, EventArgs e){
GridView gv = (GridView)sender;
GridViewRow gvr = (GridViewRow)gv.BottomPagerRow;
if(gvr != null) {
gvr.Visible = true;
var tblPager = (Table)gvr.Cells[ 0 ].Controls[ 0 ];
//hide real pager if unnecessary
tblPager.Rows[ 0 ].Visible = GridView1.PageCount > 1;
}
}
Of course now you have to set AllowPaging=true:
<asp:GridView ID="GridView1"
AllowPaging="true"
PagerSettings-Mode="NumericFirstLast"
OnRowCreated="Grid_RowCreated"
OnPreRender="Grid_PreRender"
OnPageIndexChanging="Grid_PageChanging"
runat="server">
</asp:GridView>
Final approach(working for a custom GridView and all PagerPositions):
public PagerPosition OriginalPagerPosition{
get { return (PagerPosition)ViewState[ "OriginalPagerPosition" ]; }
set { ViewState[ "OriginalPagerPosition" ] = value; }
}
protected void Page_Load(object sender, EventArgs e){
if(!IsPostBack) OriginalPagerPosition = GridView1.PagerSettings.Position;
GridView1.PagerSettings.Position = PagerPosition.TopAndBottom;
GridView1.AllowPaging = true;
// databinding stuff ...
}
Keep the RowCreated the same as above in Pager approach.
Visibility of top/bottom pagers will be controlled in PreRender according to the OriginalPagerPosition property. Both pagers are created even with PagerPosition=TOP, the bottom pager is required for your additional control(s):
protected void Grid_PreRender(object sender, EventArgs e)
{
GridView gv = (GridView)sender;
GridViewRow tpr = (GridViewRow)gv.TopPagerRow;
GridViewRow bpr = (GridViewRow)gv.BottomPagerRow;
tpr.Visible = gv.PageCount > 1 && (OriginalPagerPosition == PagerPosition.Top || OriginalPagerPosition == PagerPosition.TopAndBottom);
bpr.Visible = true;
var tblBottomPager = (Table)bpr.Cells[ 0 ].Controls[ 0 ];
tblBottomPager.Rows[ 0 ].Visible = gv.PageCount > 1 && (OriginalPagerPosition == PagerPosition.Bottom || OriginalPagerPosition == PagerPosition.TopAndBottom);
var tblTopPager = (Table)tpr.Cells[ 0 ].Controls[ 0 ];
tblTopPager.Rows[1].Visible = false;
}
Note: if you are extending the GridView control, you have to replace all occurences of GridView1(my test-grid) with this.
It would be easy to add an extra row into the grid. But the difficulty in your requirement is that the GridView's RowCollection should not contain this row since that would be error-prone. It should also be the very last row even if paging is enabled. This is (afaik) not possible.
Hence i've chosen to extend the pager with this functionality.
I'll add this as separate answer since my other is already too detailed and describes two different ways(footer,pager) to add controls to a GridView without extending it.
This approach extends a GridView as in your own requirement and is similar to my other pager-approach. But it's cleaner and only adds the additional row to the BottomPager. It woks also for every setting(AllowPaging=false,Pager-Position: Top,Bottom,BottomTop):
[DefaultProperty("EnableUpdateAll")]
[ToolboxData("<{0}:UpdateGridView runat=server></{0}:UpdateGridView>")]
public class UpdateGridView : GridView
{
[Bindable(true)]
[Category("Appearance")]
[DefaultValue("true")]
[Localizable(true)]
public bool EnableUpdateAll
{
get
{
Object val = ViewState["EnableUpdateAll"];
return ((val == null) ? true : (bool)val);
}
set
{
ViewState["EnableUpdateAll"] = value;
}
}
private bool OriginalAllowPaging
{
get
{
Object val = ViewState["OriginalAllowPaging"];
return (bool)val;
}
set
{
ViewState["OriginalAllowPaging"] = value;
}
}
private PagerPosition OriginalPagerPosition
{
get
{
Object val = ViewState["OriginalPagerPosition"];
return (PagerPosition)val;
}
set
{
ViewState["OriginalPagerPosition"] = value;
}
}
protected override void OnInit(System.EventArgs e)
{
if (ViewState["OriginalPagerPosition"] == null)
OriginalPagerPosition = base.PagerSettings.Position;
if(OriginalPagerPosition != PagerPosition.Bottom)
PagerSettings.Position=PagerPosition.TopAndBottom;
if (ViewState["OriginalAllowPaging"] == null)
OriginalAllowPaging = base.AllowPaging;
base.AllowPaging = true;
}
protected override void OnRowCreated(GridViewRowEventArgs e)
{
switch (e.Row.RowType)
{
case DataControlRowType.Pager:
//check if we are in BottomPager
if (this.Rows.Count != 0 && this.EnableUpdateAll)
{
Button btnUpdate = new Button();
btnUpdate.ID = "BtnUpdate";
btnUpdate.Text = "Update";
btnUpdate.Click += new EventHandler(UpdateAll);
var tblPager = (Table)e.Row.Cells[0].Controls[0];
var row = new TableRow();
var cell = new TableCell();
cell.ColumnSpan = tblPager.Rows[0].Cells.Count;
cell.Controls.Add(btnUpdate);
row.Cells.Add(cell);
tblPager.Rows.Add(row);
}
break;
}
}
protected override void OnPreRender(EventArgs e)
{
bool bottomPagerVisible =
OriginalAllowPaging &&
PageCount > 1 &&
(OriginalPagerPosition == PagerPosition.Bottom || OriginalPagerPosition == PagerPosition.TopAndBottom);
BottomPagerRow.Visible = bottomPagerVisible || EnableUpdateAll;
var tblBottomPager = (Table)BottomPagerRow.Cells[0].Controls[0];
tblBottomPager.Rows[0].Visible = bottomPagerVisible;
}
private void UpdateAll(Object sender, EventArgs e)
{
// do something...
}
}

ASP.net dynamic checkbox

I generate my check boxes dynamically:
for (int i = 0; i < dtCommon.Count; i++)
{
CheckBox newBox = new CheckBox();
newBox.Text = dtCommon[i].userName;
newBox.CssClass = "cbox";
if (dtCommon[i].isAlreadyRequired > 0 )
{
newBox.CssClass = "cbox highlighted";
newBox.Checked = true;
}
ApprovalSelectPanel.Controls.Add(newBox);
}
And when the save button is pressed I call this function:
protected void SaveUsers(object sender, EventArgs e)
{
}
How do I know which check boxes the user has checked?!
You could loop through the ApprovalSelectPanel.Controls and cast them back to the corresponding CheckBox type and verify the Checked property.
I think it is better to use CheckBoxList Within the ApprovalSelectPanel instead of add it in the runtime and in the runtime do the following
CheckBoxList1.DataSource = dtCommon;
CheckBoxList1.DataMember = "userName";
CheckBoxList1.DataBind();
To know which one is selected do the following
foreach(ListItem item in CheckBoxList1.Items)
if (item.Selected)
{
//Do any action
}

Resources