I have a TabControl with two tabs. One tab has a list of stores and the other has a list of employees. On the store tab I have a button that displays all employees of the store; to do that, I want to switch to the other tab and invoke a showEmployeesFromStore(store_id store) method from that tab's User Control. How would I do that?
You've got the wrong mental model. Just because the user control isn't visible on the TabControl doesn't mean that the code is invisible as well. Just call the control's method in your code, it needs to be public of course. Then change the tab control's SelectedIndex property to switch the active tab page.
The button should not be part of the 1st user control. Actually it is better not to use a button but to just trigger an event when the user selects another store.
I would expose an event on the store user control for SelectedStoreChanged or something to that effect. Pass back the newly selected store_id in the event delegate.
Subscribe to that event with your form. When the event fires, it is the form's job to decide with to do with that information. In this case, have it pull out the store_id from the store UserControl's SelectedStoreChanged event and pass it in to EmployeeUserControl.showEmployeesFromStore(store_id store)
Keep your controls ignorant of each other. Let the owner of the controls decide how to react to whatever events are raised by the controls. You'll sleep better with dreams of increased usability, better separation of subject areas, and more fewer working weekends due to untangling odd control flow... ;o)
Just realized I missed a detail. The button you're talking about should be on the form itself and not any of the user controls, assuming you don't want it to just update in real time using eventing described above. On button click, the form should go check StoreUserControl.SelectedStoreID() and pass the result to EmployeeUserControl.showEmployeesFromStore()
Related
I'm looking for the best, most effecient way of implimenting user controls navigation based on events, below is the intended use.
I also don't know what is best, to have the next back button on the control or form.
Lastly, the next button may sometimes change and initially be validate on some controls and then if validated change to next if the validate is ok.
Ok the concept:
I have 1 primary user control with 3 checkboxes, behind each checkbox is a sequence of more user forms therefore, if all three are selected it should then load all three sequences one after another.
Regardless of how many are selected, all sequences end with the same final user control.
Basically I need to understand the best and most practicle way approach this (examples welcome).
There are lots of topics that cover winforms / user control navigation but I cannot seem to see a solution which pops out to me and fits my needs.
For compatibility with some systems, I have decided to use .net 3.5; should this make a difference in suggestions.
Feedback, links, code etc all welcome :)
I ran into a similar scenario some years ago. If memory serves, I approached it as follows:
Separate the navigation buttons into their own control that groups
the buttons together. Design this control to support docking.
In this control, provide distinct buttons for Back, Next, Finish and
Cancel. Provide separate properties on the control that determine
what the user can do: CanMoveBack, CanMoveForward, CanFinish, and
CanCancel. The container should be able to set these.
In the setter for the navigation properties, you want to be able to
adjust the visibility/disabled status of each of the navigation
buttons. Don't hot-swap text. That way, each button does one thing,
and only one thing. This keeps their event handlers nice and clean.
The user control itself should raise events: OnBackClicked,
OnNextClicked, OnFinishClicked, and OnCancelClicked. Your button
event handlers should raise these. The container should decide what
to do when they are clicked.
I have the following scenario that I need to implement.
I have a GridView with a list of records. When a user selects a record, a pop-over screen appears within the browser showing the contents of the record. The contents are rendered from a UserControl, and within the UserControl there is an UpdatePanel that is used for loading/reloading data as it is manipulated and saved.
What I need to occur is that after each save on my UserControl, the GridView on the parent page needs to refresh as to reflect any changes on the record being shown in the pop-over editor control.
My plan is to setup an event on my UserControl that the parent page will subscribe too. When a save operation is executed from within the UserControl, it will call the event, and the parent page should update itself.
However, since the UserControl operates within an UpdatePanel, and is only doing a partial-postback, I am suspect that my events will not work properly.
Should this work as I hope or will I need to find another way of telling my parent page to refresh the master GridView after a record is saved?
If I need to to call an update in a different manner, what is the best approach for this scenario? I ask because I'd rather not build-out some complex saving/updating operation only to find out that I've made a few miss-assumptions and need to re-code the whole update and reload process.
I have done that before I just don't remember exactly how as I haven't been working with Web Forms in a little while. You have the right idea. The event will get raised on the parent page but you will have to do another PostBack/Partial PostBack afterwards to update the grid from the event handler on the parent. Also you will have to make sure the properties on the UpdatePanel have been set up right.
Another option is doing a full postback when you close the PopUp. If the popup is big enough that it prevents the user from seeing the grid it wont make a difference whether the record on the grid is updated when the Modal is closed rather than when the data is saved.
I have the next situation:
there is a client app with a Form
the Form contains a few TabControl's
there are different controls on TabPage's of TabControl's
when the user clicks on any control, I need to activate the TabPage that is a parent of a control. For that I use a TabPage Enter event
when the TabPage gets activated, I need to make request to the server app, and I put focus to a hidden TextBox to disable UI
The problem is, when I click on a Button on another TabPage, in TabPage.Enter event handler I take focus to my hidden TextBox, and it seems like Button click event doesn't have enough time to be processed. When I put timer and handle TabPage.Enter event after 100 ms, the Button click event seems to be fired well. Same thing happens to all the controls: CheckBox doesn't get checked, RadioButton too. I wouldn't like to use timer, as that is not a stable solution.
Any ideas how could I make TabPage to process all mouse events before I take focus to hidden TextBox? I tried to use Application.DoEvents(), but that didn't help.
You are using a wrong event for a wrong control for what you are trying to do.
Enter event for TabPage is going to be fired when that page becomes an active control of the current form which might not happen under certain conditions. Instead, you need to use Selecting or Selected event of TabControl, depending on whether you want to cancel switching to a different tab or not (see TabControlCancelEventArgs parameter of Selecting event). In your case, Selecting event would be more appropriate since it won't allow switching to a selected tab until event is complete (unless you're doing an asynchronous request to the server). Additionally, you may no longer need to use the hidden TextBox.
UPDATE
Regarding comments to OP, when you have 2 (or more) TabControls on a form and you want to get notified when you press a button in any tab of a different TabControl, you can use Enter event for TabControl. Use a global variable to store which TabControl was activated in the Enter event and then send server request for a currently active tab of that activate TabControl.
If this doesn't work for your scenario, then you need to carefully examine your workflow and see if it can be improved in relation to what you want to accomplish.
I am recently working on windows forms with visual C# and I have a bunch of radio buttons grouped together.
I needed to call some methods if the radio button is clicked and also do some validation.
So I have two methods,
public void doSomeStuff()
public bool valRadioButton1()
I can call doSomeStuff() in the click event and the latter in the validating event of the radiobutton but I could also just call both in either the click event or the validating event.
My question is that are there any advantages and disadvantages as to what event I would use to call these? Or is there any particular way is more efficient. Right now it seems that both events would do the exact same thing so why use one or another or both.
Radio buttons are kind of strange in combination with the conventional validation. The validating event seems to be designed to allow you to validate a value once when the user is done entering a value instead of every time the value changes as the user is entering it. This makes sense for a textbox where you want to look at the completed text instead of after each character that the user types. But it's a little more obscure for radio buttons. In fact I think you should generally avoid the validating event of radio buttons and instead use the validating event of the container (radio buttons should always be in an embedded container). This allows a keyboard user to select/move through different options to arrive at the one they want without repeated validations as they move through the options. Then when they move focus out of the group box (or whatever container you used), you can validate the whole option group at once. This behavior is more consistent, then, with that of other controls' validation. In fact I see very little purpose to using the validating event on individual radio buttons. The only reason I see is if you want to cancel the user's new selection without causing extra click events. But be aware that when no radio button is selected and the user first clicks on one, no validating event will occur! No radio button lost focus and validating events only occur when a control loses focus. So this is why I think you should just avoid the validating event on radio buttons and just use the validating event of the container or the click event of a radio button.
Also, I think if you want to be nice to keyboard users, you should keep the validation logic separate from the click logic and use the events appropriately. Things like enabling controls based on which option is selected would belong in the click event of a radio button, but error and warning messages about the currently selected option should go in the validating event of the container.
Edit: You asked specifically about when one event occurs and not the other. I would add this information in response to that:
Validate will be called without calling click if the code is what causes the selected radio button to change, assuming focus then passes to the radio button (or container, if you are using the container's validate event).
Click will be called without (or should I say before) calling validate if no radio button was selected and the user then clicks on one (validate only occurs when the control loses focus). Validate will eventually occur for the clicked option, though.
Click will be called without (or should I say before) calling validate if your validate handler is not linked to the specific option that was previously selected or its container. It will be called for the option that is now selected (and the container) when this option (or the container) loses focus, though.
Click could be called without validate being called if your code that looks at the value doesn't require the selected option to lose focus before looking at it.
The validation event exist for when a controls value has changes, this is decoupled from how the controls value was changed. Was it changed because a datasource was refreshed, was it changed by an end user, was it changed on a timer? Doesn't matter!
I would use the validating event to evaluate if something is valid. Even if you know that there is "no way ever that it could happen any other way".
I have two tabitems. User will enter some data and save it on the first tab. The second tab lists the saved data. What I need is when the user select the second tab before saving data in first tab a confirmation message box with Yes, No and Cancel should be shown. If the user clicks Yes button the data should be saved and go to the second tab. If he hits No, the data need not to be saved and finally if Cancel is hit the tab will retain with all entered data. How can i make this?
To keep things simple you can do the follwing in the Code Behind file.
I'd create a Model class of the data you want to display and edit in the WPF Control. Make the Model implement the INotifyPropertyChanged and IEditableObject interfaces.
INotifyPropertyChanged will allow you to Bind to the Model.
IEditableObject will allow you to provide Edit, Save and Cancel functionality.
The TabControl has a SelectionChanged Event you can handle, that will allow you to detect when the user changes tabs, in this handler you can use System.Windows.MessageBox to ask the user to save etc, System.Windows.MessageBox.Show() returns a MessageBoxResult Object you can use to detirmine what button the user clicked and perform the appropiate action.
This is not a geat way to do things, but it keeps things simple, you may want to look into some WPF design Patterns to help with Code Manageability.
If you need anything explained further, just ask.
Although I disagree with the way you interrupt the user's flow from tab to tab I'm going to humor you and answer the question:
You'll need two things to get this done:
The event that occurs when a tab was clicked
The previous tab that was selected (the one you came from)
The first item:
The tab control has a Click method that you can subscribe to:
Click=”MyTabButton_Click”
The second item:
This part you'll have to do manually. You can set a variable in the click event which contains what tab was last selected. Once this is set you can check a variable (which you previously set) as to what tab was previously selected. You can then do all your validation.
Delphi's TPageControl has an OnChanging event with an "AllowChange" parameter. I guess there is something similar in WPF.