Runtime Conventions
Radical.Windows.Presentation
has a lot of runtime conventions mainly related to two different areas:
View – ViewModel relation;
UI Composition;
Runtime conventions are managed by the IConventionsHandler
interface, and allows to take full control of the following Radical behaviors:
ResolveViewModelType: The first convention is used internally by the ViewResolver and given the view type returns the ViewModel type for the given view, the default behavior is that the view model is in the same namespace of the view and has the same type name suffixed with “Model” (e.g.: MainView and MainViewModel).
ResolveViewType: The ResolveViewType convention is currently under development and not used, but basically does the opposite stuff, using the same default behavior, as the ResolveViewModelType convention. The toolkit utilizes a view first approach, thus resolving the view type given the view model type is not required, you can use this convention to implement a view model first based approach.
ViewReleaseHandler: the
ViewReleaseHandler
is called each time aView
should be released, this handler is responsible to release theView
and its associatedViewModel
if any. This handler also unsubscribe, if allowed by theShouldUnsubscribeViewModelOnRelease
convention, theViewModel
from all the subscriptions registered with theMessageBroker
.ShouldReleaseView: determines if a
View
should be released when required.ShouldUnsubscribeViewModelOnRelease: determines if
ViewModel
subscriptions should be unsubscribed at release time.ShouldUnregisterRegionManagerOfView: internally used by the UI Composition engine to determine if a region manager should be destroyed when the owner
View
is released, the default behavior is to destroy region managers only if theView
is not a singleton view.FindHostingWindowOf: This convention is currently used to find the Window that hosts a given view model. It is pretty useful to get a reference to the Window object that hosts, in its visual tree a View Model data bound to a UserControl.
This task is performed finding the current view of the given view model (using another convention) and then reverse walking the visual tree looking for the first Window object. The convention accomplish two needs:
A view model can implement the IExpectViewClosingCallback and the IExpectViewClosedCallback (and other *Callback(s)) in order to intercept the fact that the hosting Window is closing or has been closed and since we support UI Composition features a view model can be a view model attached to a UserControl that is runtime “inserted” into the visual tree of an existing Window;
The UI Composition region service, in order to satisfy the above requirement, each time setups a new region need to find the hosting window in order to attach the closing and closed events;
ViewModels as resources: there are scenarios in which it's handy to have the current
View
ViewModel
available in theView
resources. ShouldExposeViewModelAsStaticResource and ExposeViewModelAsStaticResource control if aViewModel
is exposed as a resource (false
by default) and how it is exposed. The default behavior, when this feature is active, is to register theViewModel
in the resources using itsType
name as the resource key.GenerateViewModelStaticResourceKey: The GenerateViewModelStaticResourceKey conventions is used to determine the resource key used to store ViewModel instances in View resources when exposing ViewModels as resources in Views.
ViewHasDataContext, SetViewDataContext and GetViewDataContext: The ViewHasDataContext convention simply checks if the given view DataContext property is not null, this convention accepts a DependencyObject because in WPF the DataContext property is not defined on a single root object but is defined on FrameworkElement and on FrameworkContentElement. SetViewDataContext and GetViewDataContext respectively sets and gets the DataContext of the given view.
Note:
The
ViewDataContextSearchBehavior
has been introduced to overcome an issue encountered due to the way dependency property value inheritance works. When using nested views, for example because one child view is loaded as a content injected into a region, if the nested view does not have a DataContext property (e.g. is a view without a ViewModel) its DataContext property value is inherited from the first element in the logical tree that has a DataContext assigned. This default WPF behavior was causing some subtle bugs in the way the Radical MVVM logic was working. The ViewDataContextSearchBehavior has been introduced to determine the way the MVVM engine will look for the ViewModel on a View, the default behavior, that can be controlled via theDefaultViewDataContextSearchBehavior
property, is to look only on the View DataContext property ignoring each inherited value.ShouldNotifyViewLoaded This convention is responsible to determine if a
View
should notify that is loaded broadcasting aViewLoaded
message. A view notifies that has been loaded in 2 cases:If the View contains a
Region
;If the View, or the associated ViewModel, is decorated with the
NotifyLoadedAttribute
;
The same logic applies to the ShouldNotifyViewModelLoaded convention for the ViewModel.
AttachViewToViewModel and GetViewOfViewModel: Internally the
Radical.Windows.Presentation
MVVM and UI Composition toolkit needs to know the runtime View – ViewModel relations in order to know that given a ViewModel instance the corresponding View instance is certainly a specific instance.To achieve that the
ViewResolver
once has resolved both the required instances calls theAttachViewToViewModel
convention in order to store the view reference in the view model instance (the view model is already stored in view instance using theDataContext
property).By design this works out-of-the-box because the
AbstractViewModel
type implements theIViewModel
interface that has aView
property internally used for this tasks. If the user does not like this behavior or cannot inherit from theAbstractViewModel
type, nor implement theIViewModel
interface, can replace this convention in order to store somewhere else the required relation (e.g. a statically defined dictionary).The same logic is used by the
GetViewOfViewModel
convention that is required to retrieve the stored relation.TryHookClosedEventOfHostOf: This is internal and is used by the region service engine to attach the closed event of the hosting window, if any, in order to cleanup stuff when the window is closed.
IsHostingView: The
IsHostingView
convention is internally used by theRegion
base class to determine if a given visual element can be considered a View.AttachViewBehaviors: The AttachViewBehaviors convention can be hooked by the framework user if there is a requirement to attach behaviors (
System.Windows.Interactivity.Behavior<T>
) whenever a view is resolved by the ViewResolver. By default the built-inViewResolver
attaches the following behaviors to each view:WindowLifecycleNotificationsBehavior;
FrameworkElementLifecycleNotificationsBehavior;
DependencyObjectCloseHandlerBehavior;
GenerateServiceStaticResourceKey: The GenerateServiceStaticResourceKey conventions is used to determine the key used whne registering services as resources, both at the application level or at the View level.
Last updated