C#: Using an ArrayList in a MessageBox

Started by
7 comments, last by Arild Fines 17 years, 12 months ago
My job at the University of Iowa is to computerize certain psychological experiments that used to be performed by hand. Part of the job is to allow the experimenters to alter the instructions or parameters of the program via text files. Now, I'm writing a method that reads input from a text file line by line and prints it all out to a MessageBox so the user can read it (the user is required to confirm that they understand the instructions, so I thought this would be the ideal way to do this). Since I won't know how many lines the experimenters might change the instructions to, I decided to use an ArrayList. Here's some code:
StreamReader input = new StreamReader(@"gain.txt");
string lineIn;
ArrayList instructions = new ArrayList();

do
{
   /* Grab the line from the file */
   lineIn = input.ReadLine();

   /* Save it to the ArrayList */
   instructions.Add(lineIn);
} while (lineIn != null);

/* Display the instructions in the MessageBox */
MessageBox.Show(instructions.ToString(), "Instructions: Please Read Carefully!", MessageBoxButtons.OK, MessageBoxIcon.Information);


I proposed to use instructions.ToString() to output the contents, but all that gets output is "System.Collections.ArrayList", and for some reason when I press the OK button, it beeps again and I have to press it a second time. Any help would be greatly appreciated, either in coming up with a better way to use the ArrayList, or a completely new way to display the instructions altogether. Many thanks in advance, and ratings will be given to those kindhearted enough to help. EDIT: Silly me, nevermind the part about calling up the MessageBox twice. I forgot that the program runs in two sections that use the same method. [Edited by - FinalMinuet on April 17, 2006 10:44:46 PM]
Advertisement
The first thing that comes to mind is that you could just iterate over the ArrayList and assemble the string:

StringBuilder MessageBuilder = new System.Text.StringBuilder();foreach(String MessageLine in instructions){   MessageBuilder.Append(MessageLine);   MessageBuilder.Append("\n");}MessageBox.Show(MessageBuilder);



Please note though that I've barely started poking into C#, so there's probably a much cleaner way to do this. It's what I'd do in most other languages, though. Hope that's at least partially useful [smile]

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

How about creating a form that displays the instructions to the user? Something as simple as a listBox with some buttons.

To access the individual members of an ArrayList, you'll have to index into the ArrayList using the Item property.

Another possibility for storing your data would be to create a custom collection class designed to hold only strings. In this class you could override the ToString() method and have it return all the instructions.
Just in case people didn't notice, I edited the post. Ignore the part where I mention the MessageBox beeping twice. It's supposed to and I forgot.
Quote:Original post by FinalMinuet
I proposed to use instructions.ToString() to output the contents, but all that gets output is "System.Collections.ArrayList", ...

Yes, this is correct behavior. You were trying to output a collection of items, not the items themselves.

Assembling the ArrayList into a single string using a StringBuilder is probably the best way. If you have to do this a lot, you may want to consider creating a utility method that does the heavy lifting, so as to avoid code duplication.

Also, if you're using C# 2.0 (and not 1.1), you may want to consider using generics for the performance, readability, and correctness benefits: ArrayList<string> instead of ArrayList.

Finally, a MessageBox is not really the appropriate vehicle for messages of unknown size, particularly if the messages could become very long or if they're complicated. MessageBoxes are for short, urgent situations that require the user to take action ("Are you sure you want to quit without saving?") or errors and notifications that the user should be aware of ("The file was not found.", "You have an incoming phone call from 434-791-6279.").

A better strategy is a Form that has a multiline, read-only text box that users can scroll through to read any important messages.
- k2"Choose a job you love, and you'll never have to work a day in your life." — Confucius"Logic will get you from A to B. Imagination will get you everywhere." — Albert Einstein"Money is the most egalitarian force in society. It confers power on whoever holds it." — Roger Starr{General Programming Forum FAQ} | {Blog/Journal} | {[email=kkaitan at gmail dot com]e-mail me[/email]} | {excellent webhosting}
Quote:Original post by kmccusker
To access the individual members of an ArrayList, you'll have to index into the ArrayList using the Item property.

