By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
434,637 Members | 1,967 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 434,637 IT Pros & Developers. It's quick & easy.

c# app - probably simple question about interface design

maxx233
P: 32
Hello,
I'm developing a simple program to control a video switcher we have via RS232. All the backend control stuff is figured out just fine, the interface is what's giving me problems! I'm basically just trying to figure out how to light up buttons depending on how they logically refer to each other, and I'm certain it should be simple, but I feel like I'm going in circles on it and getting nowhere...

What I want is a column of buttons on the left (labeled Inputs 1-7), and a column of buttons on the right (labeled *Outputs* 1-7)... An Input button can be logically connected to several Output buttons (one input can feed multiple outputs), and each Output button can be logically tied to one Input button (Each output can only have one Input source.) When the user selects an input on the left, it needs to go into an 'edit mode' and show all the outputs on the right that are being fed the input selected - let's just say it's supposed to set the Output button's color to green instead of grey if that Output is being fed by the Input that was selected. Then the user can select/unselect any outputs on the right and eventually click something to end 'edit mode'. As they're making these changes the Output buttons light up or go back to being grey, depending on whether they've selected or unselected that button, and when it's all final it's saved/tracked somehow so when that Input is selected again it accurately shows which Outputs the Input is feeding. Likewise, if the user clicks any of the outputs on the right, it should show the one single input that's feeding that output device, and then the user has the option of selecting a different input and ending edit mode.

I've been trying to do it with a funky system of arraylists referrencing the button objects, and passing things all over, and I just have a strong feeling I'm *not* doing it right/efficiently, cause it's feeling way more convoluted that it should. And I haven't got it working anyway ;)

Does anyone have any ideas how this could be accomplished? I'm not an overly experienced programmer, there may well be some simple things I'm not thinking of. If you can even suggest ideas that would be really helpful - that's really what I'm after, I can figure out the coding. The simplest thing I could think of was passing a string around of which object is being edited, but I couldn't figure out any way to use that string on the receiving end to actually call reference to an object... Any ideas on that or anything else?? Thanks a ton!!

Maxx
Sep 17 '08 #1
Share this Question
Share on Google+
3 Replies


balabaster
Expert 100+
P: 797
Okay, I assume you can get the system to go into edit mode and out of edit mode okay.

My thought is that the most efficient way is to have an array or collection tied to each of the inputs, just the way you are doing it.

You will notice that buttons have a TAG property - you can attach an object to this:

MyButton.Tag = MyObject;

Well, lets say MyObject is a collection... or an array, list or whatever you like.

So now you're in edit mode, click one of the outputs. If this output button is not in the input button's output collection, then first, go through and make sure it's removed from all the other input button's collections and then attach it to this one.

Something like (Pseudo code):
Expand|Select|Wrap|Line Numbers
  1. button btnCurrentInput;
  2.  
  3. InputButtonHandler (handles all input buttons){
  4.   btnCurrentInput = this;
  5. }
  6.  
  7. OutputButtonHandler (handles all output buttons){
  8.   Dim col As Collection = (Collection)btnCurrentInput.Tag;
  9.   if col.Contains(this){
  10.     col.Remove(this);
  11.   }
  12.   else{
  13.     for (button btnInput in InputButtons){
  14.       collection crntCollection = btnInput.Tag;
  15.       if crntCollection.Contains(this){
  16.         crntCollection.Remove(this)
  17.       }
  18.     }
  19.     col.Add(this);
  20.   }
  21. }
Conceptually, that should work just fine...

If the current input already contains this output, remove it, otherwise remove it from all other outputs before adding it to this input...

When you go into edit mode, first turn all of the output buttons grey, and then cycle through your collection and turn each of the button objects in the collection green. With objects, you always refer to them by reference. So if you turn the object in your collection green, the button displayed on screen is actually the same object, so it will turn green. Put the code to set the button colors in it's own method so you can reference it both when going into edit mode and when you click each of the output buttons so that you can refresh their colors.
Sep 17 '08 #2

P: 3
I am not 100% sure that I understand exactly what you're trying to accomplish but if I am on the right track:

There are many ways to solve your problem but you might want to look at creating an input class and then create 7 instances of that class. then you can create an output object and add them to the relevant input class.

A place to start:
Expand|Select|Wrap|Line Numbers
  1.     public class Input
  2.     {
  3.         private List<Output> _outputs;
  4.  
  5.         public List<Output> Outputs
  6.         {
  7.             get
  8.             {
  9.                 return _outputs;
  10.             }
  11.             set
  12.             {
  13.                 _outputs = value;
  14.             }
  15.         }
  16.     }
  17.  
  18.     public class Output
  19.     {
  20.         //variables/methods/properties
  21.     }
  22.  
Sep 17 '08 #3

balabaster
Expert 100+
P: 797
Another possibly simpler way is just to attach the output button's tag to the input button. When you click the input button, it turns all output buttons green that have the input button as the tag. If you click it when it's already got a tag, remove the tag.

Expand|Select|Wrap|Line Numbers
  1. Button thisEdit;
  2.  
  3.         private void refreshGUI()
  4.         {
  5.             foreach (object crntControl in grpOutputs.Controls)
  6.             {
  7.                 if (crntControl.GetType() == typeof(Button))
  8.                 {
  9.                     Button crntOutput = (Button)crntControl;
  10.                     if (crntOutput.Tag == thisEdit)
  11.                     {
  12.                         crntOutput.ForeColor = Color.Green;
  13.                     }
  14.                     else
  15.                     {
  16.                         crntOutput.ForeColor = Color.Black;
  17.                     }
  18.                 }
  19.             }
  20.         }
  21.  
  22.         private void InputHandler(object sender, EventArgs e)
  23.         {
  24.             thisEdit = (Button)sender;
  25.             this.refreshGUI();
  26.         }
  27.  
  28.         private void OutputHandler(object sender, EventArgs e)
  29.         {
  30.             if (thisEdit != null)
  31.             {
  32.                 Button thisOutput = (Button)sender;
  33.                 if (thisOutput.Tag == thisEdit)
  34.                 {
  35.                     thisOutput.Tag = null;
  36.                 }
  37.                 else
  38.                 {
  39.                     thisOutput.Tag = thisEdit;
  40.                 }
  41.                 this.refreshGUI();
  42.             }
  43.         }
This should do the job without having to worry about collections and stuff. I put each of the input buttons in a group box called grpInputButtons and all of my output buttons in another group box called grpOutputButtons which allowed me to loop through each of the buttons without having to resort to arrays but still getting the benefit of a control collection.

Don't forget to hook all your buttons up to the single event handlers. This can be done in Form1.Designer.cs (Assuming your form is called Form1)

Expand|Select|Wrap|Line Numbers
  1. this.btnInput1.Click += new System.EventHandler(this.InputHandler);
  2. this.btnInput2.Click += new System.EventHandler(this.InputHandler);
  3. ...
  4.  
  5. this.btnOutput1.Click += new System.EventHandler(this.OutputHandler);
  6. this.btnOutput2.Click += new System.EventHandler(this.OutputHandler);
  7. ...
Hope that points you in the right direction.
Sep 17 '08 #4

Post your reply

Sign in to post your reply or Sign up for a free account.