Linking controls in separate views - wpf

I have two separate views each containing a ScrollViewer. I want to slave one to the other in terms of scrolling. (Views are being injected using PRISM)
I can do this trivially if they are in the same view. However I seem to be stuck doing it between isolated views. (The views are isolated for a good reason... well I think!)
What I think I want to do is echo the ScrollViewer 'ScrollChangedEvent' to the ViewModel layer then use some linking service to pass a message to the 2nd ViewModel.
However I'm struggling to work out how to drive the 2nd ScrollViewer from the ViewModel without violating MVVM.
Sure I'm missing something obvious so a shove in the right direction would be greatly appreciated.
Thanks

There are several ways to go about this. One would be, as you suggested, to transfer the scroll change to the view model. From there you can use a loose pub/sub mechanism (such as Prism's Event Aggregator) or a shared object that is available to both view models to transmit the event from one view model to the other.
My recommendation would be to use Prism.
When the second view model receives the event, it can publish it to the view using another event the view can directly consume, or through a property (using an attached property you can bind to that calls ScrollViewer.ScrollToVerticalOffset)

Related

How to build re-usable user control, within a user control in WPF?

I'm using WPF with the WAF framework.
I have a piece of UI (let's say it collects the user credentials) that gets presented on multiple views (see image).
I figured, hey, this is reusable, let's put it in its own user control.
I can get everything working fine if I ignore the inner user control and just "flatten" it if you will, but trying to encapsulate it is making me wonder what the best approach is. Should this "credentials" user control have its own dedicated view model? Should it be exposing its data through dependency properties instead? What's the best approach?
I will need to expose the data collected from the credentials control to the view model of the outer user control.
Should this "credentials" user control have its own dedicated view model? Should it be exposing its data through dependency properties instead? What's the best approach?
A UserControl can serve two purposes -
If you want to use it as a "Control" - which is often the case in a situation like this, I would treat it as 100% view. As such, I would not make the UserControl have a ViewModel at all (at least not publically), and expose it's properties via Dependency Properties. This provides the most flexibility in terms of reuse, as the UserControl acts like any other FrameworkElement, and can be dropped in and bound to your own properties in your other location like any other control.
When a UserControl acts as a View for a ViewModel, however, things are different. Here, the goal isn't reuse, but separation of concerns between your View and VM.
This situation sounds more like the first - you want to have a control that can be reused in multiple locations. In this case, this basically becomes a view element.

How should I implement multiple views on the same data?

I have a MVVM/WPF based application that can have multiple workspaces (basically containing a TreeView) open at the same time that display and operate on the same data tree. I need to be able to expand and collapse and select the items in each workspace independently and I want to be able to drag and drop items between the two workspaces (e.g. for moving or duplicating items). I also need data virtualization in that the data is only loaded (in both views) when a tree item is expanded for the first time. There is also one workspace-wide details view that shows the details of the selected item of the workspace that currently has the focus. Workspace specific expansion and selection of items must also work programatically.
Could you layout a ruff design for a MVVM based application that embraces theses features? Should I create a separate ViewModel tree for each workspace and implement a Model-ViewModel mapper? Or should I have just one ViewModel tree with two Views? How does the details view know what is currently selected and what workspace has the focus? ...
So to rephrase my question: The Model instances displayed in each View are actually the same instances. But should the ViewModels be the same too? Or better: Could I possibly get away with that?
Also: Is there an open source application I could study that has most of these features? Could Prism or any other MVVM based framework do most of that work for me?
There is a direct correlation between View and ViewModel. The View shows a visual representation of the Model, hosted and "formatted" by the ViewModel.
Since you will have different Model (data) on each View, you need to have several instances of your ViewModel hosting each set of different data.
Now the question is: do your ViewModels share some entities or objects between them ?
If yes, could they change during your application lifetime, and do you want to see these changes in realtime in your TreeViews ?
You then have two options:
Directly bind the model to the View (if the model implements INotifyPropertyChanged) by exposing it through your ViewModel: then all your views will be automatically updated when a model property changes.
Create a component which supervises Model modifications and notify ViewModel exposing them.
The second solution is more pure than the first one because Models should be POCO and shouldn't implement some plumbing oriented-interface. ViewModel should handle the plumbing.
However it's more complicated to design, and 90% of the time, you will end-up saying "come on, just one little interface doesn't hurt" :)
For your details view. You can communicate between your TreeViewModel and your DetailViewModel using a mediator (Messenger in the MVVM Light Toolkit), which is basically a low-coupled event-oriented component. Or use a supervisor which is injected in all your ViewModel and notify them using events.
Speaking of MVVM framework, and for common architecture like the one you are describing, I would recommend the MVVM Light Toolkit.
Maybe I am missing something, but is it not possible to have 2 instances of the same View / ViewModel loaded with different data?

Wpf: datatemplates and event subscription management

Sometimes a Domain Model object with a business logic (DDD) when calling a method an event is fired.
In my situation, a viewmodel (for a given view) encapsulates the domain object and needs to register and react on those domain events (i must use events because that same domain object can be managed by many loosely coupled views along with their viewmodels).
I also need to unregister to those events when that particular context is hidden.
I can handle this register/unregister/dispose in parallel with show/hide/dispose of that view using databinding, programmatically or whatever if the scenario keeps simple enough...
The problem comes when visualization logic comes with DataTemplates.
How can I know when that datatemplate becomes hidden so that I can unregister my events? is it there a better way with wpf to handle this, instead of adding more events?
What is the best practice to handle this scenario in a good MVVM approach?
edit: ok, the problem is structural. sometimes choices made inside the project has forced us to work in an atypical manner... in a good mvvm approach this problem should not happen
I'd be careful in making the ViewModel dependent on the View for making things right.
So what I would do is provide a property (Show? Visible? Open?) on the ViewModel that has a TwoWay binding with the View so the ViewModel can monitor the property.

How to use a 3rd party control inside the viewmodel?

I have a 3rd party control which among other things performs loading of some data. I want my viewmodel to keep track of this load operation and adjust its own state accordingly.
If it were up to me, I'd do the data loading far away from the view, but it is not. So, I seem to be in the situation where my viewmodel depends on my view. How do I best handle this? I feel rather dirty making the view publish events to the viewmodel but I don't see any other reasonable way to get this info into the viewmodel.
A similar situation might crop up with standard controls, too - imagine if your viewmodel depends on the events coming from a MediaElement - how do you properly model this? Do you put the MediaElement into the viewmodel? That doesn't sound right.
If publishing the events to the viewmodel is indeed the most reasonable way, is there some common pattern used for this? How do you do it?
Generally, you would not allow your ViewModel to know details or even the type of your view controls. Having it respond to events is the cleaner way to go. There are a number of libraries that contain behaviors to map control events to ICommands on your ViewModel.
Caliburn is one such library. You can map control events to methods on your ViewModel.

Silverlight 3 LoadedEvent routed to ViewModel

My client is trying to hook to a usercontrols Loaded Event in the View Model. Basically they want to know when the controls loaded event triggers inside the view model. They are looking for a way to do it without code behind the xaml. Is this even feasible. I am looking into whether I can route the loaded event to the viewmodel in the xaml.
One way of doing it is to use InvokeDataCommand. You'd specify the trigger's EventName as Loaded, and then your command (defined in your VM) would execute when Loaded event is fired.
You need to look into commanding. Silverlight support is fairly weak compared to WPF but it does contain the ICommand interface. You can extend controls to give them command properties or implement them via an attached property. The commands basically invoke themselves once an action has occurred in the UI. They are totally independent of how the UI is built (or at least they should be) and so can be completely unit tested.

Resources