Appropriate layer for a DocumentPaginator - wpf

I created a generic Paginator that leverages some Attributes to paginate an IEnumerable of any given type.
At first I placed it in my services project, but now I'm not sure anymore, since afaik every service has to expose an interface, and in this case the DocumentPaginator doesn't. Also, the paginator exposes a GetPage method that returns a DocumentPage, that is actually a View object. Am I wrong? If not, then it must be placed in the Views project.
So I thought an idea may be to create a UserControl (View) or a CustomControl, something like the PrintDialog, that contains all the "preview and print" logic.
What do you think?
Thank you guys!

Related

WPF - How to run a method of a custom control from a view model?

I work on a custom WPF Diagram Control. The control has a method that arranges the elements in the Diagram and I need to add MVVM support to call this method from my View Model.
At the moment I am a bit confused how to implement this and I hope that someome can point me to the right direction.
Maybe you need to rethink your concept. What needs to be re-aranged?
Think of ViewModel the logic behind a view and the view should be as dump as possible without any logic.
I assume also that the "arranges" method should be well tested and this could also be "easier" done on a ViewModel (if done right). Your best bet would be to place all logic in the ViewModel.
From the top of my head I could think of a DiagramViewModel with an ObservableCollection<ShapeViewModel>. ShapeViewModel can either be a base class or a concrete class which could also have some information about the location of the shape etc. The communication between the view models can be done via a Messenger (MVVM Light Messenger) or EventAggregator https://msdn.microsoft.com/en-us/library/ff921122.aspx.
If you still want to leave your architecture as you have it and want to execute a method on the view I would abstract it in a service. IDiagramUpdateService.
Look at following article which gives you good insights in communication between views and view models (and vice versa).
https://msdn.microsoft.com/en-us/magazine/jj694937.aspx
You'll find great information for both approaches.
HTH
Thanks for the quick response to my question.
I think my concept was a bit wrong, since the ViewModel should have no reference to the View.
What I would like to achieve is that I can place a button in the Main Window that calls the Arrange Method in the Custom Control.
I realized this by adding a RoutedCommand to my Custom Control.
And the Command Property of the button on the main window is bound to this RoutedCommand.
So the ViewModel is no longer involved in calling this method. It just manages the items that are shown in the Custom Control.

ViewModel-first approach to Silverlight navigation

I am looking for a truly decoupled way of supporting navigation in a Silverlight application using MVVM. I am trying to accomplish more of a "purist" implementation of the pattern where the UI is completely separated from the ViewModels so that the application can actually run entirely without a UI. To do this, I need to support navigation without UI concerns.
I have several ideas how to accomplish this (with Messaging, etc) but haven't come up with a good way of "mapping" the View to the ViewModel so that the UI can show the appropriate View when the ViewModel is "displayed". I recall coming across an article some time ago that described a solution to this very problem but can't seem to locate it online anymore.
Does anyone know how to find this article or have any experience solving this problem?
So here's my somewhat long-winded description what we ended up doing:
First, we decided to use the built-in Page Navigation framework. We had multiple reasons but since it is built-in and is also the navigation framework du jour in Windows 8, we opted to try this approach.
I should also mention that we use MVVM Light and MEF in our applications. (This comes into play below.)
To make this work, we created an application Shell (UserControl) that contains the Frame control. The Shell's DataContext is set to an instance of the ShellViewModel which exposes a single CurrentPage property (of type String). We then bind the Frame's Source property to CurrentPage. This approach is similar to Rachel's app-level ViewModel.
The ShellViewModel registers with the Messenger to receive CurrentPageChanged messages. When the message is received, the CurrentPage property is updated, the PropertyChanged event raised and the UI updated. The message originates from the NavigationService (which implements INavigationService and is injected/imported using MEF).
The NavigationService exposes a NavigateTo method which accepts the string name of the ViewModel representing the destination. This name matches the contract name applied to the ViewModel when exported (using MEF) and used to lookup the instance using our ViewModelLocator.
In the NavigateTo method, we use the ViewModelLocator to retrieve the ViewModel instance, call Deactivate on the current ViewModel (if one), call Activate on the new ViewModel then send the CurrentPageChanged message with the name of the new view as a parameter. Activate/Deactivate are helper methods on the ViewModels that allow us to perform any necessary tasks when the ViewModel is navigated to or from.
This appears to be working well and gives us a very MVVM-ish implementation with all navigation isolated from our ViewModels via the INavigationService and messaging.
The only down-side right now is that while we are using string constants in code to represent the ViewModel names, we are still hard-coding the strings in the Views to set the DataContext. I will be looking into a way to set the DataContext automatically as part of the navigation 'tooling'.
I should mention that this approach was parsed together from a number of sources, including (but not limited to) Rachel and the following links:
http://blogs.microsoft.co.il/blogs/eladkatz/archive/2011/01/25/adapting-silverlight-navigation-to-mvvm.aspx
http://blog.galasoft.ch/archive/2011/01/06/navigation-in-a-wp7-application-with-mvvm-light.aspx
http://www.geoffhudik.com/tech/2010/10/10/another-wp7-navigation-approach-with-mvvm.html
Usually I have a ViewModel for the entire app, and it contains the CurrentPage and all navigation event handling.
On the View side, I use a ContentControl with it's Content bound to CurrentPage, and use a DataTemplateSelector to determine which View to display for which ViewModel
There's an example here if you're interested, although it uses DataTemplates instead of a DataTemplateSelector.