There is no Item property in C#; that is for languages that do not support indexers. Instead, you would use myArrayList[k] to access the (k+1)th item in the ArrayList (presuming the ArrayList has at least k+1 items, of course).
- k2"Choose a job you love, and you'll never have to work a day in your life." — Confucius"Logic will get you from A to B. Imagination will get you everywhere." — Albert Einstein"Money is the most egalitarian force in society. It confers power on whoever holds it." — Roger Starr{General Programming Forum FAQ} | {Blog/Journal} | {[email=kkaitan at gmail dot com]e-mail me[/email]} | {excellent webhosting}
I'll probably just make a read-only TextBox and a CheckBox at the end that must be active in order for the user to click the OK button and continue, sort of like the EULAs you have to agree to when you install a program. The instructions aren't extremely long, 12 lines right now including blank lines, which is why I was hoping to pull it off in a MessageBox. I've never used StringBuilder before, so I'll have to do a bit of reading first, but that's no big deal.

Oh, and just to clear something up:
Quote:Original post by kSquared
Quote:Original post by kmccusker
To access the individual members of an ArrayList, you'll have to index into the ArrayList using the Item property.

There is no Item property in C#; that is for languages that do not support indexers...

The way I understand this is that there is an Item property in C#, but it isn't accessed by calling myArrayList.Item(index). It's merely just the classic indexer used in C++, myArrayList[index]. However, for universability it is included as Item so it can be compatible with other .NET languages that use Item, like Visual Basic. Correct me if I'm wrong. I'm always looking to clear up confusion.

Thanks much for all the advice. It really helps out.
Quote:Original post by FinalMinuet
The way I understand this is that there is an Item property in C#, but it isn't accessed by calling myArrayList.Item(index). It's merely just the classic indexer used in C++, myArrayList[index]. However, for universability it is included as Item so it can be compatible with other .NET languages that use Item, like Visual Basic. Correct me if I'm wrong. I'm always looking to clear up confusion.

We essentially just said the same thing. [wink] Again, there's no Item property accessed in C#. When you write C# code that includes an indexer, however, an Item property is generated in the IL. This enables CLR-compatible languages which do not support the notion of indexers to nonetheless use indexed properties.

Note that nothing actually prevents you from actually writing a property called Item in C#, though; this is perfectly legal syntax.

hope that helps,
- k2"Choose a job you love, and you'll never have to work a day in your life." — Confucius"Logic will get you from A to B. Imagination will get you everywhere." — Albert Einstein"Money is the most egalitarian force in society. It confers power on whoever holds it." — Roger Starr{General Programming Forum FAQ} | {Blog/Journal} | {[email=kkaitan at gmail dot com]e-mail me[/email]} | {excellent webhosting}
What I do in cases like this (2.0 and generic collections only):

string[] lines = File.ReadAllLines(@"gain.txt")]string text = ListUtils.Reduce<string>(lines, delegate(string s1, string s2){   return s1 + ", " + s2;});MessageBox.Show( text );public delegate T Reducer<T>(T t1, T t2);public class ListUtils{        // ...        public static T Reduce<T>(IEnumerable<T> list, Reducer<T> reducer)        {            IEnumerator<T> enumerator = list.GetEnumerator();            if (!enumerator.MoveNext())            {                return default(T);            }            T accumulator = enumerator.Current;            while (enumerator.MoveNext())            {                accumulator = reducer(accumulator, enumerator.Current);            }            return accumulator;        }         // ...}...

The full ListUtils class can be found here.
--AnkhSVN - A Visual Studio .NET Addin for the Subversion version control system.[Project site] [IRC channel] [Blog]

This topic is closed to new replies.

Advertisement