Sign in to follow this  
FinalMinuet

C#: Using an ArrayList in a MessageBox

Recommended Posts

FinalMinuet    122
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]

Share this post


Link to post
Share on other sites
ApochPiQ    22999
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]

Share this post


Link to post
Share on other sites
kmccusker    196
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.

Share this post


Link to post
Share on other sites
kSquared    1356
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.

Share this post


Link to post
Share on other sites
kSquared    1356
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).

Share this post


Link to post
Share on other sites
FinalMinuet    122
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.

Share this post


Link to post
Share on other sites
kSquared    1356
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,

Share this post


Link to post
Share on other sites
Arild Fines    968
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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this