Is it right to call Navigate to other page from ViewModel?

I know there is many ways to Navigate to other page from ViewModel.
I'm not sure is this a good idea or not, since MVVM's purpose is to separate View from ViewModel, but Navigate to other page within ViewModel mean there's a couple between View and ViewModel, that being said, if I change View name, I need to change URI (string) in ViewModel too.
I want to know, is it right to call Navigate to other page from ViewModel? If it's wrong, what's the correct (or better) way to navigate to other page?
It's both right and natural.
When you make a navigation request, the "name" you provide as part of the Uri is the name with which your View class has been registered in the container. Since registering classes with the container is done by the module itself and not the View or the ViewModel, you are not introducing coupling between the View and ViewModel.
That said, if you want to customize the way that Prism interprets your navigation requests, you can always write a class implementing IRegionNavigationContentLoader. If you register this into the container, Prism will resolve your own class instead of the built-in RegionNavigationContentLoader. But it's not the simplest thing in the world to do.
Why don't you create a separate class that will keep the logic for navigation? In that case you'll only need to send a message from ViewModel that program should change the View and details would be decided arbitrally. With that approach you still have no direct connection between View and VM

How to call a user control method using MVVM?

I'm working in a WPF project, I'm using the MVVM patter in my project.
I created a user control (also in WPF) and I want to use it in my project, now, my problem is that I have a method in my user control that I need to call from my View Model, but I don't know how to do that, how to bind to the method inside my control from the view model.
If I use code behind, obviously there is no problem since I have a direct reference to my control, so I can do "mycontrol.MyMethod();"m, but of course, doing in this way will go against the logic of the MVVM pattern.
I tried to use a Dependency Property in my user control, and use that Dependency Property to bind to it in the xaml of my project but it didn't worked, the compiler says that the property was not found or is not serializable.
So I will appreciate if someone can share some light about how can I accomplish this.
Edited
As far as I understand you have the view, which is all the GUI, then you have the model, which is all the logic, and them you have the view-model which is like an intermediate layer used to bind the view with the model, right?
In this way I have developed my project, however I came to the problem that I need a custom control, a TextBox that remember what the user entered, and when he start typing, if there are words that start with that letter, those words are shown as a suggestion, as Google does it.
This TextBox is used as a search filter; so I created a user control to do this, I added a method to my user control to allow whatever application that uses my control to add items to an internal array that holds all the strings that the user has entered.
I created a user control because I couldn't find any control that behaves the way I want.
So my problem is when I add my user control to the main project, because I need to someway be able to call the method that add the items to the internal array, but maybe I'm doing things the wrong way, so if any of you has a better idea, I will appreciate if you shared it with me.
You should never call View methods from ViewModel, and vice versa.
Make a property (ObservableCollection?) on your ViewModel, it will have CollectionChanged event, subscribe to it to monitor changes (if needed).
When you add an item to the collection in your ViewModel, GUI will be updated accordingly (you have to perform the Add() operation on GUI thread, btw).
If you need to change the current position in your list, there are colections for that (CollectionViewSource, etc).
If you really really need to pass a string to your control, make a DependencyProperty and bind it OneWay to your ViewModel's property. When you set the value, it will call PropertyChangedCallback on your DependencyProperty.
Why does the consumer of the user control need to maintain the control's internal array? That seems like you've exposed an implementation detail that you don't need to.
Why not simply make that array a dependency property (and an IEnumerable<string> or ObservableCollection<string> besides)? Then you can simply create the corresponding property in your view model and bind it to the control. It also makes the control considerably more versatile.
You shouldn't call something in the View from the ViewModel since that breaks the model.
If the reason you want to call the method in the user control is to do with UI only, I don't see anything wrong with doing it from the view - the view's cs and the view's xaml are in the same "space" in the model. You can be overly-purist in wanting to have lean and mean view cs files.

