Changing properties of Form controls (listview) from a class (C#)?

markm75

Newcomer
Joined
Jan 16, 2006
Messages
15
I've dug around on the net for the best solution to this.. so far without much luck.

I have a form, with a listview control on it. From another class, when a variable (arraylist) gets updated (arraylist.add), the next line needs to be code that will add the last value to the listview control on the form (from this class object).

So for now I've simply added a Public method to the form itself. IE: Public void UpdateListControl.

To get at that method from the class i'm casting a Form object.

I'm not convinced this is the best way to do this.. ie: My understanding of Forms and business logic, was to always add as little extra code to the Form (code) , keeping it streamlined.

Is there another way of doing this?

This other class object that needs to update the form control is also part of a new thread which is created at some point, so passing form controls via a parameter has been avoided as a result.

Thanks
 
There are a couple of other ways of achieving what you want todo. One way would be to add an event, but thats abit OTT and would still require code on the form. The easiest way is to pass a reference to the listview control as a parameter, to the class that will be changing it. This way you will be able to simply call myListView.Items.Add(object).
 
Cags said:
There are a couple of other ways of achieving what you want todo. One way would be to add an event, but thats abit OTT and would still require code on the form. The easiest way is to pass a reference to the listview control as a parameter, to the class that will be changing it. This way you will be able to simply call myListView.Items.Add(object).


I figured one way would be to pass the object as a parameter, but I'm using threading, which doesnt seem to be parameter friendly..

IE:

threadReceiverInternal = new Thread(new ThreadStart(Receiver_o.Start));

Where in this case the Receiver_o.Start cant take any parameters. I did try one method of passing parameters that I found on the web, but it didnt seem to work, or it did, but I wasnt able to call the .abort() command etc.
 
There is nothing wrong with putting code in your form class so long as it is relevant to the execution of your form. The general good practice is that you want to avoid coupling between your presentation layer (GUI) and business logic. Passing a pointer to a listview would unnecessarily couple your form class and your logic class. Think about it, if you were to suddenly decide that you wanted to display the data in the arraylist using a fancy, expensive grid instead, you would actually have to change your logic class AND your form. In reality, all you did is change your from, so that's all you should need to change. On the same token, say you decide in the future you don't want to use an ArrayList anymore and you've decided to use a database. You don't suddenly want to start adding db calls to your form class...

I would probably go with an event that your logic class uses to send information to the main form, especially seeing as how it is threaded. The important part is that you don't want either class to know or care about the other. It shouldn't matter to the form that the data is held in an ArrayList (or database or whatever) and it shouldn't matter to the logic class that the data is being displayed in a ListView.

Another possible way to handle this in a single threaded environment might be using a delegate without an event where the logic class receives a pointer to an "update" function in the form class (not a pointer to the whole form class or even widgets on the form). I'm pretty sure you'll run into concurrency issues with the threading, though if you do it that way.

It does take a little more overhead to reduce coupling like this (I think that's why Cags said it might be overkill), but if you expect any changes at all in either class it's ussually well worth the extra effort in my experience.
 
mskeel said:
There is nothing wrong with putting code in your form class so long as it is relevant to the execution of your form. The general good practice is that you want to avoid coupling between your presentation layer (GUI) and business logic. Passing a pointer to a listview would unnecessarily couple your form class and your logic class. Think about it, if you were to suddenly decide that you wanted to display the data in the arraylist using a fancy, expensive grid instead, you would actually have to change your logic class AND your form. In reality, all you did is change your from, so that's all you should need to change. On the same token, say you decide in the future you don't want to use an ArrayList anymore and you've decided to use a database. You don't suddenly want to start adding db calls to your form class...

I would probably go with an event that your logic class uses to send information to the main form, especially seeing as how it is threaded. The important part is that you don't want either class to know or care about the other. It shouldn't matter to the form that the data is held in an ArrayList (or database or whatever) and it shouldn't matter to the logic class that the data is being displayed in a ListView.

Another possible way to handle this in a single threaded environment might be using a delegate without an event where the logic class receives a pointer to an "update" function in the form class (not a pointer to the whole form class or even widgets on the form). I'm pretty sure you'll run into concurrency issues with the threading, though if you do it that way.

It does take a little more overhead to reduce coupling like this (I think that's why Cags said it might be overkill), but if you expect any changes at all in either class it's ussually well worth the extra effort in my experience.



Thanks for the help, you have eased my mind :)

I do have one coding question that is causing me grief related to this...

I have a class, inside that class I have:

Form1 frmObj = (Form1)Form.ActiveForm;

Then in one of the classes, methods I do "frmObj.PUBLICMETHOD", public method being the public method I created to update a form control.

It seems that Form.ActiveForm sometimes comes back as being null, consequently making it impossoble for the method to fire.

Is there some other way of referencing my existing Form1 and getting at that public method? Passing the form object to the class object is not possible either, simply because I would doing so in too many places and the function where I call the PUBLICMETHOD is inside of a class object as it stands (and is called from other class objects-non form objects).

Thanks
 
markm75 said:
Passing the form object to the class object is not possible either, simply because I would doing so in too many places and the function where I call the PUBLICMETHOD is inside of a class object as it stands (and is called from other class objects-non form objects).

When you say you'd be passing it too many times what do you mean by this, do you create a lot of instances of the class, or do you simply call methods from it lots of times?
 
Cags said:
When you say you'd be passing it too many times what do you mean by this, do you create a lot of instances of the class, or do you simply call methods from it lots of times?


Well.. I have this method in a class called LogFileWriter. I call this method from both Form code and from other classes, hence if I were to add a parameter to pass the Form it was called from, it wouldnt be valid in the case of calling it from another class, since that class wasnt called from a Form.
 
Cags said:
I see, if the code is called from another class does it need to select the form the same as if its called from the form?

Yeah.. this other class which does other things uses the LogFileWriter method..

Its from this Method that I'm trying to access a public method in the Form1 object: Specifically the one I call UpdateLogWindow in the main form code.

So basically, each time I want to update the log file, I also run the UpdateLogWindow method on the form, to update a rich text box with the log information (so the user doesnt have to manually open the log file to see log updates, they are dynamic on the screen).

I was able to do a similar thing in a different class with a listbox, but for some reason in this other class which contains the logfilewriter method, if I access the public method, it sees the Form1.ActiveForm as being null, meaning when the class starts, I have a line Form1 frmObj = (Form1)Form.ActiveForm;, apparently it thinks that Form.ActiveForm is null here, so later when I try to run the Public Method from Form1, it bombs out due to the null problem.

Hopefully this doesnt sound more confusing...
 
I should mention that the exact error I get when I try to fire off my Public Method from the form is:

Object reference not set to an instance of an object

Again, I'm assuming its because it thought that Form1.ActiveForm was null.

Which it shouldnt be, as the form had already fully loadeded prior to this.
 
Hmm... I'm not entirely sure I followed everything you were saying there, but by the sounds of it a custom event using a delegate could be the way to go. I've only used theses a few times, but I've found them very usefull when I've needed to perform an action in a parent object.

EDIT:- Sorry it does seem like were going in circles here.
 
Back
Top