Winform Column list - c#

I'm very new to programming so apologies if this is a very obvious question. Ive searched online but not found an answer that quite fits yet.
I am writing a programme that interprets bytes from an index within a filestream. Once they have been converted into human readable dates/strings/ints etc I wanted to use a Winform to display the results in columns. Currently I using a listbox and just dispalying each entry seperated by columns but this feels lile a very clunky way of doing it.
Can someone please suggest how I might go about placing the results into a display that uses columns?

It's better to use a ListView than a ListBox in your case. Here's an example showing all words in a string in separate columns in a ListView:
Make sure following property is set to your ListView (here the Name is ColumnsListView):
ColumnsListView.View = View.Details;
This method takes a string, splits it by space and adds a column for each of the values:
private void SetListView(string input)
{
var values = input.Split(' ');
ColumnsListView.Columns.Add("Column1");
var item = new ListViewItem(values[0]);
for (var i = 1; i < values.Length; i++)
{
ColumnsListView.Columns.Add("Column" + (i+1));
item.SubItems.Add(new ListViewItem.ListViewSubItem { Text = values[i] });
}
ColumnsListView.Items.Add(item);
}
This can be done differently when using LinQ's Skip() method to add the item with subitems:
private void SetListView(string input)
{
var values = input.Split(' ');
for (var i = 0; i < values.Length; i++)
ColumnsListView.Columns.Add("Column" + (i + 1));
var item = new ListViewItem(values[0]);
item.SubItems.AddRange(values.Skip(1).ToArray());
ColumnsListView.Items.Add(item);
}
Update:
Here's an example in case you want to use a DataGridView:
private void SetDataGridView(string input)
{
var values = input.Split(' ');
for (var i = 0; i < values.Length; i++)
ColumnsDataGridView.Columns.Add("Column" + (i + 1), "Column" + (i + 1));
ColumnsDataGridView.Rows.Add(values);
}

Related

How to access an indexed string from a string collection saved in settings?

I have a few arrays of strings in my settings labelled meas1, meas2, meas3 etc...
If I want to set the 6th item in each string collection to "", how would I do that? Below is my broken code of failed attempt:
for (int i = 19; i >= 0; i--)
{
Properties.Settings.Default["meas" + i][5] = "";
}
I know I could do Properties.Settings.Default.meas1[5] = ""; but I want I have a lot of meas that I need to do so a for loop would be preferred.
Maybe passing the item name and casting result to StringCollection would help:
for (int i = 19; i >= 0; i--)
{
var prop = Properties.Settings.Default["meas" + i] as StringCollection;
prop[5] = "";
}
Properties.Settings.Default.Save();
You need to replace as string[] with your exact data type. But the above solves your issue of accessing the item by name.

Index was outside the bounds of the array in a for loop C#

So I've been woking a Console game for a while now and I desided to use .txt files to hold the maps. This code opens and stores the txt file contents:
static void LoadMap(string fname)
{
string _org = File.ReadAllText("Maps/" + fname + ".txt");
_org.Split(',');
string[] _tmp = new string[_org.Length];
for (int i=0;i<_org.Length;i++)
{
_tmp[i] = _org[i].ToString();
}
//This line has the error
for (int i=0;_tmp[i]!="$";i+=2)
{
mapwidth += 1;
}
for (int i=0;i<_tmp.Length;i++)
{
leveldata.Add(_tmp[i]);
}
}
I get this error: Index was outside the bounds of the array. I can't figgure out why. Can anyone help? Thanks
Check that variable i does not take values beyond the Length - 1 of the array.
static void LoadMap(string fname)
{
string _org = File.ReadAllText("Maps/" + fname + ".txt");
_org.Split(',');
string[] _tmp = new string[_org.Length];
for (int i = 0;i < _org.Length; i++)
{
_tmp[i] = _org[i].ToString();
}
for (int i = 0;i < _tmp.Length && _tmp[i] != "$"; i += 2)
{
mapwidth += 1;
}
for (int i = 0;i < _tmp.Length; i++)
{
leveldata.Add(_tmp[i]);
}
}
I am not super sure what you are getting at here but I feel a foreach may be a step in the right direction.
First, here are a few things I noticed in the code you presented.
string _org = File.ReadAllText("Maps/" + fname + ".txt");
_org.Split(',');
Here you have ingested your text file and split _org with a comma delimiter. Though you never actually assigned the split array to a variable. _org is still a string, not a string[].
string[] _tmp = new string[_org.Length];
for (int i = 0; i < _org.Length; i++)
{
_tmp[i] = _org[i].ToString();
}
In this block we have set _tmp as a string array using the length of _org. The Length property in this case will retrieve the number of characters in the string _org. assuming _org is set to "foo" the size of the _tmparray is now 3. (0,1,2)
You then go on to load _tmp with the nth character of _org converted to a string.
At this point we have the following in our variables.
_org = "foo"
_tmp = {"f","o","o"}
This next part caught me a bit off guard as I cant tell for certain what you are trying to accomplish.
for (int i = 0; _tmp[i] != "$"; i += 2)
{
mapwidth += 1;
}
You are in a for loop until _tmp[i] equals "$", and you are adding 2 to i every time you move through the loop using i += 2. This logic will break the loop until it hits a "$", or if i grows outside of the bounds of the array it will throw an exception.
You then go on to add one to the mapwidth for every two increments of i
In this final block you are adding the contents of the _tmp array to leveldata
for (int i = 0; i < _tmp.Length; i++)
{
leveldata.Add(_tmp[i]);
}
Now for the good stuff, foreach.
I have made the assumption you wanted to set _org as an array, and that you wanted everything that was not a "$". That in mind, this should accomplish what you were going for, though I am not sure the purpose of incrementing by 2 in the second for loop so I have left that out for now.
static void LoadMap(string fname)
{
string[] _org = File.ReadAllText("Maps/" + fname + ".txt").Split(',');
foreach (var _tmp in _org)
{
if (_tmp != "$")
{
mapwidth += 1;
}
leveldata.Add(_tmp);
}
}
If you want to continue coding it is always a good idea to get a good grasp on the basics.
Though a bit dated here is a good tutorial by Microsoft for programming basics in C#:
C# Programmer's Reference
Try this link.
https://www.programiz.com/csharp-programming/foreach-loop
Have suggestion keyword to avoid Index was outside the bounds of the array error.
Sample code.
for(int i = 0; i < myArray.Length; i++)
{
// Coding to Array for loop.
}

