How to add labels onto a form one under another? - c#

I made this program and it worked until it didn't... I was adding labels with text onto a form and setting label.Location = new Point(0, yPos); and then doing yPos += labelHeight;
It didn't make sense to me why at first my labels were fine and then I saw huge gaps between then, turns out yPos overflowed, so I can't use this method, is there some sort of container I can use to add labels one after another without setting label location? Also my labels can be of any height and there can be a lot of them.
I was adding these labels as controls of TabPage.

You're ignoring the main problem which is that you are somehow overflowing the yPos value. So either your logic for setting the y position is flawed or you are displaying WAY too much data in one form. My large 32-inch monitor runs at a resolution of 2,500 X 1,600. The maximum value for int (and thus the maximum y value) is 2,147,483,647. Even a scrollable form that's over 1.3 Million "pages" of data at that resolution. If I could process one "screen" of data per second it would take me 373 hours (15.5 days) to consume all of the labels in that form.
So the problem is not which control to use - it how to reduce the amount of data in one form to a manageable amount. You need to look at filtering, searching, sorting, paging, etc. to get the amount of data to a manageable level. Otherwise it's write-only memory. You are displaying it but noe one is reasonably able to use it.

(Looking past the fact that you may be trying to add too many labels to begin with)
You might want to use TableLayoutPanel for adding multiple controls.
https://blogs.msdn.microsoft.com/jpricket/2006/04/05/winforms-autolayout-basics-tablelayoutpanel/
I believe this is a method you can run on something like that
Table.Controls.Add(new Label() { Text = "textHere", Anchor = ... etc};
That way you don't have to explicitly position everything within the panel, only the panel itself.
There are probably a few ways of doing what you're asking. A little bit of research on my part found that this method is generally the right way to go.
Unfortunately I am unable to test this at the moment, but it may put you on the right track.

Turns out when you add things to a form, that has AutoScroll set to true, you should always do:
this.AutoScrollPosition = new Point(0,0);
This worked, thanks to Hans Passant.

Related

How can I stop the automatic resizing of an Element in a Horizontal Layout Group in Unity?

here is my problem:
I want to have a bunch of Text-GameObjects to be evenly distributed across the screen horizontally.
So I took a Layout-Group and added it onto a Panel, which is streched across the screen, with the following settings:
Panel Settings
(The Layout Element on the Panel is not important here, I think, but the Panel itself is controlled by another Object to stretch across the Screen)
Now, I add the Text-GameObjects via Script. That looks like that:
days[i].transform.SetParent(GameObject.Find("Day Panel").transform);
days[i].AddComponent<Text>();
days[i].transform.GetComponent<Text>().font = (Font)Resources.GetBuiltinResource(typeof(Font), "Arial.ttf");
days[i].transform.GetComponent<Text>().fontSize = 25;
days[i].transform.GetComponent<Text>().color = Color.black;
days[i].transform.GetComponent<Text>().alignment = TextAnchor.UpperCenter;
days[i].transform.GetComponent<Text>().text = shownDates[i].Day.ToString();
days[i].transform.localScale = new Vector3(1, 1, 1);
days[i].transform.localPosition = new Vector3(0, 0, 0);
Now I have the problem, that the width of the text-GameObjects is influenced by the length of the string I show with them. So if a text-GameObject has a 3-char-long string in it, it is wider than a text-GameObject next to it with a one-char-long string. But I need to distribute the width "fairly" between the Text-Objects, independently from what's inside.
I hope, that you can help me, Thanks :D
Making my comment an answer as it answers your question. You have two options to solve your issue.
The first I provided is not as robust and not modular that will work if you know the number of child objects at compile time. You can utilize the field minWidth of a LayoutElement. By setting this value as the width each element needs to be to evenly fill the space, the text object will be no smaller than the value you give it. However, if you ever add any new objects to your layout group at runtime or at any other time, you would need to recalculate these values so it is not a great solution.
The second solution which would allow for almost no work by you is to add an empty parent RectTransform to fill the space above the text object. With the layout group forcing the width and height to expand to the container, each RectTransform will fill the space evenly, while the childed text can be whatever size it needs to be. Here is the hierarchy setup of this solution:
And here is the solution working:
In the example, the parent objects are panels with Image components. I only did this to show that there is a divide between each object like you want. You can remove this component and still have the object retain its structure.

Dynamical rectangle plot c# wpf

I want to create a plot that dynamically displays active elements as rectangles. I have achieved a first version that is actually ok using OxyPlot.Annotations.RectangleAnnotation which I add to myPlotModel.Annotations, you can see it in the image hereafter:
Example of wanted display
The thing is that after a while, the amount of drawn rectangles make the update not smooth as I update the shown timewindow (which is set to 15 seconds). I have already set a maximum of drawn elements that suffice to cover the displayed window (i.e. the rectangles get removed as they are too far in the past), but the rendering is still jerky. I draw the rectangles by allocating them to an equal fraction of the Y-axis, that is the third one from the top gets:
rowNumber= 3.0
minimumY = maximalY - maximalY / totalElements * rowNumber
maximumY = maximalY - maximalY / totalElements * (rowNumber + 1.0)
And the Y-axis is hidden.
My question:
Is there a smarter way of creating such a display that would be less computationally heavy, and therefore allow a smoother update? I do not have to stick to OxyPlot, it is simply the easiest way that I found to obtain what I wanted.
Thanks for your answers!
Technically, the answer to your question is "Yes".
There are a number of ways to do this.
You could have a vertical itemscontrol that had an itemscontrol in it's template. That could have a canvas as it's itemspresenter and you could bind canvas.top and canvas.left to properties in it's content. Template each into a rectangle and bind height and width.
And of course do something about the scale on the bottom and the column of activity labels or whatever you want to call them there.
Unless you're using an absolutely ancient machine, that'd just fly.
It's quite a lot of work but it would probably be quicker to write that than to search through a load of alternative packages and decide which was optimal.

How to control the space between two labels during run time

Im using Visual Studio 2015 Community C#.
I have two labels on a Windows form suppose Label1 and Label2.
These labels will get filled up with user input namely first name and last name.
How to put even space between them so that during runtime the first name doesn't over lap the last name.
AbrahLincoln Abraham Lincoln
(Label1^)(^Label2) (^Label1) (^Label2)
For example: how to make this ^ INTO that >>>>>>>>>>>>^^
Because if I put space in the Form Design before runtime then for other names It will come like this: John(unnecessary space)Doe
Hope you have understood my problem.
Thanks for your time. :D
Controls are located in a form based on coordinates. Luckily for you these controls have properties that tell you the coordinate for the top, left, right, bottom of a control. So you could dynamically move the right label after setting the text.
Label2.Point = new Point(Label1.Right + 5, Y-coord);
An easier way would be to play about with the labels properties in the designer.
You could also try to anchor label1 to the right and label2 to the left. That way you should have a clean middle line, and as the text grows larger it pushes outwards on does not overlap inwards over each other.
However you need an object to anchor to and luckily the SplitContainer works excellent for this.
Also consider setting the autosize property to off and maxing the widths of the labels. Large enough for the string you expect.
Have you considered making it one label?
As in
theOnlyLabel.Text = $"{dataObject.FirstName} {dataObject.LastName}";
or, if you're using textboxes, something like
theOnlyLabel.Text = $"{txtFirstName.Text} {txtLastName.Text}";
Otherwise, I'm afraid, you'd have to realign these two labels every time your first or last name changes.

What is the best way to approach the creation of a calendar in winforms?

I need to develop several calendar type controls in winforms. These calendars are all vertical in nature. The concept is that the calendar will have a column for each day (in a month view), hour (in a day view) or week (in a yearly view). I've attached a sample (rather crude) image of the month view.
So far I've had a good crack at this using a table layout panel, with many panels and labels. This works, however it's messy and is very slow to load. It also comes with a raft of problems that I've tried to overcome. I've attached a screenshot of how it looks at the moment.
I've come up against problems in rendering (the well known stuttering problem), which I've gotten over by hiding the grid while its being built, and then showing it when its done. Also, I've had problems with getting the table to resize correctly (the number of columns changes depending on the number of days in the month), as you can see in the screenshot the bottom row takes up all space. As you can imagine, this is all very nasty and seems to me to be rather hacky.
I've tried WPF a bit to see if I can overcome the problems, but it seems that though it may render a bit better, the issues with columns and row sizing are the same. Is there some other approach I could take to avoid these issues, or is it best to bite the bullet and just switch to WPF? I find it double frustrating because it would be quite an easy job to get this done in HTML using a table.
To reiterate the issues that I'm having are:
Columns are not automatically resizing as I would expect (the last column just fills the space making for some odd UI)
Rows are similar, with the bottom row taking up all the empty space.
Slow rendering
When re-sizing the control have to hide the grid otherwise get lots of stuttering
The hacky nature of the table layout panel
I appreciate any feedback users have on how I should best approach the problem.
I don't have a lot of experience with Table Layout Panel, but after taking a quick look at it there seems to be the options of Fixed Size for a fixed number of columns/rows (which you would change in code) and a Percent size setting for each column. For example, when loading a month with 31 days, you would create 31 columns with a percent width of about 3.2258. You could probably do something like this:
int numColumns = 31;
tableLayoutPanel1.ColumnCount = numColumns;
tableLayoutPanel1.ColumnStyles.Clear();
for (int i = 0; i < numColumns; i++)
{
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100f / numColumns));
}
This would mean as you resize the window the each day stays the same size and they all expand to fit the width of the control. If that size is too small for you, and you need the columns to be a minimum width, you can put the TableLayoutPanel inside a control which has AutoScroll enabled, and set the minimum size of the TableLayoutPanel like so:
int minColumnWidth = 20;
tableLayoutPanel1.MinimumSize = new Size(numColumns * minColumnWidth, 0);
WPF could do this better but if you aren't experienced with it, it will probably take much longer to do.
In Windows Forms, you could always draw the Calendar manually using the Graphics class and OnPaint overriding in a custom control. This would avoid the flickering and slow issues that child controls pose, and should be easier to learn than WPF.
It's been almost a year, but since i came across your question i would like to share a nice Outlook style Winforms Calendar Agenda that i found on CodeProject.

maintain button's position in c#, no matter the resolution of the screen

i designed a game in c# and finished it... but i tried it on my friend's laptop with different screen size and resolution, all my design was in a total mess!!
if there is a way to keep everything (panels, picturebox,buttons,labels,...) in their positions despite the size and resolution of screen!?!?
really need help, my project's deadline is on Monday :(
Use anchors on your controls:
I assume this is a windows form application? If so, you can use docking to maintain positions. Also, the positions should stay the same anyway unless the form is not a fixed size.
So use docking or a fixed sized form.
Also, please make sure to specify what type of GUI framework you're using next time. My answer is incredibly wrong if you're using something other than windows forms.
Aside from docking, another option would be to place all of your objects within a panel, and then center it horizontally and vertically on your resize event. e.g.
panel1.Left = this.Width/2 + panel1.Width/2;
panel1.Top = this.Height/2 + panel1.Height/2;
This will ensure that your applications static contents are always centered, regardless of resolution.

Categories