InfoPath repeating table validation - c#

I've got several repeating tables sitting in a InfoPath form. Essentially each one lists a load of strings with checkboxes next to them. When the user clicks submit I want to ensure that at least one checkbox per repeating table has been ticked.
I was just in the middle of writing a validating event handler for the table which would set a validation variable to either true or false but I realised that the main data source is read-only on validating and changed events.
How would I go about checking that something has been ticked in the repeating table before the form is submitted?
[NOTE] I'm using repeating tables instead of the multiselection control because the form has to be browser compatible.
Thanks in advance

I think you have two options (and these are just off the top of my head / not actually building a similar form solution).
1) Build an XPath expression that will evaluate whether or not one of your checkboxes has been selected. Than add a hidden node to your form (one not bound to a control in thew view), and add this validation property to it.
2) Continue writing your event handler, to cancel the submit event after running your custom validation logic in code.
http://msdn.microsoft.com/en-us/library/microsoft.office.infopath.formevents.submit(VS.80).aspx

Related

C# ASP.NET - Dynamic MenuItems in a user control are randomly being duplicated outside of control creation

EDIT: I needed to skip control creation during post back -- see my answer below.
I'm working on a very basic front end to a simple tool and I wanted to present some data in a much more sorted and useful way, instead of making one huge wall of text. I found this tutorial on building a simple tabbed interface using MultiView, but have run into a bizarre problem. I can't use Ajax tabs because of legal hissy fits over 3rd party software.
My webpage is a basic ASP.NET page with a user control plopped in the middle of it. In this control's ascx file, I defined the Menu (empty) and the MultiView (also empty) so that I can dynamically populate the tabs with content driven from an external file.
When the default page's OnInitComplete function is called, I call through to the user control to load the data file, then build out the tabs and the view content based on the loaded data. I tried doing this from PageLoad, PreInit, and CreateChildControls, but I kept getting an errors saying that I was setting the the MultiView's active view index at an invalid time (and also that there were 0 views despite the fact I just added a bunch of them):
ActiveViewIndex is being set to '0'. It must be smaller than the
current number of View controls '0'. For dynamically added views, make
sure they are added before or in Page_PreInit event.
But OnInitComplete appears to work just fine, so I went with that.
I iterate over the loaded data (multiple lists of strings), and for each list, I add a MenuItem with the list's title to the Menu and a View to the MultiView. The View is populated with a table->row->cell as in the above tutorial. In the cell, I add the list title and a CheckBoxList data bound to the list of strings.
So far so good, but when I click on a tab (or one of the checkboxes, etc) and there is a postback or something like that (the screen flashes as the site redraws itself), there is now a duplicate set of MenuItems immediately after the original. Each time I click on a tab or checkbox, another set of menu items are added.
I clear the MenuItem's Items list prior to building the controls and I verify that the controls hierarchy is structurally as expected after the control construction. Yet when one of my callbacks is called, my MenuItem list magically has some items added to it. None of my other controls appear affected at all. As a hack, I can remove the duplicates manually in my menu's OnMenuItemClick event, but I'd have to do the same in any of the callbacks I receive. Obviously I'd rather prevent this from happening. This has me stumped and I haven't been able to find anything online about it. Why would one set of controls have some content duplicated, yet every other control maintain its state correctly? My code is really simple so there isn't a way to add additional menu items without also adding the views. Anyway, there are a correct number of items prior to clicking on the tab/checkbox, an additional set immediately following in the callback.
This is my first time using ASP.NET, so I'm learning as I go. :) Thanks!
My problem was that I was not testing for postback before creating the controls. The code below is working for me.
In my user control's code behind:
protected void OnInitComplete( EventArgs e )
{
if( !Page.IsPostBack )
{
CreateMyControls();
}
}

Different validation rules for different actions

I have a form that has 3 buttons on it: Save, Approve and Reject.
Now I need validate User's input differently based on what button has been clicked.
For example User should be able to Save the object even if most of the fields are empty but in order to Approve some fields are required.
One approach is to put validation to CanSave and CanApprove methods (the buttons are bound to ICommand in the ViewModel). The problem here that buttons get disabled but there is no indication of which fields are required to fill to enable particular button.
Ideally all buttons should be enabled all the time and perform validation when the button is clicked. But how do I mark fields as invalid from VM?
Try adding something like a LastStateValidated property on your class and base your IDataErrorInfo validation off that value.
This means that the first time you load the form, the validation that appears will only be the ones that are in effect regardless of the object's state.
When you try and execute a command, the State changes and this will make IDataErrorInfo validate differently, so different validation errors will show up based on what the last action was that the user tried executing.

C#: click (where applicable) versus validating event

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".

Group Textboxes to add them to a List from a Windows Form Application

I am working on a Windows Form Application and I want to allow the user to add groups of (2) data inputs - whether that is 2 textboxes or some other control. For each "set" they would be inputting text into each field. I would then iterate through each 'set' to a dictionary where one goes in as the key and the other the value. It will start with a default of 2 sets of inputs.
So my problem/question is:
1) Since I want to allow them to add a limit number of inputs (but unknown how many they will add), what would be the best control for doing this.
2) how do I group each 2 inputs together so I can add one field as the key and one as the value in a dictionary.
Any thoughts.
I would create a user control, put the two textboxes on it, with the designer names of KeyTextBox and ValueTextBox, then on the user control class, add two properties, one for the key and the other for the value.
Now let's say you have a "add text input Pair" button on your main form, and also an empty panel that will hold your list of buttons. In the code for that button you just new up an instance of your KeyValuePairTextBoxControl, then add it to the Panel's Controls collection.
Now whenever you want to create a dictionary based on these values you simply loop through the controls collection of that panel, and for each KeyValuePairTextBoxControl you can access it's key and value properties to place them in the dictionary.
You could also expose the text changed events of the textboxes through your user control and as you create each control you wire up some handler for these events so that you can refresh your dictionary each time.
You might be able to do this much cleaner with some data binding features, but generally that can get much more complicated depending on the details of what you want to do.

Confirmation on switching between tabs

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.

Categories

Resources