I am trying to create a dynamic menu with a title and group of checkboxes. So the output would be something like this: (pseudocode-ly)
Title 1
-checkbox1 -checkbox2 -checkbox3
Title 2
-checkbox1 -checkbox2 -checkbox3
I can get the Title back just fine, but my checkboxes are not. (See below)
Care
System.Web.UI.WebControls.CheckBoxList
Corporate & Enterprise Solutions
System.Web.UI.WebControls.CheckBoxList
I realize I am returning a DataSet, I just don't know how to handle it.
BusinessUnit bu = new BusinessUnit();
DataSet businessNames = bu.ListBusinessUnitNames();
ArrayList buNames = new ArrayList();
if (businessNames.Tables.Count > 0 && businessNames.Tables[0].Rows.Count > 0)
{
foreach (DataRow row in businessNames.Tables[0].Rows)
{
buNames.Add(row["BSUN_NAME"].ToString());
}
}
int counter = 1;
foreach (string name in buNames)
{
Label lblName = new Label();
lblName.ID = "unitName_" + counter;
lblName.Text = name;
CheckBoxList chkBoxes = new CheckBoxList();
chkBoxes.ID = name + "Programs_" + counter;
foreach (string item in buNames)
{
DataSet buPrograms = bu.ListBusinessUnitPrograms(item);
foreach (DataRow row in buPrograms.Tables[0].Rows)
{
chkBoxes.DataTextField = row[0].ToString();
chkBoxes.Text = chkBoxes.DataTextField;
}
}
programs.InnerHtml += lblName.Text + chkBoxes;
counter++;
}
Here are the mechanics for doing it in code:
ListItem LI1 = new ListItem("aaa");
ListItem LI2 = new ListItem("bbb");
LI1.Selected = true;
LI2.Selected = false;
chkBoxes.Items.Add(LI1);
chkBoxes.Items.Add(LI2);
(Assuming you're using WebForms [aspx])
In your code example, the statement programs.InnerHtml += lblName.Text + chkBoxes; is appending the value of the default .ToString() implementation of the chkBoxes object. To actually add the checkboxes to the page, you will need some sort of container control (such as a Placeholder) on the page, and append your dynamically created control to the container's Controls collection via phPlaceholder.Controls.Add(chkBoxes)
Related
I am working on a Xamarin.Android proyect, I am filling a list view with a Web Service query. Now I need to access the listview's items values which I will use for future queries.
This is how I fill my listView
WebReference.ToDoWS cliente = new ToDoWS();
DataTable tabla = new DataTable();
tabla = cliente.ObtenerTareas();
ListView listado = FindViewById<ListView>(Resource.Id.tareas);
if (tabla.Rows.Count > 0)
{
List<string> tareas = new List<string>();
for (int i = 0; i < tabla.Rows.Count; i++)
{
tareas.Add(tabla.Rows[i][1].ToString());
}
ArrayAdapter<string> adaptador = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleListItem1, tareas);
listado.Adapter = adaptador;
}
Here's a pick of how it looks
Is there a way to access the text values inside each row? I tried with the SetOnClickListener but I don't know how to use it at all.
I was able to access the item index with the following:
listado.ItemClick += (sender, e) =>
{
string index = e.Position.ToString();
Toast.MakeText(this, "Click" + index, ToastLength.Long).Show();
};
Documentation Referece: https://learn.microsoft.com/en-us/xamarin/android/internals/api-design#Events_and_Listeners
I have a webapp that goes and makes some webgets and returns the results in Gridview. Sometimes, the app may need to make 400+ webgets, but only populate the grid with 15-20 records.
Is there a way to partially load a GridView, so that each record is appended to the existing GridView?
Adding Code
List<Test> testList = new List<Test>();
foreach (Location str in list)
{
string url;
try
{
url = "http://www.test.com/" + str.Url;
XmlReader reader = XmlReader.Create(url);
Rss10FeedFormatter formatter = new Rss10FeedFormatter();
if (formatter.CanRead(reader))
{
formatter.ReadFrom(reader);
IEnumerable<SyndicationItem> items = formatter.Feed.Items;
int itemCt = 1;
foreach (SyndicationItem item in items)
{
Test test = new Test();
test.Name = item.Name;
test.City= item.City;
testList.Add(data);
//if I add this here, the RowDatabound does not fire, if I take out, it works fine but only after all requests are made
listGrid.DataSource = temp;
listGrid.DataBind();
}
}
else
throw new ApplicationException("Invalid RSS 1.0 feed at " + FeedUrl.Text.Trim());
}
Create a separate list that you will DataBind the gridview to, and then whenever you change the elements in that list just rebind the gridview.
var mySmallerList = bigList.Skip(someNumber).Take(someOtherNumber);
myGridView.DataSource = mySmallerList;
On my asp.net form, within a table row I add cells and within those cells I add textboxes with an attribute like -
string residentId = (new GUID()).ToString();
string houseId = (new GUID()).ToString();
HtmlTableRow detailRow = new HtmlTableRow();
detailRow.Attributes.Add("residentId", residentId);
detailRow.Attributes.Add("houseId", houseId);
HtmlTableCell dataCell = new HtmlTableCell();
TextBox tb = new TextBox();
tb.Attributes.Add("componentname", "tbMoveInDate");
tb.Attributes.Add("onchange", "updateMoveInDate()";
cell.Controls.Add(tb);
detailRow.Cells.Add(dataCell);
with a possiblility of 100+ rows, all with distinct IDs of course.
within my javascript I have this function -
function updateMoveInDate() {
var MoveInDateEle = $("[componentname*='tbMoveInDate']");
}
at this point MoveInDateEle is a collection of all of those text boxes within the table and
var currentRow = $("[componentname*='tbMoveInDate']").parent().parent();
gives me all of the rows. but not my specific row.
How is it possible to get the specific text box I am working with and the specific resident Id and house Id associated with that control?
Modify the C# code like this:
tb.Attributes.Add("onchange", "updateMoveInDate(this)";
and the js function like:
// obj here refers to the current textbox in the scope
// on which the on-change event had occurred...
function updateMoveInDate(obj) {
var currentRow = $(obj).closest('tr');
}
You could do
tb.Attributes.Add("onchange", "updateMoveInDate(this)";
And
function updateMoveInDate(txt) {
var $txt = $(txt);
var $row = $txt.closest('tr');
var residentId = $row.attr('residentId');
var houseId = $row.attr('houseId');
}
Try this
tb.Attributes.Add("onchange", "updateMoveInDate(this)";
in code behind
string residentId = (new GUID()).ToString();
string houseId = (new GUID()).ToString();
HtmlTableRow detailRow = new HtmlTableRow();
detailRow.Attributes.Add("residentId", residentId);
detailRow.Attributes.Add("houseId", houseId);
HtmlTableCell dataCell = new HtmlTableCell();
TextBox tb = new TextBox();
tb.Attributes.Add("componentname", "tbMoveInDate");
tb.Attributes.Add("onchange", "updateMoveInDate(this)";
cell.Controls.Add(tb);
detailRow.Cells.Add(dataCell);
jQuery:
function updateMoveInDate(args) {
var MoveInDateEle = $(args).closest('tr');
}
I'm trying to get back 2 unique images form an array. Right now I'm refreshing the page until I get 2 unique images. This is not ideal. How can I modify this code to back 2 unique images with out refreshing the page till it hapens.
Can I do it in this layer or do I need to check for unique numbers in the data layer?
Picture dlPicture = new Picture();
DataTable DTPictures = dlPicture.GetRandomPicture();
Picture dlPicture2 = new Picture();
DataTable DTPictures2 = dlPicture2.GetRandomPicture();
// the variables to hold the yes and no Id's for each set
string firstNoPicId = "";
string firstYesPicId = "";
string secondNoPicId = "";
string secondYesPicId = "";
foreach (DataRow row in DTPictures.Rows)
{
firstYesPicId = row["PicID"].ToString();
secondNoPicId = firstYesPicId;
FirstPicMemberNameLabel.Text = row["MemberName"].ToString();
FirstPicLink.ImageUrl = "Pictures/" + row["PicLoc"];
}
foreach (DataRow row in DTPictures2.Rows)
{
secondYesPicId = row["PicID"].ToString();
firstNoPicId = secondYesPicId;
SecondPicMemberNameLabel.Text = row["MemberName"].ToString();
SecondPicLink.ImageUrl = "Pictures/" + row["PicLoc"];
}
if (firstYesPicId != secondYesPicId)
{
FirstPicLink.PostBackUrl = "default.aspx?yesId=" + firstYesPicId + "&noId=" + firstNoPicId;
SecondPicLink.PostBackUrl = "default.aspx?yesId=" + secondYesPicId + "&noId=" + secondNoPicId;
}
else
{
Response.Redirect("Default.aspx");
}
There two pretty obvious ways to deal with this
Add an overload dlPicture.GetRandomPicture(int picID) This will accept an ID so that it won't return an already used picID
restructure your code so that it loops until the secondYesPicId != firstYesPicId
Something like
secondYesPicId = firstYesPicId;
while (firstYesPicId == secondYesPicId)
{ DataTable DTPictures2 = dlPicture2.GetRandomPicture();
foreach (DataRow row in DTPictures2.Rows)
{
secondYesPicId = row["PicID"].ToString();
SecondPicMemberNameLabel.Text = row["MemberName"].ToString();
SecondPicLink.ImageUrl = "Pictures/" + row["PicLoc"];
}
}
Perhaps a better solution would be adding code to your datalayer.GetRandomPicture to make sure it can't return the same picture twice in a row?
in this Picture class add a LastRandomPictureID variable and do a 'WHERE NOT ID = LastRandomPictureID' on your query (you might want to make it a bit more robust to handle the case where only 1 picture exists).
var rnd = new Random();
int randomPicIndex1 = rnd.Next(numOfPictures);
int randomPicIndex2;
do {
randomPicIndex2 = rnd.Next(numOfPictures);
} while (randomPicIndex1 == randomPicIndex2);
Then use these indexes in order to get random rows from your table.
DataRow row1 = DTPictures.Rows[randomPicIndex1];
DataRow row2 = DTPictures.Rows[randomPicIndex2];
I've asked this before, but sadly I'm still having issues and the issue wasn't resolved. Basically, I'm dynamically creating a LinkButton for each row of a table I am generating, and that button has the task of deleting the row with the corresponding ID from the database. To do this, I seemingly need to assign the LinkButton a Command so it'll go into the event when it is clicked. Problem is, when the button's clicked the program never goes into the command - I've put breakpoints in there and it never goes into them. Here's my code:
protected void Page_Init(object sender, EventArgs e)
{
if (Request.QueryString["id"] != null)
{
ColorConverter conv = new ColorConverter();
string connection = ConfigurationManager.ConnectionStrings["TPRTestConnectionString"].ConnectionString;
TPRDBDataContext dc = new TPRDBDataContext();
DataContext db = new DataContext(connection);
Table<SageAccount> SageAccount = db.GetTable<SageAccount>();
Table<InvoiceItem> InvoiceItem = db.GetTable<InvoiceItem>();
Table<Invoice> Invoice = db.GetTable<Invoice>();
Boolean alloweditting = (from s in dc.Invoices where s.id.ToString() == Request.QueryString["id"] select s.alloweditting).Single();
if (alloweditting == false)
{
dtlsInsert.Visible = false;
modalPanel.Visible = false;
}
int sagepk = (from s in dc.Invoices where s.id.ToString() == Request.QueryString["id"] select s.sageaccount).Single();
lblSageID.Text = (from s in dc.SageAccounts where s.ID == sagepk select s.SageID).Single();
lblDate.Text = DateTime.Now.ToShortDateString();
Table table = new Table();
table.Width = Unit.Percentage(100);
table.GridLines = (GridLines)3;
TableHeaderRow header = new TableHeaderRow();
header.BackColor = (System.Drawing.Color)conv.ConvertFromString("#EDEDED");
foreach (string header2 in new string[] { "", "Quantity", "Rate", "Description", "Nominal Code", "Subtotal" })
{
TableCell cell = new TableCell();
cell.Text = header2;
header.Cells.Add(cell);
}
table.Rows.Add(header);
var data = (from s in dc.InvoiceItems where s.invoiceid.ToString() == Request.QueryString["id"].ToString() select s);
foreach (var x in data)
{
TableRow row = new TableRow();
if (x.invoicetext == null)
{
decimal total;
try
{
total = (decimal)x.rate * (decimal)x.quantity;
}
catch
{
total = 0;
}
int i = 0;
foreach (string columnData in new string[] { x.id.ToString(), x.quantity.ToString(), x.rate.ToString(), x.description, x.nominalcode, total.ToString("N2") })
{
TableCell cell = new TableCell();
{
if (i == 0)
{
LinkButton lnkdel = new LinkButton();
lnkdel.Text = "Delete";
lnkdel.ID = "lnkDel" + Guid.NewGuid();
if (alloweditting == false)
{
lnkdel.Enabled = false;
}
lnkdel.Font.Bold = false;
lnkdel.CommandArgument = x.id.ToString();
//lnkdel.Command += lnkdel_Command;
//lnkdel.Command += new CommandEventHandler(this.lnkdel);
cell.Controls.Add(lnkdel);
i++;
}
else
{
cell.Text = columnData;
}
}
row.Cells.Add(cell);
}
runningtotal = runningtotal + total;
}
else
{
int i = 0;
foreach (string columnData in new string[] { x.id.ToString(), x.invoicetext })
{
TableCell cell = new TableCell();
if (i == 0)
{
LinkButton lnkdel = new LinkButton();
lnkdel.Text = "Delete";
lnkdel.ID = "lnkDel" + Guid.NewGuid();
if (alloweditting == false)
{
lnkdel.Enabled = false;
}
lnkdel.Font.Bold = false;
//lnkdel.Command += lnkdel_Command;
//lnkdel.Command += new CommandEventHandler(this.lnkdel);
lnkdel.CommandArgument = x.id.ToString();
cell.Controls.Add(lnkdel);
i++;
}
else
{
cell.Text = columnData;
cell.ColumnSpan = 5;
}
row.Cells.Add(cell);
}
}
switch (x.formatoptions)
{
case 1:
row.ForeColor = (System.Drawing.Color)conv.ConvertFromString("black");
row.Font.Bold = false;
break;
case 2:
row.ForeColor = (System.Drawing.Color)conv.ConvertFromString("black");
row.Font.Bold = true;
break;
case 3:
row.ForeColor = (System.Drawing.Color)conv.ConvertFromString("red");
row.Font.Bold = false;
break;
case 4:
row.ForeColor = (System.Drawing.Color)conv.ConvertFromString("red");
row.Font.Bold = true;
break;
}
table.Rows.Add(row);
}
TableFooterRow row2 = new TableFooterRow();
TableCell cell2 = new TableCell();
cell2.Text = "<span style\"text-align: right; width: 100%;\">Total = <b>" + runningtotal.ToString("N2") + "</b></span>";
cell2.ColumnSpan = 6;
row2.Cells.Add(cell2);
table.Rows.Add(row2);
var update = (from s in dc.Invoices where s.id.ToString() == Request.QueryString["id"] select s).Single();
update.total = runningtotal;
dc.SubmitChanges();
datatable.Controls.Clear();
datatable.Controls.Add(table);
}
else
{
Response.Redirect("Invoices.aspx");
}
}
protected void Page_Load(object sender, EventArgs e)
{
}
protected void lnkdel_Command(object sender, CommandEventArgs e)
{
string connection = ConfigurationManager.ConnectionStrings["TPRTestConnectionString"].ConnectionString;
using (SqlConnection conn = new SqlConnection(connection))
{
SqlCommand comm = new SqlCommand("DELETE FROM InvoiceItem WHERE id = #id", conn);
comm.Parameters.AddWithValue("#id", e.CommandArgument.ToString());
conn.Open();
try
{
comm.ExecuteNonQuery();
}
catch (Exception ex)
{
Response.Write(ex);
}
}
}
Note I've commented out 2 of the crucial lines for posting here, just to point out that I've tried both of the lines that's commented out, and neither work :(
You need to add the controls on every postback. You appear to be only creating them on the initial get (that query string check). On the post back, those controls never get recreated so no event fires.
It's notoriously counter-intuitive, but while ASP.NET bends over backwards to make you think that the instance of your page class is the same between two HTTP requests, the reality is that they are not the same. A new instance is created each time. It looks like you are trying to avoid adding the dynamically generated controls multiple times -- thinking you don't want duplicates. The reality is that you will never get duplicates when adding dynamically generated controls in a life-cycle method such as OnInit() since it's always a new instance of the page class, and thus those dynamically generated controls are gone.
The reason this is usually transparent to developers is that all the controls in the code-front are automatically re-generated for you on both the initial request and every single post-back. For your dynamically created controls, you happen to have this line:
if (Request.QueryString["id"] != null) { ... }
Unless you're doing something special, that "id" attribute will not be in the query string on the postback. This means that none of the code in the if block will be run on the post back (when your event actually fires.) This means that your if-check at the top should be removed altogether. All that code should run for each and every request (GET and POST).
Just saying I've created a workaround - simply creating a simple link to the page, along with a query string containing the id of the row to delete