C# adding empty literal in empty tablecell results in - c#

I'm reading a menu control code. The code uses a tablerow in a table to construct the menu. After each menu item tablecell, it adds the code:
TableCell td = new TableCell();
Literal lt = new Literal();
td.Controls.Add(lt);
tr.Cells.Add(td);
And it results in a space between each menu item, when displaying the menu table. I just wonder why it does that? Does an empty tablecell take space?

I've noticed .NET adds in into empty cells, this has to be down to HTML tables getting a bit ugly looking with an empty cell; it won't get any border and can sometimes (depending on your styling) look rather weird. If you're wanting a gap between table cells use cellspacing or apply a style with margin-right.
On a side note it's recommended you be using var on the left side of your declarations (only when the right side clearly states what it is), ie:
var td = new TableCell();
var lt = new Literal();
td.Controls.Add(lt);
tr.Cells.Add(td);
You would not use it like this:
var x = GetMyVariable();

Related

Add more items to same Row and same column in listview

I know how to add/delete items but I don't know how to add more items to the same field (same row and same column). I want whenever I click a button, an item is added to same selected row but not to new row in the listView.
I uploaded a photo you can check to see what I exactly mean.
Consider looking at ObjectListView or DataGridView instead of what you are currently. It may be more flexible to your needs.
Your question is somewhat unclear. Clearly you are using listView and you have columns and rows resulting in a cell / box / grid location. I gather that, after its initial creation, you wish to append or alter the data at that location.
To get to the point: Multi-line text within a given 'cell' is not supported (as best I can tell). The picture you have shown is likely a custom object or something similar to a listView, but different (such as a ObjectListView). Or perhaps a picture.
listView2.Items[0].SubItems[4].Text = "123\nabc"; //Doesn't add a proper newline like a normal string
listView2.Items[0].SubItems[4].Text = "123\rabc"; //Doesn't add a proper return carriage like a normal string
listView2.Items[0].SubItems[4].Text = "123\r\nabc"; //Doesn't add a proper newline like a normal string
I am assuming you are using the details view
listView1.View = View.Details;
First adding your headers, listView1.Columns.Add(text, width);
listView1.Columns.Add(First Name", 50);
listView1.Columns.Add("Middle Name", 100);
listView1.Columns.Add("Last Name", 100);
You then add data to the listView. However, this is not done directly. You build a listViewITEM then add that item to the list view.
string[] row = new string[3];
row[0] = "john";
row[1] = "someone";
row[2] = "doe";
ListViewItem lvi = new ListViewItem(row);
listView1.Items.Add(item);
listView1.SelectedItems[#].SubItems[#].Text = "string" + "\n" + "string2";
CrazyPaste suggested adding a row, which could be practical and is something you often see with listViews.
However, If you choose to add or "redo" the rows, be sure to remove any old information before inputting new information to avoid duplicates.
Taken from the popup within visual studio 2013 pro
listView1.Items.RemoveAt(int index)
listView1.Items.Insert(int index, string key, string text, int imageIndex)
OR
listView1.Items.Clear(); //Clears all items
then
//Add populate logic here
Two arrays or a multidimensional array in a loop would be effective if you wish to populate the listview in that manner.
To achieve this programmatically, you could...
listView2 = new ListView();
listView2.View = View.Details;
listView2.Location = new Point(50, 50);
listView2.Size = new Size(400, 100);
this.Controls.Add(listView2);
listView2.Columns.Add("AAA");
listView2.Columns.Add("BBB");
listView2.Columns.Add("CCC");
listView2.Columns.Add("DDD");
listView2.Columns.Add("EEE");
ListViewItem item1 = new ListViewItem();
item1.Text = "0"; //The way to properly set the first piece of a data in a row is with .Text
item1.SubItems.Add("1"); //all other row items are then done with .SubItems
item1.SubItems.Add("2");
item1.SubItems.Add("3");
item1.SubItems.Add("");
item1.SubItems.Add("");
ListViewItem item2 = new ListViewItem();
item2.Text = "00";
item2.SubItems.Add("11");
item2.SubItems.Add("22");
item2.SubItems.Add("33");
item2.SubItems.Add("");
item2.SubItems.Add("");
ListViewItem item3 = new ListViewItem();
item3.Text = "000";
item3.SubItems.Add("111");
item3.SubItems.Add("222");
item3.SubItems.Add("333");
item3.SubItems.Add("");
item3.SubItems.Add("");
//item1.SubItems.Clear();
//item1.SubItems.RemoveAt(1);
listView2.Items.Add(item1);
listView2.Items.Add(item2);
listView2.Items.Add(item3);
//listView2.Items.Insert(2, item1); //0 here is the row. Increasing the number, changes which row you are writing data across
listView2.Items[0].SubItems[4].Text = "123\rabc";
To 'update' the information:
listView1.Items.Clear();
listView1.Items.Add(item1);
listView1.Items.Add(item2);
...etc
NOTES:
I was not able to get .Insert to work with subitems.
If you already inserted a listViewItem, You cannot insert an item
without first removing it
SubItems are not automatically created to fill empty space. Commands like 'listView2.Items[0].SubItems[4].Text' will not work with null/non-existent SubItems
I don't have much to go on. But this adds a new row:
string[] row = { "1", "snack", "2.50" };
var listViewItem = new ListViewItem(row);
listView1.Items.Add(listViewItem);
Here's a post discussing how to update an existing listitem:
C#: How do you edit items and subitems in a listview?
Ok. after I searched the internet for ages, it turned out that listView does not support text wrap. so instead I used DataGridView. thank you for your help

Add tbody through code behind (C#)

I use jquery DataTable in my MVC3 project. The table is dynamically generated through code behind. The only thing (so far) that I have troubles with, is the tbody.
I want to add a tbody section with ID, without any rows, from code behind.
I've been looking a lot, and the best thing I got is:
TableRow tb = new TableRow();
tb.TableSection = TableRowSection.TableBody;
tb.ID = "Body";
But that way, I get a row in the tbody section, with one row with the id..
What I want to get is:
<tbody id="Body"></tbody>
How can I get that result from code behind?
Thanks
Such thing is not possible with the generic Table control, it simply doesn't support giving ID to its <tbody>.
What you can do though is assign the desired ID as custom attribute of the table:
Table1.Attributes["data-tbodyid"] = "Body";
Then using jQuery assign this on the fly to the table's <tbody>:
$(document).ready(function () {
$("table").each(function () {
var tbodyId = $(this).data("tbodyid");
if (tbodyId && tbodyId.length > 0)
$(this).find("tbody").eq(0).attr("id", tbodyId);
});
});
I ended up using HtmlGenericControl:
HtmlGenericControl tb = new HtmlGenericControl("tbody");
tb.ID = grid.GridBodyName;
Of course, the table itself, the header, the footer and its cells should also be HtmlGenericControl.
Adding the body to the table, and the cells to the header\footer should be done that way:
HTMLTable.Controls.Add(tb);

make items from checkboxlist links to other pages

I have a checkboxlist.When I check one the value will appear in a table.Now I want that value and each value I check to make it a link.This is my code for getting the checked values:
foreach (ListItem item in check.Items)
{
if (item.Selected)
{
TableRow row = new TableRow();
TableCell celula = new TableCell();
celula.Style.Add("width", "200px");
celula.Style.Add("background-color", "red");
//celula.RowSpan = 2;
celula.Text = item.Value.ToString();
row.Cells.Add(celula);
this.tabel.Rows.Add(row);
Now I want the item.value to make it a link..I'm using c# in asp.net application
Add a Hyperlink control to the celula.Controls collection instead of setting the TableCell's Text property.
// Create a Hyperlink Web server control and add it to the cell.
System.Web.UI.WebControls.HyperLink h = new HyperLink();
h.Text = item.Value;
string url = "~/Default.aspx?Item=" + Server.UrlEncode(item.Value);
h.NavigateUrl = url;
celula.Controls.Add(h);
Note that you need to recreate this table on every postback, so you might want to add this to Page_PreRender instead.

WPF Styling a Cell Dynamically

I have a requirement to generate a "report" in WPF which is simply a grid.
However, the columns and the styling rules (e.g. "Red if value below zero") for this grid are unknown at compile time.
There are hundreds of questions like this and I must have read over half of them but I cannot find a solution to this requirement which would be trivial in WinForms.
I have managed to style an entire row by setting the ItemContainerStyle of the ListView, but I couldn't manage to get this to focus on a single cell.
As such I'm now trying the CellTemplate approach but this throws an error ({"Child with Name '{x:Type ListViewItem}' not found in VisualTree."}) and of course when I use a DisplayMemberBinding the CellTemplate isn't even called at all.
My converter when it gets passed the value is getting the entire row, not just the cell's value, so perhaps this is useful information.
GridView viewLayout = new GridView();
for (int i=0; i<columns.Length; i++)
{
ColumnDisplaySettings col = columns[i];
var g = new GridViewColumn()
{
Width = col.Width,
//DisplayMemberBinding = "[" + i + "]" /* Have to omit this for CellTemplate */
};
if (i == 0)
{
g.CellTemplate = new DataTemplate();
var t = new DataTrigger();
t.Binding = new Binding("[0]");
t.Value = "0";
var b = new Binding() { Converter = new MyBkColorConverter() };
t.Setters.Add(new Setter(Control.BackgroundProperty, b,
"{x:Type ListViewItem}")); /* Error here */
g.CellTemplate.Triggers.Add(t);
}
viewLayout.Columns.Add(g);
}
lv.View = viewLayout;
I've encountered DataTemplateSelectors in my searches, so if a useful reference exists on using these without any known XAML then I'd appreciate that too.
Thanks for any help you can provide.
The error is happening because "{x:Type ListViewItem}" is a string. The {x:..} notation is a XAML markup extension, but you're not using XAML. To refer to the list ListViewItem in code, use typeof(ListViewItem).
Oh also, you're trying to set the Background property to a type, ListViewItem, which makes little sense.. let me re-read and update this answer..
Update: you don't need the third parameter to the Setter constructor.
Hope that helps!
Using the WPF Toolkit's DataGrid is one solution to this. (Comment if more details required).

Adding space BETWEEN cells in TableCell()

My code is below. I want to add space between cells in tableCell()
something the equivalent of
<td></td> <td></td>
I am NOT looking for cellpadding or cellspacing because they both add space between the left cell border and the left table border (wall); I want to add space between two CELLS, not the table and the cell;
protected void Page_Init(object sender, EventArgs e)
{
Table tb = new Table();
tb.ID = "tb1";
for (int i = 0; i < iCounter; i++)
{
TableRow tr = new TableRow();
TextBox tbox = new TextBox();
tbox.ID = i.ToString();
TableCell tc = new TableCell();
tc.Controls.Add(tbox);
tr.Cells.Add(tc);
tb.Rows.Add(tr);
}
pnlScheduler.Controls.Add(tb);
}
Any ideas?
Try this:
TableCell tc = new TableCell();
HtmlGenericControl div = new HtmlGenericControl("div");
div.Style.Add("padding-left", "5px");
div.Style.Add("padding-right", "5px");
div.Controls.Add(tbox);
tc.Controls.Add(div);
tr.Cells.Add(tc);
tb.Rows.Add(tr);
An alternative might be this (I modified your code and added a label, which you can add alternate to every "tc.Controls.Add(tbox);"
protected void Page_Init(object sender, EventArgs e)
{
Table tb = new Table();
tb.ID = "tb1";
for (int i = 0; i < iCounter; i++)
{
TableRow tr = new TableRow();
TextBox tbox = new TextBox();
TextBox tLabel = new Label();
tbox.ID = i.ToString();
tLabel.width = 10;
TableCell tc = new TableCell();
tc.Controls.Add(tbox);
tc.Controls.Add(tLabel);
tc.Controls.Add(tbox);
tc.Controls.Add(tLabel);
tc.Controls.Add(tbox);
tc.Controls.Add(tLabel);
tr.Cells.Add(tc);
tb.Rows.Add(tr);
}
pnlScheduler.Controls.Add(tb);
}
*edit
My apologies for the margin, I don't think it is possible with margins, however I was able to create a css that can be applied to the middle cells give them padding on both the left and right sides.
but to get around the fact that the first and last elements don't push out against the wall of the table you have to apply the class to only the middle td's
example of css code
table
{
border:1px solid black;
border-collapse: collapse;
table-layout: fixed;
}
td.middle
{
border:1px solid black;
padding-left: 20px;
padding-right: 20px;
}
and then your middle td's would be created with the <td class="middle"></td>
however to convert this type of code to c# I'm not entirely sure. I will keep looking on how to apply this class to only specific elements, but your best bet would be to create a flag that checks the element to make sure that they aren't the first or last ones in the table, unless you are adding them manually then you just add the class manually as needed.
However might I suggest that if this is for page layout, your better off having css do the work for you instead of using table design. But if it's to show data in a table format then never mind, I said nothing.
Hope this helps. will post if I find anything else.
you could always add "empty" cells of the desired with.
For giving space between the table cells we have to use table's cellpadding and cellspacing property.
<table cellspacing="1" cellpadding="2">
</table>
<TABLE CELLSPACING="X">
The X in the line, is replaced with the number of pixels you want between the cells.
<TABLE CELLPADDING="X">
The X in the line, is replaced with the number of pixels you want between the text and cell edge.
When you're ready to add two cells with this spacing, create a table instead; with one row and two td's like:
<table cellspacing="2"><tr><td>stuff</td><td>more stuff></td></tr></table>
Apply a left margin to the table's td (except the last one in each row).
You can do it by assigning a common class, or by applying a class that reset the margin only to the last td.
You can use jQuery either and inject margin, but doing it via css only is cleaner.

Categories

Resources