Quantcast
Channel: patterns & practices: Prism
Viewing all articles
Browse latest Browse all 1878

New Post: Activate existing view with Event driven design

$
0
0

Hi,

As far as I know, Prism does not provide functionality to activate the parent views when an inner view is activated. In fact, with Regions, Prism aims to compose the user interface without needing the views to know each other. Hence, Prism does not even provide any functionality to obtain a view's parent.

Based on this, climbing up the visual tree and activating corresponding views would require to implement your own custom functionality not only to activate the views; but to find them, their Regions and their RegionsManagers too. Therefore, I believe it would be simpler to activate the top view first and then start activating the inner views up to the required one. In order to do this, you would need to have the information to know which views you need to activate. Then, for example, you could activate the top view and check the views of its Regions to check if it contains a view that needs to be activated. This inner view that was activated could repeat the process with its inner views and so on.

On the other hand, if you want to have a re-usable functionality that could be used to activate directly an inner view and their parents, regardless of the cost of implementing this functionality, I believe you could use an approach like the following one:

First you will need some infrastructure in your views / view models to support this kind of scenario. For this example, we will use the ViewModelBase class that I saw in one of your previous samples which defines a BaseRegionManager property where the scoped RegionManager is stored. Also, we will define an interface (lets call it IActivateVisualTree) that defines an ActivateVisualTree method. This interface could be implemented in your views.

Second, you will need a service in charge of activating the view and its corresponding tree. This service could be either a simple static class or a shared service registered in the container. How to implement it would depend mostly of your personal preferences. This service could for example expose a single static method that could then be invoked when needed to do the job. In this example, it will be invoked inside the implementation of the ActivateVisualTree method that we defined before for each view:

// Some view 's code...
ActivateVisualTree()
{
    // The service...
    VisualTreeActivator.Activate(this);
}
Hence, when you need to activate an specific view, you could cast the view to an IActivateVisualTree object and invoke the ActivateVisualTree method. By doing this, neither the code that requests the view to be activated or the view itself need to know how to activate the visual tree; that will be the responsibility of the service.

The complex part here is the implementation of the aforementioned service. Based on my understanding the service will need to do something similar to the following steps to activate the visual tree involved:

  1. Taking the view passed as a parameter, start climbing up the visual tree until you find a element with a DataContext of type ViewModelBase. Then, obtain the RegionManager contained in the BaseRegionManager property. This should be the RegionManager that contains the Region where the view is injected. (I believe you could find the code in the RegionManagerRegistrationBehavior class provided by Prism useful to implement your own logic to climb up the visual tree.)
  2. Again, taking the view as a base, start climbing up the visual tree until you find an element that has a RegionManager.RegionNameProperty attached to it. You can use the GetRegionName static method of the RegionManager class to check for the aforementioned property. Once found, save the Region's name. It should be the name of the Region where the view is injected.
  3. Obtain the Region from the RegionManager found in step 1. To do so, use the Region's name obtained in step 2. With this you should have the Region where the view is injected.
  4. Activate the view using the Activate method of the Region obtained in step 3.
  5. Finally, in order to activate the parent views, climb up the visual tree again until you find an element that implements our IActivateVisualTree interface. Once found, stop climbing and invoke the ActivateVisualTree method of this element.

So, when you need to activate an specific view and their parents, you would only need to invoke its ActivateViewTree method. This method consumes the service that will activate the view and invoke the ActivateVisualTree method on the parent view, activating all the views "recursively" until no parent that implements the IActivateVisualTree interface is found.

Take into account that we haven't tested this approach, and that it's only one possible approach to implement the functionality you are mentioning. Again, how to implement this will depend mostly of your personal preferences and the requirements of your scenario.

Finally, I would like to mention that this approach might not be useful if you have DataTemplates in your visual tree, as a DataTemplate is not a FrameworkElement and it has no Parent property you can use to climb up.

I hope this helps,

Damian Cherubini
http://blogs.southworks.net/dcherubini


Viewing all articles
Browse latest Browse all 1878

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>