View Injection Manager Concept

  • 5 min to read

The Concept of the View Injection Manager

The ViewInjectionService provides only a core set of methods and properties that allows you to integrate ViewModels (with their Views) to a component. To inject ViewModels and Views in a more convenient way, use the ViewInjectionManager. It allows you to perform injecting and manipulation under ViewModels and Views in any section of the application's code.

If your application contains several injectable controls, each of them should have a unique identifier specified using the ViewInjectionService's RegionName property. This property is used by the ViewInjectionManager to recognize controls (regions) that should be populated with ViewModels and Views.

<UserControl x:Class="DXSample.View.MainView"
    ...
    xmlns:dxwui="http://schemas.devexpress.com/winfx/2008/xaml/windowsui"
    xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
    xmlns:common="clr-namespace:DXSample.Common">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <dxui:TileBar Padding="10">
            <dxmvvm:Interaction.Behaviors>
                <dxmvvm:ViewInjectionService RegionName="{x:Static common:Regions.Navigation}" />
            </dxmvvm:Interaction.Behaviors>
        </dxui:TileBar>
        <dx:LoadingDecorator Grid.Row="1" >
            <dxwui:FlipView>
                <dxmvvm:Interaction.Behaviors>
                    <dxmvvm:ViewInjectionService RegionName="{x:Static common:Regions.Main}"/>
                </dxmvvm:Interaction.Behaviors>
            </dxwui:FlipView>
        </dx:LoadingDecorator>
    </Grid>
</UserControl>

The Regions is a simple static class.

public static class Regions {
    public static string Main { get { return "MainRegion"; } }
    public static string Navigation { get { return "NavigationRegion"; } }
}

The ViewInjectionManager uses its own ViewInjectionManager.Inject methods.

public static class ViewInjectionManagerExtensions {
    public static void Inject(this IViewInjectionManager service, string regionName, object key, Func<object> viewModelFactory);
    public static void Inject(this IViewInjectionManager service, string regionName, object key, Func<object> viewModelFactory, string viewName);
    public static void Inject(this IViewInjectionManager service, string regionName, object key, Func<object> viewModelFactory, Type viewType);
    ...
}
  • The first method overload injects a ViewModel (viewModelFactory) marked with a unique identifier (key) to the specific region (regionName) and uses the view from the control's ItemTemplate or ContentTemplate (it depends on the control they are populated from.).
  • The other two method overloads inject a ViewModel (viewModelFactory) marked with a unique identifier (key) to the specific region (regionName) and use the View (viewName or viewType argument) created using the ViewLocator.

Below is a list of method parameters.

  • The property regionName specifies the region name (identifier).
  • The key property specifies the identifier of the View and its ViewModel
  • The viewModelFactory property specifies the ViewModel factory that is invoked when its region is shown
  • Then, the viewName or viewType properties specify the view that will be created using the ViewLocator.

To navigate between injected ViewModels and Views, use the ViewInjectionManager.Navigate method.

public class ViewInjectionManager : IViewInjectionManager {
    public virtual void Navigate(string regionName, object key) ;
    ...
}

To control when the ViewModel (with its View) becomes active, inactive or closed, the ViewInjectionManager provides the following methods.

public class ViewInjectionManager : IViewInjectionManager {
    public void RegisterNavigatedEventHandler(object viewModel, Action eventHandler);
    public void RegisterNavigatedAwayEventHandler(object viewModel, Action eventHandler);
    public void RegisterViewModelClosingEventHandler(object viewModel, Action<ViewModelClosingEventArgs> eventHandler);
    ...
}

To unregister event handlers, use the ViewInjectionManager.UnregisterNavigatedAwayEventHandler, ViewInjectionManager.UnregisterNavigatedEventHandler, ViewInjectionManager.UnregisterViewModelClosingEventHandler methods respectively.

public class ViewInjectionManager : IViewInjectionManager {
    ...
    public void UnregisterNavigatedEventHandler(object viewModel, Action eventHandler = null);
    public void UnregisterNavigatedAwayEventHandler(object viewModel, Action eventHandler = null);
    public void UnregisterViewModelClosingEventHandler(object viewModel, Action<ViewModelClosingEventArgs> eventHandler = null);
}

To manually invoke an event, you can use one of the Raise* methods.

public class ViewInjectionManager : IViewInjectionManager {
    public void RaiseNavigatedEvent(object viewModel);
    public void RaiseNavigatedAwayEvent(object viewModel);
    public void RaiseViewModelClosingEvent(ViewModelClosingEventArgs e);
    ...
}
See Also