I'm new at C#, WPF and MVVM pattern. Sorry for this quite long post, I am trying to set all my points of understanding (or non understanding).
After studying a lot of texts on the commanding mechanism provided by WPF and the MVVM pattern, I have a few problems getting my mind straight on how to use these things.
I understand that the commands provided for WPF allows to define multiple "calling points" for command logic that is held in a component of the visual tree. When a command is called, the call bubbles through the visual tree (starting at the command target or the focused element) until it bumps into an element holding a CommandBinding that defines where is the command logic.
What seems nice about that is that you can define public commands without specifying either the logic nor the calling points at first.
I also understand that following the MVVM pattern, the ViewModel of a View should handle the logic whereas the base WPF implemtentation of commands only allows visual elements to handle it because the call bubbles through the visual tree.
I then found that custom implementations such as Josh Smith's RelayCommand can be used in this case, as you bind a command called by an element of the view (button for example) to the RelayCommand object in the underlying ViewModel.
But then, I dont see how it's a command (by the definition of WPF commanding pattern) anymore since we're directly specifying an implementation that is referenced in the ViewModel. With this method, we loose all the benefits of being able to call a command from anywhere without knowing where the logic is implemented. In this case, why not directly use a Click event handler (for example) ?
Could someone explain me where I'm wrong ?
(thanks for those who read the post to the end !)
Regards.
NR
But then, I dont see how it's a command (by the definition of WPF commanding pattern) anymore since we're directly specifying an implementation that is referenced in the ViewModel.
This is still a command, and implements ICommand, but it's no longer taking advantage of the routing strategies built into WPF. It's a command, but no longer a RoutedCommand - so in a sense, you're right - it's not following the original concepts of WPF's routed commanding infrastructure, but it's still a command.
With this method, we loose all the benefits of being able to call a command from anywhere without knowing where the logic is implemented. In this case, why not directly use a Click event handler (for example) ?
You're still keeping the benefits of having the logic separated from the View. The View doesn't need to know how this is implemented, and the ViewModel can implement the command without knowing how the View will trigger it. The command can still come from a gesture, a button, etc - and be changed (completely within the XAML), without changing the logic and code at all.
Switching back to event handlers breaks this - if you use event handlers, changing the View's implementation requires updating the event handlers (code behind).
After some further research on how to use the original WPF command behaviour in a MVVM project, I found this link : http://matthamilton.net/commandbindings-with-mvvm !
From what I understand, it provides a way to "attach" to the view, CommandBindings handled by the viewmodel. This way, the viewmodel would be able to implement a commandbinding that would be discovered when the command call walks the visual tree.
Bye.
Related
I'm thinking about a platform-neutral (i.e. not .NET MEF) technique of implementing chain-of-responsibliity pattern using web services as the handlers. I want to be able to add more CoR handlers by deploying new services and not compiling new CoR code, just change configuration info. It seems the challenge will be managing the metadata about available handlers and ensuring the handlers are conforming to the interface.
My question: any ideas on how I can safely ensure:
1. The web services are implementing the interface
2. The web services are implementing the base class behavior, like calling the successor
Because, in compiled code, I can have type-safety and therefore know that any handlers have derived from the abstract base class that ensures the interface and behavior I want. That seems to be missing in the world of services.
This seems like a valid question, but a rather simple one.
You are still afforded the protection of the typing system, even if you are loading code later, at runtime, that the original code never saw before.
I would think the preferred approach here would be to have something like a properties file with a list of implementers (your chain). Then in the code, you are going to have to have a way to instantiate an instance of each handler at runtime to construct the chain. When you construct the instance, you will have to check its type. In Java, for instance, that would take the form of instanceof (abomination ordinarily, but you get a pass for loading scenarios), or isAssignableFrom. In Objective C, it's conformsToProtocol.
If it doesn't, it can't be used and you can spit an error out to the console.
I have read a lot of gwt-mvp questions that are asked here, but since i'm totally new to this design pattern I would like to ask some questions:
[1] The Activity-Place pattern is a different pattern than mvp?
[2] In the MVP pattern presenters contain the logic. Now the logic of the widgets/controls is defined in the Activities?
[3] The CustomPlace classes are fixed (as the Eclipse plugin constructs them) or can i put data/methods and what kind?
[4] What is the use of the Presenter interface inside a CustomView? What data/methods would make sense to add into it?
[5] I want to build an application that will use many data structures that will be saved into a database. I have read some other posts here and I will make the Model part of MVP live inside each Activity. So i think to create each time the data structures of each activity at start and load its values (if necessary from db) and will update the database after the user goes to another view. What do you think about this approach?
Let's start by debunking one myth: Activities/Places have nothing to do with MVP. Places is about navigation, Activities are about "componentizing" the UI wrt Places. On the other hand, MVP is a design pattern, it's about how to organize your code.
Many people are using their activities as their MVP-presenters, but it's not enforced. The GWT team is trying a new approach where the activity is distinct from the presenter (work underway in the mobilewebapp sample if you want to follow what's going on there). You could also have your activity being your view and making use of an "internal" presenter (similar to how Cell widgets work)
A Place is more or less a URL. You can put whatever you want in it. I'd suggest making places immutable though: build a Place, goTo it, make use of its properties to build your UI.
That's about MVP then. This is only needed to decouple your view and presenter, mostly to make mocking in unit tests easier (this is particularly of the view interface though, not much for the presenter one, unless writing a test harness for you views). In some cases, you might also want to use the same view with distinct presenters; they'll all implement the same interface so the view can talk back to them.
How about the closing of the window/tab? I'd rather use a periodic auto-save, or an explicit save button; and implement mayStop so it prompts the user when there are unsaved changes (similar to how most desktop office apps work —e.g. MS Word or LibreOffice—, and GMail if you try to navigate away before your mail draft is auto-saved)
The Activity-Place is an implementation of the pattern. Google introduced gwt-mvp pattern at Google IO, but only provided it's implementation as part of GWT about a year later.
Yes Activities contain business logic. No, widgets/controls usually do not contain any logic, they just fire events based on user action. The logic that acts upon those events is written by user and resides elsewhere.
I don't use Eclipse, so wouldn't know about Places generated by it. Normally custom Places can contain custom fields and methods. For example they can contain custom place token arguments, i.e. if place token is "#place:id1", than your custom Place could contain field holding this argument.
When View needs to call/access Activity, it does so via Presenter, which Activity implements. For example when user enters all data in a for and presses submit, then you could have a method in Presenter named submit(formData).
Preparing/loading data in activity.start(..) is a normal way of doing things. If particular activity is used a lot, then you might consider caching the data if appropriate.
I need a tutorial for the new GWT MVP framework which is presented here.
The description Google gives is a little bit short for me. What are the meanings of — and how do I use — the following?
Activities
Places
Eventbus
ClientFactory
PlaceHistoryMapper
ActivityMapper
Also, where are the models in this new framework?
Places
These are classes that encode information about where your program has navigated. You might make a Place that means, "I'm on the home screen," and another one that means "I'm editing the user with id 52384. I think a better name for these would be PlaceTags, because they are not actually a place themselves - they just indicate where your program is. The URL is hooked to Places in a PlaceHistoryMapper, in which you can say, "hey, #home should generate a HomeScreenPlace and #edituser:52384 should generate a EditUserPlace (maybe constructed with a field you set to 52384).
Activities
These start and stop your code. Each Activity has a start method that is called when appropriate. You determine what "when appropriate" means by making an ActivityMapper, which has a function called getActivity. getActivity accepts a Place, and you have to decide which Activity to return. If the Place is whatever you've coded to mean "I'm on the home screen," you might return a HomeScreenActivity, and if the Place means "I'm editing the client with id 523584," you might return a EditClientActivity. You can add methods or a constructor to an activity to pass in an id like 523584.
EventBus
This is an object the different parts of your program use to communicate. If you don't want to, you don't need to know very much about it - you can just plug it in where indicated in Google's documentation (that you linked to)
ClientFactory
This is a centralized object whose only responsibility is making other objects. You can also skip this concept if you want to simplify things - you'll just be missing out on the central organization of your objects. The advantage is that if you want to switch them out later for, say, a mobile version, or a mocked-up-for-testing version, you can do so all at once within a single place and the rest of your program doesn't have to change at all. You can also reuse the same objects easily when coordinating from a central place, so you don't have to re-create the whole main screen every time someone goes to #home.
Your Actual Program
All this stuff is just for navigation. Your models, views, and presenters are all set up in each Activitys start() method, which the framework calls when your app should navigate to a new place. In the start method you should start up your presenter (usually using a new instance) and start up your display (usually reusing an instance - the client factory is good for this). When you've created your display, you let the framework know by setting it as the widget for the AcceptsOneWidget that the framework passed into your start method.
This is incomplete, but a good supplement to the docs you mentioned: http://code.google.com/intl/de-DE/webtoolkit/doc/latest/DevGuideMvpActivitiesAndPlaces.html
I would also recommend you to carefully listen to the Google I/O presentations, they are a golden key to understand the GWT philosophy:
http://www.google.com/events/io/2010/
http://www.google.com/events/io/2009/
Specially these ones (try to keep a more holistic view of the MVP framework). They do not talk about the real GWT implementation but they give you basic knowledge of MVP. I still am an 8 months noob, so from noob to noob :)
Ray Ryan's overview of the MVP paradigm. Great resource (it was an enlightening for me).
http://www.google.com/events/io/2009/sessions/GoogleWebToolkitBestPractices.html
http://www.google.com/events/io/2010/sessions/architecting-production-gwt.html
Daniel Danilatos's testing for GWT. Here you will understand why all the fuzz for MVP!
http://www.google.com/events/io/2010/sessions/gwt-continuous-build-testing.html
Given the following scenario:
ViewModelA launches ViewModelB (via a common Controller, of course, that uses Ioc and DI to resolve the types needed).
ViewModelB needs to set a property value in ViewModelA.
Is it bad to simply inject ViewModelA into ViewModelB via constructor injection and just set the property directly?
Or…
Should a messaging system like the EventAggregator from Prism be used to handle all communication between ViewModels?
I like the injection approach because it’s easy, but my instincts are telling me I’m missing something. I call on your collective wisdom to help fill in my blind spot.
I consider it a code smell if you need two-way references. Often you can replace one of the references with an event.
Let ViewModelB raise an event that ViewModelA subscribes to. A complete messaging system like the one found in Prism is certainly an option, but in your scenario it sounds like a 'normal' event will do just fine.
I suggest you read this question (and my answer) since it's similar, but not exactly your problem. It does deal with communication of properties between parent/child ViewModel objects.
Let's look at a basic example:
ViewModelA is the parent and has to present the Sum of some property on B
ViewModelB is the child and has a property that needs summing
So the user makes a request to edit the property on B and the request succeeds, so B presumably changes the value of its property and fires a PropertyChanged event.
ViewModelA could subscribe to the events on all children, but having gone down that path, I don't like it. When children are added and removed, you have a lot of bookkeeping to do.
Injecting A into B is cleaner, but you still have a lot of bookkeeping to do. What if you have a "Clear Children" action on A? You have to remember to properly get rid of the parent relationship from B to A in all cases. Still it's better than events in my opinion because it's more explicit.
Personally I like the messaging idea. I'm more familiar with MVVM Light's messenger than Prism, but it's the same idea... a global message bus. At any time, any B can say "I changed my property!" and then A listens for the notification and does the computation itself. I think this is your cleanest solution with much less bookkeeping.
I suggest using a much lighter dedicated Messaging solution called "Light Message Bus". It is not part of any yet another ;-) MVVM framework, but independent component. And I got it working in no time in less than 3 minutes.
You might find the sample applications of the WPF Application Framework (WAF) useful. The ViewModels don't know about each other. The mediation between them is done by Controllers. This way you can prevent cyclic dependencies between ViewModel objects.
Looking into various MVVM frameworks for SL. In the Caliburn documentation I saw a code in a controller that calls MessageBox. Is this right or is this just for intro? Is there something like MessageBox service in Caliburn like in Chinch MVVM?
It's indeed introductive code, just to demonstrate that the controller method is actually executed. Yet, I agree on the issue you pointed out: the presence of raw UI code in the presenter could lead to an inappropriate mix of view concerns.
About the MessageBox service: in Caliburn v2 (trunk), ShellFramework module, there is a Question/Answer ViewModel abstracting the functionality of a MessageBox, with the advantage of letting you to design the UI for the dialog.
Also, it's very straightforward to roll your own IMessageBox abstraction and provide a basic implementation using the default WPF MessageBox.
Marco is correct. This is just to demonstrate that the action is called. I wouldn't recommend this in practice. I will try to make some changes to the samples or add some comments that make this clearer. Caliburn has services built-in for calling custom message boxes.