Refactoring Form.ShowDialog() code to MVP - winforms

I have a WinForm and few properties that are set on it.
for example : Name,Address are accepted on the Form.
(many more properties in actual example)
The current implementation is somewhat similar to
frmName frmView = new frmName (); //frmName is WINFORM
frmView.Name= "ABC"; //any valid string or read this from file
frmView.Address="SomeAddress"; //any valid address or read this from file
if (frmView.ShowDialog() == DialogResult.OK)
{
//OK CLICK PROCESS and
// get new values edited by user
string name = frmView .Name;
string address = frmView.Address;
doProcessing(name,address);
}
else{
//Ignore cancel click..
}
how do i convert this to a MVP based Winform application.
Also need to refactor the processing done on ShowDialog() to the Presenter/Model
(dunno exactly where to do it)?
Also need to avoid writing code on the form itself.(Passive view)
Thanks All.

I'm still experimenting with different MVP approaches myself, but the way I'm currently doing it is like so:
frmName frmView = new frmName();
if (frmView.ShowDialog() == DialogResult.OK) {
presenter.RequestProcessing(frmView.Name, frmView.Address);
} else {
//Ignore cancel click..
}
You say you want to avoid writing any code on the form itself, but this doesn't make sense to me. In Passive View, you pass on all application-specific requests to the controller or presenter.
In this example, the view handles view-related logic. Opening the dialog box isn't a user action that anything else (such as the presenter) needs to be informed about. Just like opening a context menu, a dialog box is part of how this particular view chooses to offer those application-specific requests to the user. Until the user actually goes through with it and submits the request, the presenter doesn't need to know anything.
In some circumstances where I've needed to be able to handle errors within the dialog box itself, I've passed the IPresenter object into the dialog box's constructor. It can then make the appropriate presenter request itself when the "OK" button is clicked, for example, and can show a message box instead of closing in case of an error.
There are a lot of variations on MVP, but I hope this helps. Good luck with setting it up.

Related

Dynamic validation within the model in CakePHP