Where do I instantiate my Objects in CRUD n-Tiered WinForm App?

Say I have a WinForm CRUD(like) application. I want to follow best practices on this so I try and make it follow OOP and a n-Tiered design.
Unfortunately I am familar with the words but not the practice of them. So lets go with the following example: My CaseNote program. I have a tabbed application where you go to the search tab to find a member and then one of the options is to go to the CaseNote tab to create a new case note, look at existing CaseNotes, or create a follow up CaseNote to a Parent Note. All of this is for the member you selected from the search tab.
So if I am creating objects and passing them around to be used by different forms where should I be instantiating them? I had thought I would have 3 layers; UI, Object, DAL. Where I fall flat is where I instance tho objects. I can't instance them in the object layer, can I? Also, if I instance them on the form how do I pass them from form to form in a quite large app?
CaseNotes Screen Shot
If you want to look at some more words around this problem you want to look at MVP and MVC. (These stand for Model View Controller and Model View Presenter). Some people will shoot me down for saying this but they are quite similar in concept.
The aim of MVP and MVC is to allow you to design your application logic without even having to think about your application apperance. It also allows you to define your user interactions without implementing an actual GUI. Esentially your model is your application logic, your data, your classes which actually do stuff like talk to your database. Your presenter or controller is what interacts with your model and what controls your user interface and reacts to user operations on the interface. Finally your View is your winforms design or your web page.
I'm sure you will be able to find plenty of material on the web about this but to give you some concrete help with this problem should serve to inform and illustrate your reading.
The first thing you need to do is start creating your objects that represent your data. So you will have a CaseNote object which is contains the casenote data. You will have a case note data container of some sort such as a case note database. You can define the logical operations and properties of these as if they where real items.
Then you would move on to define your presenter or controller which will define the operations that you want to support from the GUI. At the same time you should define an Interface that will define for the presenter/controller what operations is can perform on the GUI. So for instance your presenter may expose a method called SearchForCaseNote which takes a string parameter. Your view Interface will expose a method called DisplayCaseNote. When a user clicks on the search button the view will pass through the command to the presenter which will then call the model to get the data. The presenter may format the data at this point, i.e. convert DateTime object to a string and then pass the data back to the view through the interface define method called DisplayCaseNote.
You don't have to use the View interface, you could call into the view directly, but having the interface means you can have many different view implementations.
One last thing i need to mention is where you create these different parts of your application. My view is everything thing should fall out from the presenter/controller. So when you application starts it creates the presenter/controller object which then create and displays your view passing itself as a variable to the view. The presenter/controller can then either create the initial models by loading them from disk or ideally discover them through a dependency injection container like unity. In fact using unity to discover the view implementation is probably a better idea again as it gives you true seperation between view and presenter/controller. When you come to move to another view, (i.e. open another window), your presenter/controller should expose a method such as DisplayDetailPage which the view calls when a button is clicked. This would create the presenter/controller for the next view which would in turn create the view and get a reference to the model.
Hope this helps.
I think you should use the RocketFramework

Resources