Click here to Skip to main content
14,390,091 members
Rate this:
Please Sign up or sign in to vote.
See more:
My application consists of a number of tab pages.

On one we have 5 custom buttons that can be set with details that are then used when the button is clicked. The buttons have 3 main states.

On the main tab page I have 5 buttons of the same type that are representative of the other buttons which basically gives 5 pairs of buttons.

When any button is pushed on either tab page code is run and I need the other paired button to be set to the same state.

All buttons use the same code from the main Form file and the buttons on the setup tab are linked via
this.commentatorPicks.PTR_Commentator_1.Click += new System.EventHandler(this.CommentatorPTR_Click);
            this.commentatorPicks.PTR_Commentator_2.Click += new System.EventHandler(this.CommentatorPTR_Click);
            this.commentatorPicks.PTR_Commentator_3.Click += new System.EventHandler(this.CommentatorPTR_Click);
            this.commentatorPicks.PTR_Commentator_4.Click += new System.EventHandler(this.CommentatorPTR_Click);
            this.commentatorPicks.PTR_Commentator_5.Click += new System.EventHandler(this.CommentatorPTR_Click);

with the other buttons linked via the OnClick event.

I have tried a number of ways to keep the buttons in sync like cloning the state of the paired button that is not clicked, but the state of the first button looks like it is not set until after the call

The code I am trying to run is this

public void CommentatorPTR_Click(object sender, EventArgs e)
        {
            {
                PreviewTakeRemoveButton ptrBtn = sender as PreviewTakeRemoveButton;
                PreviewTakeRemoveButton remoteBtn = null;
        
                if (ptrBtn != null)
                {
                    String name = (sender as Button).Name;
                    int pos = name.LastIndexOf("_") + 1;
                    String number = name.Substring(pos, name.Length - pos);

                    if (name.StartsWith(NZRB_Global.Consts.MAIN_PICKS_BUTTON_PREFIX))
                    {
                        remoteBtn = (PreviewTakeRemoveButton)inRaceSceneControl.GetControl(NZRB_Global.Consts.COMMENTATOR_PICKS_BUTTON_PREFIX + number);
                    }
                    else
                    {
                        remoteBtn = (PreviewTakeRemoveButton)inRaceSceneControl.GetControl(NZRB_Global.Consts.MAIN_PICKS_BUTTON_PREFIX + number);
                    }
                     
                    String commentator = (String)ptrBtn.Tag;
                    XmlNode picks = commentatorPicks.GetCommentatorPicks(commentator);
                    if (null == picks)
                    {
                      //  ptrBtn.ResetButton();
                    }
                    else
                    {
                        NZRB_Global.Utils.LogButtonClick(sender, ptrBtn.Name + " " + ptrBtn.ButtonState);
                        String dp = commentatorPicks.GetCommentatorDataPool(picks);

                        switch (ptrBtn.ButtonState)
                        {
                            case PreviewTakeRemoveButton.PTRB_STATE.PBS_INACTIVE:

                                inRaceSceneControl.SendVizCmd(false, dp);
                                inRaceSceneControl.ShowScene(false, NZRB_Global.Consts.DIRECTOR_FF_SELECTIONS, Consts.GFX_LBAR_LAYER, null, SceneType.sports, true);
                                break;

                            case PreviewTakeRemoveButton.PTRB_STATE.PBS_TAKE:
                                inRaceSceneControl.ClearScene(false, NZRB_Global.Consts.DIRECTOR_FF_SELECTIONS, Consts.GFX_LBAR_LAYER);
                                inRaceSceneControl.SendVizCmd(true, dp);
                                inRaceSceneControl.ShowScene(true, NZRB_Global.Consts.DIRECTOR_FF_SELECTIONS, Consts.GFX_LBAR_LAYER, null, SceneType.sports, true);
                                break;

                            case PreviewTakeRemoveButton.PTRB_STATE.PBS_REMOVE_TAKE:
                                inRaceSceneControl.ClearScene(true, NZRB_Global.Consts.DIRECTOR_FF_SELECTIONS, Consts.GFX_LBAR_LAYER);
                                break;
                        }
                    }

                    remoteBtn.CloneButton(ptrBtn);
                }
            }            
        }


Does anyone have any idea how i can get this to work?

What I have tried:

Cloning second buttons state
Setting second button to next state
Canning Perform Click on second button (endless loop)

Additional Info's :
I am using Winforms and it is quite a complex UI due to the working style of the operators.

 Basically there are many custom buttons and User Controls that send graphics to a "preview" machine and then the main on-air graphics engine.

 There are many scenes that can be sent and some scenes can co-exist with others while other scenes need to be removed automatically if another scene is sent over top.
 When a scene is removed automatically the corresponding buttons also need to be reset to a starting state.

 I also have to juggle the existence of a background that can be used with some of the scenes either manually or automatically.

 I have dealt with the current situation(in the short term at least) by ensuring the operator can only use one of the paired buttons at a time to remove the "mix and match" possibility. So once a button sends an image to either the preview or main display the corresponding "paired" button is disabled until the scene is removed either by another button click or automatically. 
Posted
Updated 20-Mar-19 23:21pm
v2
Comments
Gerry Schmitz 19-Mar-19 22:51pm
   
"Buttons" have no state. A variation is the ToggleButton or the CheckBox; which maintain "independent" state. State can be coordinated via a "group" of "Radio Buttons", but not buttons. "Custom buttons" are another story. It looks foreign from here.
Jason Gleim 20-Mar-19 16:40pm
   
You should not use buttons to manage the state. When a button isn't visible on screen it isn't updated. So you are tying to set properties on an object which isn't visible... that won't do anything.

You need to manage your state with an object. Update the state in the click handlers then reflect that back out to the buttons. However, you don't say if you are using winforms or xaml for the UI. You may also run into a situation where you can't update the button state from inside the event handler. There are rules around that like you can't raise an event which results in UI changes from inside the event handler for an event surfaced by the UI. You have to decouple one event from another using a timer or a storyboard or something like that which allows the UI thread to exit the current event handler before entering a new one.

The best approach would be data binding the buttons back to a global state object that implements INotifyPropertyChanged. That's easy to do in xaml but much more difficult in Winforms.
Member 13724700 21-Mar-19 15:15pm
   
I am using Winforms and it is quite a complex UI due to the working style of the operators.

Basically there are many custom buttons and User Controls that send graphics to a "preview" machine and then the main on-air graphics engine.

There are many scenes that can be sent and some scenes can co-exist with others while other scenes need to be removed automatically if another scene is sent over top.
When a scene is removed automatically the corresponding buttons also need to be reset to a starting state.

I also have to juggle the existence of a background that can be used with some of the scenes either manually or automatically.

I have dealt with the current situation(in the short term at least) by ensuring the operator can only use one of the paired buttons at a time to remove the "mix and match" possibility. So once a button sends an image to either the preview or main display the corresponding "paired" button is disabled until the scene is removed either by another button click or automatically.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100