Within a CREATE operation using the model validation and the "isUnique" rule, I check whether a specific value already exists in the database.
My application is a dictionary. In some cases it IS necessary to skip that validation and to allow the application to create more than one entry for one and the same word. Therefore I need a way to manipulate the validation as follows:
The validation returns an error message, as usual. In addition, there should be displayed a checkbox with a label that says something like "I confirm I want create another entry for this word" If I check the checkbox and submit the form again, then the validation should return true and the word will be stored. If the checkbox remains unchecked, the validation will continue to return false.
I thought of something like this (it's only pseudo code to illustrate what I mean. I KNOW that this is not working PHP code)
function afterValidate() {
if ($this->validationErrors contains the observed field) {
if ($this->data does NOT contain the extra checkbox) {
extend $this->data with an extra checkbox;
}
else {
if (extra checkbox is checked) {
force validation to return true;
save record;
}
}
}
}
Unfortunately, I can't get it working in my model!
My first obstacle is on the second IF construct: How do I extend the data object within the model?
I can push stuff into it (my desired checkbox) and even see it, when I debug using the pr() command. But neither the Controller nor the View sees it: when I output the data object in the Controller or in the View it still contains the standard form fields but not the checkbox…?
I presume I could move the code to the Controller and get it working there, but I think it rather has to happen in the model since there is the afterValidate callback for post-processing data.
Thanks for hints!

ZK window not unique in ID space

In our project we use ZK for webpages. There is a combobox which has lists. When selected, it fetches data from a java object through onSelect, i have given the logic.
when i select one there are 4 listboxes on that page to be filled with data according to the selection. when i select first time, no problem occurs.
But on second time i get an error pop-up like "Not Unique in the id space of Window" and showing the list box item id which have to be filled on select.
Can any one help out there?
Note: Though it shows this error i get the listboxes filled correctly according to the combo box selection. Still i cant stop this error occurring..
Your issue is a conflict of ids in ZK's id space.
A bit of background..
ZK generates ids for components at runtime, if you open up the DOM in the browser you'll see each component has some machine readable id.
However, you can also give components an id. This id does not go to the DOM but lets you reference the component in your application.
These two shouldn't be confused. The conflict you're experiencing is with the latter type of id; you are assigning a component an id in your Java code or in your ZUL file which, at runtime, is not unique.
The case you describe where it only happens the second time you click is a tell tale sign here. The content you are adding on the event has an id defined in it and you are not removing this content when you are done.
Consider the following example:
#Wire
private Window myWindow;
#Listen(Events.ON_CLICK + " = #myButton")
public void onMyButtonClicked() {
Label myLabel = new Label("sean is cool");
myLabel.setId("myLabel");
myLabel.setParent(myWindow);
}
This will work the first time you click myButton, but will throw your error on the second click. That is because the second event tries to add myLabel to myWindow but there is already a myLabel there.
There are lots of ways to resolve this depending on what you are trying to do.
Have a look through the ZK documentation on ID Spaces for more.
I also faced the same error.
My scenario is the same, only the widgets being used are different.
Hence putting my workaround here.
I have put the following piece of code in the doBeforeCompose() method of the composer:
Component widgetWithId = page.getFellowIfAny("widgetWithId");
if (widgetWithId != null) {
widgetWithId.detach();
}
Here widgetWithId is the component/widget, which is tried to be regenerated by the code, with the same Id and ZK is throwing error for it.

Using cached data from child window in parent window without a trip to the database

I'm looking for a design approach, so I don't have any code to share.
I have a WPF rich-client application that presents detail data to the user. When the user clicks "Edit" The entire form goes into edit state. This reveals a couple of "Add" buttons. These "Add" buttons open child views providing the user with tools to create new entities. Think "adding a new item to a customer order you're working with". That's the easy part.
When the user closes these child views, the new entities must be displayed and editable in the parent view for continued detailed editing. Something like "add the new item on the child form, pick the part number, then close the child and add quantity and delivery date on the parent view. I don't have any flexibility in this workflow. I have this working also.
When the user is finished with the parent view and is satisfied with the newly added items and detail edits they can click "Save". That is when all the changes need to go back to the database. If the user clicks cancel, all the changes including entities created on the child views must disappear, and the form returned to it's original state.
It's that last bit that stumps me. I'm almost new to Entity Framework, so I thought I could somehow keep the entire set of changes in memory on the client and commit all the changes to the database at the point of user-Save. I don't know if that's possible, or how I have to impliment my data changes to prevent accidental trips to the database.
To put all the facts on the table, I'm using a unit of work pattern, but I have access to an EF context object, if needed. If I have to work with the context object, I must do so across several views and their associated view-models.
I've looked at a whole lot of stackoverflow Q&A but cannot find, or perhaps recognize, a solution path. I've some ideas about using cloned entities, or perhaps transactions, but do not know if there are others or how to choose between them. These would be new skills and require time spent learning. I am willing to spend time learning a new skill, but not learning and trying three or four.
I'm grateful for any advice you might offer.
On the constructor when read from the DB record the value twice. One private variable for current and one for Old.
private string lNameOld;
private string lName;
public string LName
{
get { return lName; }
set
{
if(lName == value) return;
lName = value;
NotifyPropertyChanged("LName");
}
}
public void save()
{
if (lName != lNameOld)
{
// write to database
// really should process all in a transaction
lNameOld = lName;
}
{
public void cancel()
{
if (lName != lNameOld)
{
Lname = lNameOld; // notice capital L so Notify is called
}
{

Windows Phone 7: Tombstoning with URIs?

I'm building a wp7 app in Silverlight. All of my app's state is stored in NavigationContext.QueryString. If this could be saved on application deactivation, and that page navigated to on application reactivation, that would take care of my requirements for tombstoning.
However, I'm not quite sure how to do this. I was thinking about saving NavigationContext.QueryString to the State dictionary in App.xaml.cs::Application_Deactivated(), but that code doesn't have access to NavigationContext.QueryString. Is there another way I can do this?
I suppose I could just save the query string to the State dictionary every time I navigate, then restore that when the app is re-activated. Or is there a better approach?
Update: Based on indyfromoz's answer, I'd like to implement the following
OnNavigatedToHandler()
{
// save NavigationContext.QueryString in the State dictionary
}
To reduce redundancy, I thought I'd implement this in a class that inherits from PhoneApplicationPage, then have all the rest of my pages inherit from that class. However, I then get the problem that all the page classes are partial because they are also defined in generated code. I don't want to change the generated code, because rechanging it every time it gets regenerated would be a huge pain.
Is there a better way to do this?
Update 2: Here is what I am hacking together now in the main page of my app (the one that is navigated to on startup):
public partial class MainPivot : PhoneApplicationPage
{
public MainPivot()
{
InitializeComponent();
Loaded += new RoutedEventHandler(MainPivot_Loaded);
PhoneApplicationService.Current.Deactivated += new EventHandler<DeactivatedEventArgs>(App_Deactivated);
MessageBox.Show("launching main pivot (state count: " + PhoneApplicationService.Current.State.Count + ")");
if (PhoneApplicationService.Current.State.Count != 0)
{
Debug.Assert(PhoneApplicationService.Current.State.ContainsKey(QueryStringKey),
"State is initialized, but contains no value for the query string");
string oldQueryString = (string)PhoneApplicationService.Current.State[QueryStringKey];
MessageBox.Show("Old query string: " + oldQueryString);
NavigationService.Navigate(new Uri(oldQueryString));
}
}
public readonly string QueryStringKey = "queryString";
void App_Deactivated(object sender, DeactivatedEventArgs e)
{
PhoneApplicationService.Current.State[QueryStringKey] = NavigationService.Source;
}
// ...
It works (sorta) but it's ugly.
Update 3: Looks like the wp7 OS will automatically reload the correct page in a page-based app. I am in fact using pages, so perhaps there's not that much work I need to do here.
However, it doesn't seem to be working. I launch the app, go to a page, hit "Start", then hit "Back". The screen says "Resuming..." but seems to hang there. Is my code supposed to be responding in some way at this point? Is there a way I can keep the debugger attached even after hitting "Start"?
Transient data is usually stored in the State dictionary provided by the PhoneApplicationService class. The data is stored in the OnNavigatedFrom event of the page and restored from the OnNavigatedTo event of the page. If you stored the parameters from the URI of the page in the state dictionary within the OnNavigatedFrom event that is available in every page of your application, you can implement the logic to read the parameters in the OnNavigatedTo event, thereby taking care of Tombstoning
HTH, indyfromoz

WPF IDataErrorInfo multiple field validation

What is a good way to integrate multiple field validation with IDataErrorInfo?
Let say that I have a dialog with 3 textboxes for ftp information
URL
Username
Password
I have put the Required attribute on the fields (assume a normal TextBox for the password).
I validate the ftp connection when the user press "OK". At the moment I show a dialog but it would be nice if I could trigger the Validation error style on ftp connection errors.
I have looked at Validation.MarkInvalid but don't understand how to use it.
var be = GetBindingExpression(xamlURLField);
Validation.MarkInvalid(be, new ValidationError(-- WhatValidationRuleToPutHere --, be, "Can't connect to ftp", null)
You are mixing concerns a little here. Validation is for validating user input on a basic level. Doing some post-verification should be handled differently and is generally more complex than you'd want to encompass in the area of "Validation". When something like this is hard, there is usually a reason and this is the reason.
I would treat trying to connect as a separate step in your user interaction and display a message manually.

Resources