Index out of bound

I am programming in C# i need to put some things in a string 'xml'
I have the following code
TextBox[] myTextBoxes = new TextBox[] { this.textBox2, this.textBox3, this.textBox4, this.textBox5, this.textBox6, this.textBox7, this.textBox8, this.textBox9, this.textBox10, this.textBox11 };
TextBox[] ValueBoxes = new TextBox[] { this.textBox3, this.textBox5, this.textBox7, this.textBox9, this.textBox11 };
CheckBox[] myCheckBoxes = new CheckBox[] { this.checkBox2, this.checkBox4, this.checkBox6, this.checkBox8, this.checkBox10 };
CheckBox[] myMandBoxes = new CheckBox[] { this.checkBox3, this.checkBox5, this.checkBox7, this.checkBox9, this.checkBox11 };
and to verify certain condition i have
xml += "<fields>";
for (int i = 0; i < myTextBoxes.Length; i++)
{
if (string.IsNullOrWhiteSpace(myTextBoxes[i].Text))
{
if (myCheckBoxes[i].Checked == true)
xml += "<field display='yes'> ";
else
xml += "<field display='no'> ";
if (myMandBoxes[i].Checked == true)
xml += "<mandatory='yes'>";
else
xml += "<Mandatory='no'>";
xml += "<label>" + (string)myTextBoxes[i].Text + "</label>";
}
}
It gives me an Indexoutof boud exception at if (myCheckBoxes[i].Checked == true)
How can i resolve this
Your arrays have different amounts of elements in them so you cannot access them all by using the same index. They will have to be done independently.
You don't have same number of checkboxes as Textboxes so you can't access them against the same index.
Your index is starting from 0 to myTextBoxes.Length, if i is going to be greater than 4, then you will get this exception.
Not really sure what you are trying to do but you can add a check against the length before accessing the element from myCheckBoxes.
if (i < myCheckBoxes.Length && myCheckBoxes[i].Checked == true)
xml += "<field display='yes'> ";
Use Foreach instead
Here edit as myTextBoxes.Length - 1
for (int i = 0; i < myTextBoxes.Length - 1; i++)
EDIT:
Also your checkBox count and Textox count does not tally
Your for loop is running to myTextBoxes.length, but you are iterating through myCheckBoxes. It seems you have more textboxes than CheckBoxes
Change it to:
for (int i = 0; i < myCheckBoxes.Length; i++)
{
Instead of
for (int i = 0; i < myTextBoxes.Length; i++)
use
for (int i = 0; i < myCheckBoxes.Length; i++) // or myMandBoxes.Length (Both the CheckBoxes have same items)
Because you are looping with CheckBoxes so why having a length of TextBox.
Your text box has 11 elements, while checkbox has 5 elements.
Change following
if (string.IsNullOrWhiteSpace(myTextBoxes[i].Text))
to
if (string.IsNullOrWhiteSpace(myTextBoxes[i].Text) && i < myCheckBoxes.Length )
First of all, never use += on strings when constructing them with loops, they are immutable, and using it this way, it's just a waste of speed and memory. Use a StringBuilder instance instead.
As for your question, the length of the myTextBoxes array is 10, so you have items at indexes 0 through 9. The code in this line
if (myCheckBoxes[i].Checked == true)
tries to access the corresponding item in the myCheckBoxes array that has 5 elements (indexed 0 to 4). When i becomes 5, the code accesses the myCheckBoxes[5] that does not exist, hence the exception.
Other than that, textBox2 or checkBox7 are simply awful names for controls, and there are better options in the .net Framework for XML serialization and generation.

how to access all of the contents of a DICOM sequence using clearcanvas

Currently I building a small desktop application that can handle DICOM files. I am coding in C# and .NET and using the ClearCanvas library. One thing that I need to do is to be able to display the full contents of the file including all of the sequences. But the sequences are done in a recursive manner, so each sequence can have more sequences inside of it. Right now my code can access the first two levels, but I am just doing this as a tester, since I need to be able to access the nth level of sequences. So I need to somehow automate this. This is what my code looks like right now for the first two levels.
DicomSequenceItem[] seq = attrs2[i].Values as DicomSequenceItem[];
if (seq != null)
{
for (int j = 0; j < seq.Length; j++)
{
for (int n = 0; n < seq[j].Count; n++)
{
DicomSequenceItem[] level2 = seq[j].ElementAt(n).Values as DicomSequenceItem[];
if(seq[j].ElementAt(n).GetValueType().ToString().Equals("ClearCanvas.Dicom.DicomSequenceItem"))
{
for (int k = 0; k < level2.Length; k++)
{
for (int l = 0; l < level2[k].Count; l++)
{
text += "\t\t" + level2[k].ElementAt(l) + "\r\n";
}
}
}
else
{
text += "\t" + seq[j].ElementAt(n) + "\r\n";
}
}
}
}
Any help (code samples) would be greatly appreciated.
Thanks!
Here's a simple recursive routine to traverse through the tags in an attribute collection, including stepping recursively through any Sequence elements that may be in the collection:
void Dump(DicomAttributeCollection collection, string prefix, StringBuilder sb)
{
foreach (DicomAttribute attribute in collection)
{
var attribSQ = attribute as DicomAttributeSQ;
if (attribSQ != null)
{
for (int i=0; i< attribSQ.Count; i++)
{
sb.AppendLine(prefix + "SQ Item: " + attribSQ.ToString());
DicomSequenceItem sqItem = attribSQ[i];
Dump(sqItem, prefix + "\t", sb);
}
}
else
{
sb.AppendLine(prefix + attribute.ToString());
}
}
}
DicomAttributeCollection is Enumerable, so you can just use a foreach loop to go through all of the attributes in the collection. The attributes themselves are stored in a SortedDictionary, so they will also be in ascending tag order when enumerated.
Note that if you downloaded the source code for the ClearCanvas libraries, you also could look at the real Dump() method that is part of the DicomAttributeCollection class. It traverses through a collection and writes to a StringBuilder instance all of the tags in the collection.

Arrange 2 List<string> to list box

i have 2 List that i want to put into my Listbox
the first List contain names and the second contain numbers
my problem is that some of the names long so the numbers cannot a display in the same line
how can i put in in appropriate way ?
listBox.Items.Add("Name" + "\t\t\t" + "Number");
for (int i = 0; i < lists.Count; i++)
{
listBox.Items.Add(lists._namesList[i] + "\t\t\t" + lists._numbersList[i]);
}
Update here is what I tried with a ListView
listViewProtocols.View = View.Details;
listViewProtocols.Columns.Add("Name");
listViewProtocols.Columns.Add("Number");
for (int i = 0; i < lists._protocolsList.Count; i++)
{
listViewProtocols.Items.Add(new ListViewItem{ lists._nameList[i], lists._numbersList[i].ToString()});
}
Consider using a ListView component, with Details style. As #Yuck mentioned in the comments it will give you the effect you need.
It is a bit akward to populate from 2 separate lists but it is doable with the code below:
listView1.View=View.Details;
listView1.Columns.Add("Name");
listView1.Columns.Add("Number");
string[] names= { "Abraham", "Buster", "Charlie" };
int[] numbers= { 1018001, 1027400, 1028405 };
for(int i=0; i<names.Length; i++)
{
listView1.Items.Add(
new ListViewItem(new string[] {
names[i], numbers[i].ToString() }));
}
I would strongly recommend doing an array of structures instead of separate lists like this:
public struct Record
{
public string name;
public int number;
public string[] ToStringArray()
{
return new string[] {
name,
number.ToString() };
}
}
and used like this:
listView1.View=View.Details;
listView1.Columns.Add("Name");
listView1.Columns.Add("Number");
Record[] list=new Record[] {
new Record() { name="Abraham", number=1018001 },
new Record() { name="Buster", number=1027400 },
new Record() { name="Charlie", number=1028405 }
};
for(int i=0; i<list.Length; i++)
{
listView1.Items.Add(
new ListViewItem(list[i].ToStringArray()));
}
There are couple of options I can think of:
Make the listbox wider so that it can accomodate longer text or add a horizontal scrollbar to it.
Constrain the max length of names to, let's say, 20 chars and replace extra characters with ....
Probably the best solution is to use grid instead of listbox - you need to display two columns of data, which is exactly the grid is for.

Categories

Resources