I'm working on Windows c#.
Firstly, the things those can not be change as my need are following:
The Size of TableLayoutPanel is fixed.
The Total # of columns are fixed.
Now, I want to set a fix height for all rows but as increasing the rows, if I set the RowStyle property to Percent with 100.0F then it works fine for 3 to 4 items, but after 4-5 items, the control on one row overwrites controls on another row.
I have searched for this so more but i'm not able to get the proper answer. I have also tried the AutoSize, Percent, Absolute properties of RowStyle, even though it is not working.
So what to do and how? How can I achieve this?
Ultimately, I want to do same like as DataGridView of Windows C#.
Thanks in advance....
I'm working on WinForms...the sample code is here..
int cnt = tableLayout.RowCount = myDataTable.Rows.Count;
tableLayout.Size = new System.Drawing.Size(555, 200);
for (int i = 1; i <= cnt; i++)
{
Label lblSrNo = new Label();
lblSrNo.Text = i.ToString();
TextBox txt = new TextBox();
txt.Text = "";
txt.Size = new System.Drawing.Size(69, 20);
tableLayout.Controls.Add(lblSrNo, 0, i - 1);
tableLayout.Controls.Add(txt, 1, i - 1);
}
tableLayout.RowStyles.Clear();
foreach (RowStyle rs in tableLayout.RowStyles)
tableLayout.RowStyles.Add(new RowStyle(SizeType.AutoSize));
The label and textboxes are working fine for 4-5 #of rows but whenever the #of row(in this case, variable cnt in for loop) increases, the rows are overwriting each other that is one control overwrite to another...I had drag-drop the TableLayoutPanel control and created just one row and 2 columns manually.
So please tell me how to do it.
I'm still new to tableLayoutPanels myself, but I noticed that at the bottom of your code, you're Clearing all the rowstyles from the collection, then you're trying to iterate through them in your foreach loop.
You did this:
tableLayout.RowStyles.Clear(); //now you have zero rowstyles
foreach (RowStyle rs in tableLayout.RowStyles) //this will never execute
tableLayout.RowStyles.Add(new RowStyle(SizeType.AutoSize));
Try this instead.
TableLayoutRowStyleCollection styles =
tableLayout.RowStyles;
foreach (RowStyle style in styles){
// Set the row height to 20 pixels.
style.SizeType = SizeType.Absolute;
style.Height = 20;
}
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Edit: I just realized that adding N rows doesn't add N rowstyles that you can iterate through. I think what's happening is that you're adding N rows, but none of them have a rowstyles.
I suppose you can Clear() the rowstyles, then just add N rowstyles similar to how you're already doing.
There are 2 ways to increase the row height of table layout panel.
Look into the following link :
https://social.msdn.microsoft.com/Forums/windows/en-US/d80db8e1-d6cc-48b8-957f-0f73263c6d4a/how-to-change-the-row-height-of-a-tablelayoutpanel-at-runtime?forum=winforms
It specifies by setting the YourTableLayoutPanel.RowStyles[index].Height int he code behind class.
The other way is to set the row height in the designer of your UI. Through UI, go into Rows properties of the panel, select the row and set the required height using percent or absolute
Related
I am using Microsoft.Office.Interop.Word in a WinForms application written in c# to create a word document programmatically. I need to create a table with the first two columns having a predefined fixed width and the third (last) column stretched to fill the remaining width of the useable page (if I do not specify any widths, by default, the table would stretch itself to fill the useable width of the page and all 3 columns would be resized equally, which is not what I need).
I can preset the size of the first two columns like this:
myTable.Columns[1].Width = 130;
myTable.Columns[2].Width = 70;
That part is straight forward and works ok. But I couldn't work out how to adjust the third column to stretch-fill the rest of the page width. Here's my last attempt which resulted in the third column extending way beyond the edge of the page:
myTable.Columns[3].Width = wordApp.UsableWidth - myTable.Columns[1].Width - myTable.Columns[2].Width;
I also tried not specifying a value for the width of the 3rd column hoping that it would take up the rest of the width of the table by default - but instead, the 3rd column was adjusted to some seemingly arbitrary value (with the content of cells on this column wrapped to fit) and the overall width of the table shrank to fit all 3 columns which was less than the useable width of the page.
I tried playing with different values for the following table attributes without success:
myTable.AllowAutoFit = true;
myTable.PreferredWidth = wordApp.UsableWidth;
If anyone could help, that would be greatly appreciated. Thank you.
I included the relevant block of code if this helps in anyway:
Microsoft.Office.Interop.Word.Table myTable = wordDoc.Tables.Add(paraTitle.Range, 2, 3, ref missing, ref missing);
myTable.Borders.Enable = 1;
myTable.AllowAutoFit = true;
myTable.PreferredWidth = wordApp.UsableWidth;
//myTable.PreferredWidthType = WdPreferredWidthType.wdPreferredWidthAuto;
myTable.Columns[1].Width = 130;
myTable.Columns[2].Width = 70;
myTable.Columns[3].Width = wordApp.UsableWidth - myTable.Columns[1].Width - myTable.Columns[2].Width;
myTable.Rows[1].Cells[1].Range.Text = "Items returned by:";
myTable.Rows[1].Cells[1].Range.Bold = 1;
myTable.Rows[1].Cells[2].Range.Text = "Name";
myTable.Rows[1].Cells[2].Range.Bold = 1;
myTable.Rows[1].Cells[3].Range.Text = "(person's name and initials...)";
myTable.Rows[1].Cells[3].Range.Bold = 0;
myTable.Rows[2].Cells[2].Range.Text = "Date / Time";
myTable.Rows[2].Cells[2].Range.Bold = 1;
myTable.Rows[2].Cells[3].Range.Text = "(timestamp...)";
myTable.Rows[2].Cells[3].Range.Bold = 0;
UsableWidth refers to the Window width of the Word Application, not the document page width.
Instead use:
doc.PageSetup.PageWidth - (doc.PageSetup.LeftMargin + doc.PageSetup.RightMargin);
I have form with DataGridView on it that displays data. Everything looks fine except when one of the columns content is wider then the column width. So I searched and found a line of code that I added to my Adjust_the DGV_width method so that columns width is adjusted
foreach (DataGridViewColumn col in zGrid1.Columns)
{
col.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
}
It works nicely but it is ugly and I would prefer to keep the columns width as is except when there is content that cant fit in.
How can I programmaticaly find out what is the width of the content that cant fit columns width?
Here is how it looks now, but I prefer when there is more space in columns.
This can be easily achieved by checking the column width after setting it to autosize.
Example:
int myDefaultWidth = 100;
myDataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
foreach ( DataGridViewColumn column in myDataGridView.Columns )
{
if ( column.Width < myDefaultWidth)
{
column.Width = myDefaultWidth;
}
}
So I have a database 'Restaurant', with a table 'dining_tables'.
In my C# application, I am attempting to count the amount of tables in the 'dining_tables' table, then creating a button for each of those tables, and dynamically placing them on the form, side by side, and in rows.
5 buttons per row. (Not sure how to line-break the buttons efficiently after every 5 buttons)
This is how I'm fetching the tables from the database:
(SQL is a class I made for simplying the sql tasks)
SqlDataReader dr = SQL.queryExec("SELECT * FROM tables");
while(dr.Read()){
var tblName = dr["tbl_Name"];
}
^ Now that I am extracting the name for each table, I have done the following.
1) Create a button, style it, and apply the current 'tblName' to the the text property of the button.
2) Add the button to the form.
What I'm stuck on now, is finding out how to align the buttons vertically on the form for every tbl_Name, and then continuing on a new line after every 5 buttons.
Note: I intend to later refine this by adding pages, but for now I want to know how to accomplish the above.
Any positive support will be much appreciated.
Thank you all in advance.
Have you tried using flowLayoutPanel?
it is a control panel that will align and position all controls inside it automatically for yourself it has 4 direction in the property FlowDirection, try using that and I think you will just have to use this configurations
flowLayoutPanel.FlowDirection = FlowDirection.LeftToRight;
flowLayoutPanel.WrapContents = true;
you will just have to calculate how many width 5 buttons have, plus its magin then set it to be the width of your flowLayoutPanel
SqlDataReader dr = SQL.queryExec("SELECT * FROM tables");
int i = 0;
while (dr.Read())
{
Button btn = new Button();
btn.Text = dr["tbl_Name"].ToString();
btn.Width = 100;
btn.Height = 50;
btn.Left = (i % 5) * 110;
btn.Top = (i / 5) * 60;
Controls.Add(btn);
i++;
}
Or Simply
SqlDataReader dr = SQL.queryExec("SELECT * FROM tables");
int i = 0;
while (dr.Read())Controls.Add(new Button() {Text = dr["tbl_Name"].ToString(),
Size = new Size(100, 50), Location = new Point(i % 5 *110, i++ / 5 * 60) });
Sayka's answer is the best one when it comes to using pure code without other controls to generate a formula that can properly align 5 buttons and line-break after them.
However, I personally found the flowlayoutpanel to be the best option for me as the Scroll functionality helps me escape from having to input pages.
I am usign a code a code like this and when the text gets long, it cuts it off and doesn't show the whole text :( In this aspect I want it to behave like a list box item. One line was for one item in the list box and didn't have this trucnacted text issue.
listView1.Scrollable = true;
listView1.View = View.Details;
listView1.HeaderStyle = ColumnHeaderStyle.None;
ColumnHeader header = new ColumnHeader();
header.Text = "MyHeader";
header.Name = "MyColumn1";
listView1.Columns.Add(header);
listView1.Items.Add("TooLongTextDoesntShow");
listView1.Items.Add("short");
listView1.Items.Add("abcd");
I think it is just easier to attach a picture of the issue. Please notice how it is not displaying full text of the highlighted item :(
Thanks for your help.
Just specify a column header width.
ColumnHeader header = new ColumnHeader();
header.Text = "MyHeader";
header.Name = "MyColumn1";
header.Width = listView1.Width //Same Width as Entire List Control
listView1.Columns.Add(header);
Alternative ways to do, is during the add.
You can make use of: ListView.ColumnHeaderCollection.Add
public virtual ColumnHeader Add(
string text,
int width //width of the header
)
Ok, I found a solution, please let me know if there are better ways of doing it too
AFTER adding items to list view is done, we should call this:
listView1.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent);
We take an example of ListView with 2 columns and resize on contents and then to minimum width.
// Auto resize of ListView Columns to minimum width
private int[] ColumnsWidth = { 35, 322 };
/// <summary>
/// Resize the columns based on the items entered
/// </summary>
private void ResizeColumns()
{
// Auto Resize Columns based on content
m_urlsListView.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent);
// Make sure to resize to minimum width
if (m_urlsListView.Columns[0].Width < ColumnsWidth[0])
{
m_urlsListView.Columns[0].Width = ColumnsWidth[0];
}
if (m_urlsListView.Columns[1].Width < ColumnsWidth[1])
{
m_urlsListView.Columns[1].Width = ColumnsWidth[1];
}
}
The content is being truncated because of (practically invisible) column. You can tell the ListView to adjust the column widths automatically:
listView1.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
listView1.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent);
You can just add a column and define its width according to your text size requirement. Moreover "Scrollable" property can be set to true if the actual width of the listview control is smaller
ListView_Column_Width_Image
I am dynamically creating a TableLayoutPanel, and then dynamically creating Labels and TextBoxes to put inside it.
It would seem logical that I could just assign the number of columns and rows to the TableLayoutPanel:
tableLayoutPanelGreatGooglyMoogly = new TableLayoutPanel();
tableLayoutPanelGreatGooglyMoogly.RowCount = NUMBER_OF_ROWS;
tableLayoutPanelGreatGooglyMoogly.ColumnCount = NUMBER_OF_COLUMNS;
...create the controls to place inside it:
Label lbl = new Label();
lbl.Parent = tableLayoutPanelGreatGooglyMoogly;
. . .
...and then put the created control[s] in the specified "cell" (column and row):
tableLayoutPanelGreatGooglyMoogly.SetColumn(lbl, ACol); // "ACol" is the current column
tableLayoutPanelGreatGooglyMoogly.SetRow(lbl, i); // "i" is the current row
...but that's not working - neither if I specify the width and height values for the dynamically created child controls or if I don't (in which case they are too large - specifically, their width is too great).
UPDATE
I added this code, and it makes no difference:
// ROWS
tableLayoutPanelGreatGooglyMoogly.RowCount = NUMBER_OF_ROWS;
TableLayoutRowStyleCollection rowStyles =
this.tableLayoutPanelGreatGooglyMoogly.RowStyles;
foreach (RowStyle rStyle in rowStyles) {
rStyle.SizeType = SizeType.Percent;
rStyle.Height = 8;
}
// COLUMNS
tableLayoutPanelGreatGooglyMoogly.ColumnCount = TOTAL_NUMBER_OF_COLUMNS;
TableLayoutColumnStyleCollection columnStyles =
this.tableLayoutPanelGreatGooglyMoogly.ColumnStyles;
foreach (ColumnStyle cStyle in columnStyles) {
cStyle.SizeType = SizeType.Percent;
cStyle.Width = 12;
}
UPDATE to the UPDATE
I see that at design-time, a Label or TextBox (presumably, any control) has a Cell[col,row] property. I would like to access that dynamically, if it is not readonly, so that I could set:
lbl.Cell = i,i
txtbox.Cell = i+1,i
Is that possible to do in code? The "Cell" property does not seem to be recognized (understandably, I guess) at that time.
UPDATE to the UPDATE REVISITED
I added this line of code:
tableLayoutPanelGreatGooglyMoogly.CellBorderStyle = TableLayoutPanelCellBorderStyle.Single;
...and now I see that the labels and textBoxes actually are in the cells (columns and rows) I'm expecting them to inhabit.
However, I need to get the labels to move down from the upper left corner of their cells to the center of the cell (both vertically and horizontally).
Even at design time (with a "test"/temporary TableLayoutPanel on the form), added Labels do not respond to changes to the TextAlign property when they are sitting inside a TableLayoutPanel cell - no matter what I set TextAlign to ("Middle Center" seems the most sensible), they stubbornly remain affixed to the top left of the cell.
Similary, changing the Labels' Location.X and Location.Y at design time does nothing. The Labels stick to the NW corner of the cell like a barnacle to a long-lost anchor.
An important part of using the GridLayoutPanel that is rarely mentioned is the use of the Anchor property in child controls.
The Anchor property determines which edge of the cell each child control will extend to.
When you create your labels you do it like this:
Label lbl = new Label();
lbl.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
lbl.Parent = tableLayoutPanelGreatGooglyMoogly;
It should stretch the labels to the full size of the cell.
See http://msdn.microsoft.com/en-us/library/w4yc3e8c(v=vs.80).aspx in the "Positioning Controls Within Cells Using Docking and Anchoring" secton.