I have a listbox where I want to display a list of names and highscores from a character class. I use ListBox.Items.Add to add the following string for each character:
public String stringHighscore()
{
return name + "\t\t\t" + score.ToString();
}
The problem is that when the name exceeds a certain length, the score gets pushed to the right. The listbox looks like this (sorry, my rep doesn't allow me to post images yet):
(Link to the listbox image on tinypic)
I have thought this may be due to the "\t" but I am not sure. How can I solve this and properly align the scores? Would it be better if I used two listboxes, one for names and one for scores?
You can use String.PadRight method.
Returns a new string that left-aligns the characters in this string by
padding them with spaces on the right, for a specified total length.
Let's say you have 20 characters length for name as maximum
public String stringHighscore()
{
return name + name.PadRight(20 - name.Length) + "\t\t\t" + score.ToString();
}
If your name's length is 13, this will add 7 space characters. And that way, your all name's length will equal (20) at the end.
Look at this csharp-examples article :
Align String with Spaces.
For official reference, look Composite Formatting
Good luck!
Seems to me like you would be best off using a ListView rather than trying to manually align anything yourself. Usage is barley harder than working with simple list boxes, and all the configuration can be done in the IDE (I'm assuming you are using VisualStudio, or a similarly powerful IDE).
Say you have a ListView item called scoresListView. From the IDE you can set the View property to Details, which will cause the list to be rendered in columns of a given width with a heading at the top (I figure you would want "Name" and "Score"). The code to add a column looks something like this (I assume you have a using System.Windows.Forms clause at the top of your C# file for the sake of readability):
scoresListView.Columns.Add("Name", 200); // add the Names column of width 200 pixels
scoresListView.Columns.Add("Score", 200, HorizontalAlignment.Right); // add the Score column of width 200 pixels (Right Aligned for the sake of demonstration)
Adding items (a name/score pair) to the list view can be as simple as:
string myName = "abcdef"; // sample data
int myScore = 450;
scoresListView.Items.Add(new ListViewItem(new string[] { myName, myScore.ToString() } )); // add a record to the ListView
Sorry there isn't all that much explanation, hope this helps now or in the future - the ListView is a very useful control.
Related
For starters I'm very very new to writing code! :)
What I have so far...
So far I've used Xamarin.Forms to create a user interface for a sort of specialized calculator. I'm using a Grid Layout containing: a first column of Labels, a second column of Entries (that I have named in Xaml), and a third column of Steppers (so I can change the entries by typing or using the stepper). These 3 views on each row repeat for several rows with different label text on each row and at the bottom of the Grid Layout I have an Entry for the output.
The problem...
Basically, I want to buy a certain product at different weights and prices...among other criteria....and I want to quickly figure out how much money I'll make at a future possible sale price. Simply put... I'm trying to add/subtract/multiply/divide using Xamarin.Forms Entries. I've looked everywhere and can't seem find anyone giving an example of how to do this. I've tried different methods and usually end with an error of not being able to convert the Xamarin.Forms entry to a string...So I'm back to zero. Can I get an example of a Method where I would be able to add/subtract/multiply/divide 2 Xamarin.Forms Entry views together in the C# code behind? This seems very simple to me...what am I missing??? Is there a thread/article/video somewhere that I haven't found that covers this?? And like I said, I'm very new so the answer is probably very simple.
Thanks in advance!
Steven
Entries deal with strings, not numeric values, so you need to convert them before doing calculations.
var amount = Decimal.Parse(EntryA.Text);
var price = Decimal.Parse(EntryB.Text);
var total = amount * price;
// you can use a format string as an argument to ToString()
// to control the output - ie, how many decimals, commas, etc
LabelTotal.Text = total.ToString();
In a real app you will want to validate the input in case the user enters text instead of a value number (the Parse method will throw an exception if the input is bad);
from these two questions in SO | 1 | and | 2 |(this one's my
own) I've tried to solve but I'm running into some problems.
Take a look at where I am stuck!!
I have successfully word-wrapped this string "Damodarmarg, Kusunti, Inside Ringroad, Lalitpur, Bagmati, Nepal" using a code (see my SECOND CODE)
But I DO NOT KNOW how to get the number of lines that have been wrapped. (because it wraps automatically).
This is the screenshot of my PRINT PREVIEW:
I want to put some space between Residential Address and Permanent Address. To do that I need to know how mny lines are being word-wrapped.
Thats my problem. The word-wrap is happening but NOT the line spacing! I just want to know how I can calculate the number of lines that have been word-wrapped so that I can run a function to do appropriate line spacing between two fields!
I want to know the number of lines that have been word-wrapped (which you can observe, in the screenshot above, is clearly = 2 here).
Why do I need this number? ==> If x is the number of lines word wrapped, I want to execute the function newline() x number of times. That's why. Its my own function whose purpose is to correct line spacing among different fields.
Example:
For a string "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
IF the page margin only allows 10 characters per line then
The output should beABCDEFGHIJKLMNOPQRSTUVWXYZ
and the number of lines used, stored by variable linesFilled(say), should be = 3
Obviously,this is just a run-down example. In real-practice, I would like to have no character limit per line. Instead I want MeasureString to automatically know how many words fit in a line and then word-wrap the rest that are not fitting to next consecutive line(s). For your information: I have already done this much . You see, I seek your help only to know how to get the number of lines that have word-wrapped. That has been really tricky to work around.
What I have tried so far:
FIRST CODE:
My code looks like this(for the line counting; which you need to help me with):
int charactersFitted;
int linesFilled;
SizeF stringSize = new SizeF();
stringSize = e.Graphics.MeasureString("Residential Address: " +
RAddressTextBox.Text, stringFont, layoutSize, newStringFormat,
out charactersFitted, out linesFilled);
textBox1.Text = Convert.ToString(stringSize);
textBox2.Text = Convert.ToString(stringSize.Width);
So, this first code is supposed to give me the number of lines that were wrapped around the print margin. Currently just gives the width of the part of string that occupied the whole line as opposed to the number of lines the string has occupied (can I get a method to know the number of lines?)
SECOND CODE:
Graphics RAddress = e.Graphics;
SizeF RAddressLength = RAddress.MeasureString("Residential Address: "+
RAddressTextBox.Text, stringFont,700);
RAddress.DrawString("Residential Address: " + RAddressTextBox.Text,
stringFont, Brushes.Black, new RectangleF(new Point(pagemarginX,newline()),
RAddressLength), StringFormat.GenericTypographic);
and this second code helps we actually wrap the string when it does not fit in page margin(this second code here works perfectly at the moment. It automatically word-wraps text NOT fitting in a line to next consecutive line(s) but it DOES NOT tell me how many lines have been word-wrapped. THATS my problem)
Note: newline() is my own function which leaves one line when called. And pagemarginX sets approapirate margin. Thats all. Do not be confused. As for why I havent used DrawString in my FIRST CODE; I have been using both codes. This one to display the string and the FIRST CODE to count the lines in string. I haven't been able to count the number of lines with this one. Sorry for the confusion.
SAMPLE OUTPUT(s) FOR YOUR INFORMATION: Currently, output of stringSize.Width is 114.226.As suggested in some of the comments, I tried outputting linesFilled instead of stringSize.Width and the output was 5 . Another suggestion was to try int numLines = Convert.ToInt32(Math.Ceiling(layoutSize.Width / stringSize.Width)); which gave me the output 7 . As shown in the screenshot of my PRINT PREVIEW over there^^^, I obviously need the output=2 for my string. Please somebody help me!
I welcome:
Solutions that augment and enhance my FIRST CODE to produce correct lines of word-wrap as output for the string: "Damodarmarg, Kusunti, Inside Ringroad, Lalitpur, Bagmati, Nepal" (which should be 2)
Solutions that can modify my SECOND CODE to also produce the number of lines that have been wordwrapped (This type of solution would be awesome!!)
Creative solution: A solution that takes input as string and wordwraps that string to a margin and also produces the number of lines word-wrapped. (OR, whatever you think that solves this problem also works!)
My specifications are NOT rigid. You can solve this problem any way you are comfortable with!
I have edited my question to include as much detail as possible. If you'd like the whole module, you can simply ask me too. I am hoping for a solution. Thanks!
Not sure if this is what you're looking for but when using a print dialog you can do something like this that will give you the number of characters on the page and how many lines per page the string takes up:
private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
int charactersOnPage = 0;
int linesPerPage = 0;
// Sets the value of charactersOnPage to the number of characters
// of stringToPrint that will fit within the bounds of the page.
e.Graphics.MeasureString(stringToPrint, this.Font,
e.MarginBounds.Size, StringFormat.GenericTypographic,
out charactersOnPage, out linesPerPage);
}
e.MarginBounds.Size is what will do the trick for you I believe. Then you can just takes the "charactersOnPage" value and divide it by "linesPerPage" to get the number of characters that fit on one line:
var charactersPerLine = charactersOnPage / linesPerPage;
Once you have "charactersPerLine" you can accomplish the rest of what you're trying to do.
I think you meant
textBox2.Text = Convert.ToString(linesFilled);
instead of
textBox2.Text = Convert.ToString(stringSize.Width);
Edit: Try this:
int numLines = Convert.ToInt32(Math.Ceiling(layoutSize.Width / stringSize.Width));
This might be a hard question, or a stupidly simple one. Either way, bear with me, as I'm quite new to C#.
I've been building a Form with a ListBox inside, and a few other things, and all has been well. Where things get odd are in the filling of said box with information.
My logic to filling this ListBox thus far has been:
foreach (var value in userList)
{
listBoxForForm.Items.Add("#" + value.internalId + " \t\t-\t" + value.title + "\t\t-\t" + value.typeName);
}
(Don't mind the odd between the " and the \t!)
The problem is that this looks odd if certain values are too long (not "long" as in value.length but "long" as in width).
To better explain it, I took a screenshot (forgive the government-style censoring):
As you can see, the problem is that the text doesn't seem to format correctly when using \t in this context.
Is there a way I can format this text neatly in the intended 3-column style I'm going for here? Without knowing the length of the variables in each value, I mean?
You should try with String.PadLeft():
using System;
class Program {
static void Main()
{
string s = "cat".PadRight(10); string s2 = "poodle".PadRight(10);
Console.Write(s);
Console.WriteLine("feline");
Console.Write(s2);
Console.WriteLine("canine");
}
}
which will output:
cat feline
poodle canine
Rather than using tabs, you should use a String.PadRight(X) where X is the maximum length of the field. You will need to ensure that your X value is longer than the maximum length of the data, or clip the data to the maximum length to ensure that the columns line up.
I think what you are looking for is this.
String.PadRight and String.PadLeft Methods
I am trying to write a kiosk program for my print center at a school for students to select size and media type and then have it generate a price. I am currently doing this with radio buttons which works fine but we are adding many more options and a drop down list box would be more appropriate. Also, my code for calculating the price is out of control. I would like to set this up so that calculating the price should be easy. Setup is something like this:
File1 - Paper Size (9 options) - Media Type (18 options)
File2, File 3, etc.
I was going to store this in a 3D array filename[]papersize[]media[] for processing the price.
The problem is that not all media types are available in all sizes. I see that you can not disable items in the list. If you pick one size, I can selectively populate the other drop down with or without items, but it changes my index numbers. If I could disable items, I could keep the same index and make an easy loop for processing prices. As it is now I would have to manually specify and loop for each paper size since the media types are different indexes.
I hope this makes sense, I am not really a programmer, I am just trying to make something simple to improve our workflow and accuracy at the print center. I can provide a screen shot of the old program and a mockup of my new program if it would help. Can anyone think of a more elegant solution for this?
Thanks!!
EDIT
Yikes.. Ok, this is ending up to be more difficult than I was expecting: Thanks everyone for your input, it is much appreciated. I did not really expect any responses and there were a lot. Thank You. I attempted the table idea mentioned below but I am not exactly sure how to implement it. I will comment on that post for what I tried. Let me provide more detail in the event that someone else has another idea.
For example of what I am trying to do:
Size = 8.5x11 has media = matte, double sided matte, luster, gloss, acetate, resume
Size = 11x17 has media = same minus acetate and resume
and so on, up to a 60" roll with backlit media and all sorts of stuff.
Price for 8.5x11 is 1.50 regardless of paper and then each paper has its own price
Price for 11x17 is 3.00 and each paper has its own price which is more than their 8.5x11 counterparts
8.5x11 matte = .25
11x17 matte = .50
8.5x11 matte total = 1.75
11x17 matte total = 3.50
I am trying to do this in as little steps as possible. Currently I have radio buttons which take up a bunch a screen real-estate and do things like: When 11x17_1.Checked acetate_1.Disable, etc. Also for calculating price I have hundreds of lines of code doing things like:
If(8.5x11_1.Checked)
{
If(matte_1.Checked)
price = 8.5x11matte_1;
if(luster_1.Checked)
price = 8.5x11luster_1;
...etc.
}
Rolls require more data (height) to be processed as we charge by linear inch for these. Currently for each file I just have a height box that they are required to fill out. I could just put a height field next to each file for my new version. Then if they select a roll, the height box bust be filled out, which requires more IF's... which I currently have hundreds of. Any thoughts on a more elegant way to do this?
I just don’t have the programming background to simplify this, but I know this can probably be done in 10 lines of code using an array and drop down lists:
It has been a long time since I used arrays but I was thinking of something like:
Selection[file_1][combobox_size.Index][combobox_media.Index]
I think I would have to manually define each array value since the prices are arbitrary?
[0][0][0] = 1.75
[0][0][1] = 1.75
[0][0][2] = 2.00
And so on.
My winform would have let’s say 12 rows for them to enter a file name and then pick the drop down lists. If filename != null then I will process a price for the file and selections.
So if file 1 was 11x17 gloss my array would be something like:
[0][1][3] which I would have pre-defined with a value of $4.00 for example
If it is a roll then I would just multiply by the required height box.
Is this logic sound or grossly inefficient?
EDIT #3
Ok, almost there I think. Sadly, I was unable to figure out the other solutions offered by the community, but I wrote a "get_index" function that looks like this:
public static int get_index(string index)
{
if (index == "Matte")
return (1);
....
if (index == "Luster")
return (3);
....
else
return (0);
}
in my main program I define prices like this:
for (int x = 0; x < filenum; x++)
{
pricegrid[x, 0, 0] = 1.75; // 8.5x11 Resume
pricegrid[x, 0, 1] = 1.75; // 8.5x11 Matte
pricegrid[x, 0, 2] = 1.75; // 8.5x11 Double Sided Matte
pricegrid[x, 0, 3] = 2.35; // 8.5x11 Luster
.....
}
Then to calculate the price I am doing something like this calling that get_index function:
private void calculate_price()
{
getindex[0] = get_index(media1.SelectedItem.ToString());
....
}
You should populate your ComboBox dynamically as you do.
Instead of using SelectedIndex you can use SelectedValue which does not depend on number of elements.
See for example: Using ValueMember in ComboBox
You shouldn't use one three-dimensional array. You will need 3 tables to that. Store all your types in a database.
3 tables are:
1. paper
2. media
3. papermedia
so. you populate first dropdown with papersizes.
then when item is selected in papersizes you run a query to populate dropdown media (you join through intersection table). this way you will only show media that is only available for this papersize. or you can do the other way around.
Does this answer your question?
There are several ways of doing it.
You could create a class FileWithDetail that'd store
[class File / class paper size / class Mediatype ]
Initialize your list at the start of your app
List<FileWithDetail> LstFileWithDetail = new FileWithDetail(){...}
Then with Linq to Object you would easily be able to query the object and bind it to your comboboxes according to your selected value
var LstPaperSize = from p in FileWithDetail
where p.FileName == SelectedFileName
Select ...
how do I get text to wrap from one acrofield to the next? I have an adobe pdf doc our client gave us. It has acro fields one atop another (all with the same name). They want the text to wrap from one to another when it reaches the end of the line. All the other examples I see out there do not deal with filling in acro fields that wrap. Please help!
// loop through disabilities and display them
foreach (var disability in formNature.Disabilities)
{
fields.SetField("EVALUATION", disability.PrimaryDisabilityName + "; ");
}
in theory this should loop through all the disabilities they had entered on the web form and display them one after another while text-wrapping when it reaches the end of each line. But instead it only displays one item one the field.
This isn't a complete answer unfortunately.
First, when you call SetField() you are erasing the current contents of the field and replacing it with your new value. When done in a loop only the last value will ever be stored then. What you need to do is loop through each value and concatenate them into one big string.
string buf = '';
foreach (var disability in formNature.Disabilities)
{
buf += disability.PrimaryDisabilityName + "; ";
}
buf = buf.Trim();
Second, the PDF standard to the best of my knowledge does not support chaining of fields for overflow which is what you are looking for. The only way that I know of to accomplish what you are trying is to actually measure the strings and compare them to the widths of the fields and truncate them as needed. To do this you will need to find the font used for the given field, create a BaseFont from it and use that to Measure the string. Then compare that with the field's rectangle and use only the characters that "fit" into that field. Repeat as needed.
That all said, I would really really recommend that you just edit the PDF and replace the multiple fields with one large field that supports multiple lines. Your life will be much, much easier.