As the user interacts with a rich client application, its user interface (UI) will be continuously updated to reflect the current task and data that the user is working on. The UI may undergo considerable changes over time as the user interacts with and completes various tasks within the application. The process by which the application coordinates these UI changes is often referred to as navigation. This topic describes how to implement navigation for composite Model-View-ViewModel (MVVM) applications using the Prism library.
Frequently, navigation means that certain controls in the UI are removed, while other controls are added. In other cases, navigation may mean that the visual state of one or more existing controls is updated—for example, some controls may be simply hidden or collapsed, while other controls are shown or expanded. Similarly, navigation may mean that the data being displayed by a control is updated to reflect the current state of the application—for example, in a master-detail scenario, the data displayed in the detail view will be updated based on the currently selected item in the master view. All of these scenarios can be considered navigation because the user interface is updated to reflect the user's current task and the application's current state.
Navigation within an application can result from the user's interaction with the UI (via mouse events or other UI gestures) or from the application itself as a result of internal logic-driven state changes. In some cases, navigation may involve very simple UI updates that require no custom application logic. In other cases, the application may implement complex logic to programmatically control navigation to ensure that certain business rules are enforced—for example, the application may not allow the user to navigate away from a certain form without first ensuring that the data entered is correct.
Implementing the required navigation behavior in a Windows Presentation Foundation (WPF) application can often be relatively straightforward because it provides direct support for navigation. However, navigation can be more complex to implement in applications that use the Model-View-ViewModel (MVVM) pattern or in composite applications that use multiple loosely-coupled modules. Prism provides guidance on implementing navigation in these situations.
Navigation is defined as the process by which the application coordinates changes to its UI as a result of the user's interaction with the application or internal application state changes.
UI updates can be accomplished by adding or removing elements from the application's visual tree, or by applying state changes to existing elements within the visual tree. WPF is a very flexible platform, and it is often possible to implement a particular navigation scenario using this approach. However, the approach that will be most appropriate for your application depends on multiple factors.
Prism differentiates between the two styles of navigation described earlier. Navigation accomplished via state changes to existing controls in the visual tree is referred to as state-based navigation. Navigation accomplished via the addition or removal of elements from the visual tree is referred to as view-based navigation. Prism provides guidance on implementing both styles of navigation, focusing on the case where the application is using the Model-View-ViewModel (MVVM) pattern to separate the UI (encapsulated in the view) from the presentation logic and data (encapsulated in the view model).
In state-based navigation, the view that represents the UI is updated either through state changes in the view model or through the user's interaction within the view itself. In this style of navigation, instead of replacing the view with another view, the view's state is changed. Depending on how the view's state is changed, the updated UI may feel to the user like navigation.
The view needs to display the same data or functionality in different styles or formats.
The view needs to change its layout or style based on the underlying state of the view model.
The view needs to initiate limited modal or non-modal interaction with the user within the context of the view.
This style of navigation is not suitable for situations in which the UI has to present different data to the user or when the user has to perform a different task. In these situations, it is better to implement separate views (and view models) to represent the data or task, and then to navigate between them using view-based navigation, as described later on in this topic. Similarly, this style of navigation is not suitable if the number of UI state changes required to implement the navigation are overly complex because the view's definition can become large and difficult to maintain. In this case, it is better to implement the navigation across separate views by using view-based navigation.
The following sections describe the typical situations in which state-based navigation can be used. Each of these sections refers to the State-Based Navigation QuickStart, which implements an instant messaging–style application that allows users to manage and chat with their contacts.
Your application may often need to present the same data to the user, but in different formats or styles. In this case, you can use a state-based navigation within the view to switch between the different styles, potentially using an animated transition between them. For example, the State-Based Navigation QuickStart allows users to choose how their contacts are displayed—either as a simple text list or as avatars (icons). Users can switch between these visual representations by clicking the List button or the Avatars button. The view provides an animated transition between the two representations, as shown in the following illustration.
Because the view is presenting the same data, but in a different visual representation, the view model is not required to be involved in the navigation between representations. In this case, navigation is entirely handled within the view itself. This approach provides the UI designer with a lot of flexibility to design a compelling user experience without requiring changes to the application's code.
Blend behaviors provide a good way to implement this style of navigation within a view. The State-Based Navigation QuickStart application uses Blend's DataStateBehavior data-bound to a radio button to switch between two visual states that are defined using the visual state manager, one button to show the contacts as a list and one button to show the contacts as icons.
As the user clicks the Contacts or Avatar radio buttons, the visual state is toggled between the ShowAsList visual state and the ShowAsIcons visual state. The flip transition animation between these states is also defined using the visual state manager.
Another example of this style of navigation is shown by the State-Based Navigation QuickStart application when the user switches to the details views for the currently selected contact. The following illustration shows an example of this.
Again, this can be easily implemented using the Blend DataStateBehavior; however, this time it is bound to the ShowDetails property on the view model, which toggles between the ShowDetails and ShowContacts visual states using a flip transition animation.
Similarly, the view within an application may sometimes need to change its layout or style based on changes to an internal application state, which in turn is represented by a property on a view model. An example of this scenario is shown in the State-Based Navigation QuickStart where the user's connection status is represented on the Chat view model class using a ConnectionStatus property. As the user's connection status changes, the view is informed (via a property change notification event) allowing the view to visually represent the current connection state appropriately, as shown in the following illustration.
To implement this, the view defines a DataStateBehavior data bound to the view model's ConnectionStatus property to toggle between the appropriate visual states.
Note that the connection state can be changed by the user via the UI or by the application according to some internal logic or event. For example, the application may move to an "unavailable" state if the user does not interact with the view within a certain time period or when the user's calendar indicates that he or she is in a meeting. The State-Based Navigation QuickStart simulates this scenario by switching the connection status randomly using a timer. When the connection status is changed, the property on the view model is updated, and the view is informed via a property changed event. The UI is then updated to reflect the current connection status.
All the preceding examples involve defining visual states in the view and switching between them as a result of the user's interaction with the view or via changes in properties defined by the view model. This approach allows the UI designer to implement navigation-like visual behavior in the view without requiring the view to be replaced or requiring any code changes to the application's code. This approach is suitable when the view is required to render the same data in different styles or layouts. It is not suitable for situations in which the user is to be presented with different data or application functionality or when navigating to a different part of the application.
Frequently, an application will need to interact with the user in a limited way. In these situations, it is often more appropriate to interact with the user within the context of the current view, instead of navigating to a new view. For example, in the State-Based Navigation QuickStart, the user is able to send a message to a contact by clicking the Send Message button. The view then displays a pop-up window that allows the user to type the message, as shown in the following illustration. Because this interaction with the user is limited and logically takes place within the context of the parent view, it can be easily implemented as state-based navigation.
Interacting with the user using a pop-up window in the State-Based Navigation QuickStart To implement this behavior, the State-Based Navigation QuickStart implements a SendMessage command, which is bound to the Send Message button. When this command is invoked, the view model interacts with the view to display the pop-up window. This is achieved using the Interaction Request pattern described in Implementing the MVVM Pattern.
The following code example shows how the view in the State-Based Navigation QuickStart application responds to the SendMessageRequest interaction request object provided by the view model. When the request event is received, the SendMessageChildWindow is displayed as a popup window.
Although state-based navigation can be useful for the scenarios outlined earlier, navigation within an application will most often be accomplished by replacing one view within the application's UI with another. In Prism, this style of navigation is referred to as view-based navigation.
The target of the navigation—the container or host control of the views to be added or removed—may handle navigation differently as views are added or removed from it, or they may visually represent navigation in different ways. In many cases, the navigation target will be a simple Frame or ContentControl, and navigated views will simply be displayed within these controls. However, there are many scenarios where the target for the navigation operation is a different type of container control, such as a TabControl or a ListBox control. In these cases, navigation may require the activation or selection of an existing view or the addition of new view is a specific way.
The application will also often have to define how the view to be navigated to is identified. For example, in a web application, the page to be navigated to is often directly identified by a Uniform Resource Identifier (URI). In a client application, the view can be identified by type name, resource location, or in a variety of different ways. Furthermore, in a composite application, which is composed from loosely coupled modules, the views will often be defined in separate modules. Individual views will need to be identified in a way that does not introduce tight coupling and dependencies between modules.
After the view is identified, the process by which the new view is instantiated and initialized has to be carefully coordinated. This can be particularly important when using the MVVM pattern. In this case, the view and view model may need to be instantiated and associated with each other via the view's data context during the navigation operation. In the case when the application is leveraging a dependency injection container, such as the Unity Application Block (Unity) or the Managed Extensibility Framework (MEF), the instantiation of the views and/or view models (and other dependent classes) may have to be achieved using a specific construction mechanism.
The MVVM pattern provides a separation between the application's UI and its presentation and business logic. However, the navigational behavior of the application will often span UI and presentation logic parts of the application. The user will often initiate navigation from within the view, and the view will be updated as a result of that navigation, but navigation will often also need to be initiated or coordinated from within the view model. The ability to cleanly separate the navigational behavior of the application across the view and view model is an important aspect to consider.
An application will also often need to pass parameters or context to the view so that it can be initialized properly. For example, if the user navigates to a view to update the details of a specific customer, the customer's ID or data will have to be passed to the view so that it can display the correct information.
Many applications will also have to carefully coordinate navigation to ensure that certain business rules are obeyed. For example, users may be prompted before navigating away from a view so that they can correct any invalid data or be prompted to submit or discard any data changes that they have made within that view. This process requires careful coordination between the previous view and the new view.
Lastly, most modern applications allow the user to easily navigate backward (or forward) to previously displayed views. Similarly, some applications implement their workflows using a sequence of views or forms and allow users to navigate forward or backward through them, adding or updating data as they go, before completing the task and submitting all their changes at one time. These scenarios require some kind of journaling (or history) mechanism so that the sequence of navigation can be stored, replayed, or pre-defined.
Prism provides support and guidance for these challenges by extending Prism's region mechanism to support navigation. The following sections provide a brief summary of Prism regions and describe how they have been extended to support view-based navigation.
Prism regions are designed to support the development of composite applications (that is, applications that consist of multiple modules) by allowing the application's overall UI to be constructed in a loosely-coupled way. Regions allow views defined in a module to be displayed within the application's UI without requiring the module to have explicit knowledge of the application's overall UI structure. They allow the layout of the application's UI to be changed easily, thereby allowing the UI designer to choose the most appropriate UI design and layout for the application without requiring changes in the modules themselves.
Prism regions are essentially named placeholders within which views can be displayed. Any control in the application's UI can be a declared a region by simply adding a RegionName attached property to it, as shown here.
For each control specified as a region, Prism creates a Region object to represent the region and a RegionAdapter object, which manages the placement and activation of views into the specified control. The Prism Library provides RegionAdapter implementations for most of the common WPF controls. You can create a custom RegionAdapter to support additional controls or when you need to define a custom behavior. The RegionManager class provides access to the Region objects within the application.
In many cases, the region control will be a simple control, such as a ContentControl, that can display one view at a time. In other cases, the Region control will be a control that is able to display multiple views at the same time, such as a TabControl or a ListBox control.
The region adapter manages a list of views within the associated region. One or more of these views will be displayed in the region control according to its defined layout strategy. Views can be assigned a name that can be used to retrieve that view later on. The region adapter manages the active state of the views within the region. The active view is the view that is the selected or top-most view—for example, in a TabControl, the active view is the one displayed in the selected tab; in a ContentControl, the active view is the view that is currently displayed as the control's content.
Note: The active state of a view is important to consider during navigation. Frequently, you will want the active view to participate in navigation so that it can save data before the user navigates away from it, or so that it can confirm or cancel the navigation operation.
Previous versions of Prism allowed views to be displayed in a region in two ways. The first, called view injection, allows views to be programmatically displayed in a region. This approach is useful for dynamic content, where the view to be displayed in the region changes frequently, according to the application's presentation logic.
View injection is supported through the Add method on the Region class. The follow code example shows how you can obtain a reference to a Region object via the RegionManager class and programmatically add a view to it. In this example, the view is created using a dependency injection container.
The second method, called view discovery, allows a module to register a view type against a region name. Whenever a region with the specified name is displayed, an instance of the specified view will be automatically created and displayed in the region. This approach is useful for relatively static content, where the view to be displayed in a region does not change.
View discovery is supported through the RegisterViewWithRegion method on the RegionManager class. This method allows you to specify a callback method that will be called when the named region is shown. The following code example shows how you can create a view (via the dependency injection container) when the main region is first shown.
For a detailed overview of Prisms region support and information about how to leverage regions to compose the application's UI using view injection and discovery, see Composing the User Interface. The rest of this topic describes how regions have been extended to support view-based navigation, and how this addresses the various challenges described earlier.
Both view injection and view discovery can be considered to be limited forms of navigation–view injection is a form of explicit, programmatic navigation, and view discovery is a form of implicit or deferred navigation. However, in Prism 4.0, regions have been extended to support a more general notion of navigation, based on URIs and an extensible navigation mechanism.
Navigation within a region means that a new view is to be displayed within that region. The view to be displayed is identified via a URI, which, by default, refers to the name of the view to be created. You can programmatically initiate navigation using the RequestNavigate method defined by the INavigateAsync interface.
Note: Despite its name, the INavigateAsync interface does not represent asynchronous navigation that's carried out on a separate background thread. Instead, the INavigateAsync interface represents the ability to perform pseudo-asynchronous navigation. The RequestNavigate method may return synchronously following the completion of navigation operation, or it may return while a navigation operation is still pending, as in the case where the user needs to confirm the navigation. By allowing you to specify callbacks and continuations during navigation, Prism provides a mechanism to enable these scenarios without requiring the complexity of navigating on a background thread.
The INavigateAsync interface is implemented by the Region class, allowing you to initiate navigation within that region.
You can also call the RequestNavigate method on the RegionManager, which allows you to specify the name of the region to be navigated. This convenient method obtains a reference to the specified region and then calls the RequestNavigate method, as shown in the preceding code example.
By default, the navigation URI specifies the name of a view that is registered in the container.
Using MEF, you can simply export the view type with the specified name.
During navigation, the specified view is instantiated, via the container or MEF, along with its corresponding view model and other dependent services and components. After the view is instantiated, it is then added to the specified region and activated (activation is described in more detail later in this topic).
Note: The preceding description illustrates view-first navigation, where the URI refers to the name of the view type, as it is exported or registered with the container. With view-first navigation, the dependent view model is created as a dependency of the view. An alternative approach is to use view model–first navigation, where the navigation URI refers to the name of the view model type, as it is exported or registered with the container. View model–first navigation is useful when the view is defined as a data template, or when you want your navigation scheme to be defined independently of the views.
The RequestNavigate method also allows you to specify a callback method, or a delegate, which will be called when navigation is complete.
The NavigationResult class defines properties that provide information about the navigation operation. The Result property indicates whether or not navigation succeeded. If navigation was successful, then the Result property will be true. If navigation failed, normally because of returning 'continuationCallBack(false)' in the IConfirmNavigationResult.ConfirmNavigationRequest method, then the Result property will be false. If navigation failed due to an exception, the Result property will be false and the Error property provides a reference to any exception that was thrown during navigation. The Context property provides access to the navigation URI and any parameters it contains, and a reference to the navigation service that coordinated the navigation operation.
Frequently, the views and view models in your application will want to participate in navigation. The INavigationAware interface enables this. You can implement this interface on the view or (more commonly) the view model. By implementing this interface, your view or view model can opt-in to participate in the navigation process.
Note: In the description that follows, although a reference is made to calls to this interface during navigation between views, it should be noted that the INavigationAware interface will be called during navigation whether it is implemented by the view or by the view model. During navigation, Prism checks to see whether the view implements the INavigationAware interface; if it does, it calls the required methods during navigation. Prism also checks to see whether the object set as the view's DataContext implements this interface; if it does, it calls the required methods during navigation.
This interface allows the view or view model to participate in a navigation operation. The INavigationAware interface defines three methods.
The IsNavigationTarget method allows an existing (displayed) view or view model to indicate whether it is able to handle the navigation request. This is useful in cases where you can re-use an existing view to handle the navigation operation or when navigating to a view that already exists. For example, a view displaying customer information can be updated to display a different customer's information. For more information about using this method, see the section, Navigating to Existing Views, later in this topic.
The OnNavigatedFrom and OnNavigatedTo methods are called during a navigation operation. If the currently active view in the region implements this interface (or its view model), its OnNavigatedFrom method is called before navigation takes place. The OnNavigatedFrom method allows the previous view to save any state or to prepare for its deactivation or removal from the UI, for example, to save any changes that the user has made to a web service or database.
If the newly created view implements this interface (or its view model), its OnNavigatedTo method is called after navigation is complete. The OnNavigatedTo method allows the newly displayed view to initialize itself, potentially using any parameters passed to it on the navigation URI. For more information, see the next section, Passing Parameters During Navigation.
After the new view is instantiated, initialized, and added to the target region, it then becomes the active view, and the previous view is deactivated. Sometimes you will want the deactivated view to be removed from the region. Prism provides the IRegionMemberLifetime interface, which allows you to control the lifetime of views within regions by allowing you to specify whether deactivated views are to be removed from the region or simply marked as deactivated.
The IRegionMemberLifetime interface defines a single read-only property, KeepAlive. If this property returns false, the view is removed from the region when it is deactivated. Because the region no longer has a reference to the view, it then becomes eligible for garbage collection (unless some other component in your application maintains a reference to it). You can implement this interface on your view or your view model classes. Although the IRegionMemberLifetime interface is primarily intended to allow you to manage the lifetime of views within regions during activation and deactivation, the KeepAlive property is also considered during navigation after the new view is activated in the target region.
Note: Regions that can display multiple views, such as those that use an ItemsControl or a TabControl, will display both non-active and active views. Removal of a non-active view from these types of regions will result in the view being removed from the UI.
To implement the required navigational behavior in your application, you will often need to specify additional data during navigation request than just the target view name. The NavigationContext object provides access to the navigation URI, and to any parameters that were specified within it or externally. You can access the NavigationContext from within the IsNavigationTarget, OnNavigatedFrom, and OnNavigatedTo methods.
Prism provides the NavigationParameters class to help specify and retrieve navigation parameters. The NavigationParameters class maintains a list of name-value pairs, one for each parameter. You can use this class to pass parameters as part of navigation URI or for passing object parameters.
The following code example shows how to add individual string parameters to the NavigationParameters instance so that it can be appended to the navigation URI.
Additionally, you can pass object parameters by adding them to the NavigationParameters instance, and passing it as a parameter of the RequestNavigate method. This is shown in the following code.
You can retrieve the navigation parameters using the Parameters property on the NavigationContext object. This property returns an instance of the NavigationParameters class, which provides an indexer property to allow easy access to individual parameters, independently of them being passed through the query or through the RequestNavigate method.
Frequently, it is more appropriate for the views in your application to be re-used, updated, or activated during navigation, instead of replaced by a new view. This is often the case where you are navigating to the same type of view but need to display different information or state to the user, or when the appropriate view is already available in the UI but needs to be activated (that is, selected or made top-most).
For an example of the first scenario, imagine that your application allows the user to edit customer records, using the EditCustomer view, and the user is currently using that view to edit customer ID 123. If the customer decides to edit the customer record for customer ID 456, the user can simply navigate to the EditCustomer view and enter the new customer ID. The EditCustomer view can then retrieve the data for the new customer and update its UI accordingly.
An example of the second scenario is where the application allows the user to edit more than one customer record at a time. In this case, the application displays multiple EditCustomer view instances in a tab control—for example, one for customer ID 123 and another for customer ID 456. When the user navigates to the EditCustomer view and enters customer ID 456, the corresponding view will be activated (that is, its corresponding tab will be selected). If the user navigates to the EditCustomer view and enters customer ID 789, a new instance will be created and displayed in the tab control.
The ability to navigate to an existing view is useful for a variety of reasons. It is often more efficient to update an existing view instead of replace it with a new instance of the same type. Similarly, activating an existing view, instead of creating a duplicate view, provides a more consistent user experience. In addition, the ability to handle these situations seamlessly without requiring much custom code means that the application is easier to develop and maintain.
Prism supports the two scenarios described earlier via the IsNavigationTarget method on the INavigationAware interface. This method is called during navigation on all views in a region that are of the same type as the target view. In the preceding examples, the target type of the view is the EditCustomer view, so the IsNavigationTarget method will be called on all existing EditCustomer view instances currently in the region. Prism determines the target type from the view URI, which it assumes is the short type name of the target type.
Note: For Prism to determine the type of the target view, the view's name in the navigation URI should be the same as the actual target type's short type name. For example, if your view is implemented by the MyApp.Views.EmployeeDetailsView class, the view name specified in the navigation URI should be EmployeeDetailsView. This is the default behavior provided by Prism. You can customize this behavior by implementing a custom content loader class; you can do this by implementing the IRegionNavigationContentLoader interface or by deriving from the RegionNavigationContentLoader class.
The implementation of the IsNavigationTarget method can use the NavigationContext parameter to determine whether it can handle the navigation request. The NavigationContext object provides access to the navigation URI and the navigation parameters. In the preceding examples, the implementation of this method in the EditCustomer view model compares the current customer ID to the ID specified in the navigation request, and it returns true if they match.
If the IsNavigationTarget method always returns true, regardless of the navigation parameters, that view instance will always be re-used. This allows you to ensure that only one view of a particular type will be displayed in a particular region.
You will often find that you will need to interact with the user during a navigation operation, so that the user can confirm or cancel it. In many applications, for example, the user may try to navigate while in the middle of entering or editing data. In these situations, you may want to ask the user whether he or she wants to save or discard the data that has been entered before continuing to navigate away from the page, or whether the user wants to cancel the navigation operation altogether. Prism supports these scenarios via the IConfirmNavigationRequest interface.
The IConfirmNavigationRequest interface derives from the INavigationAware interface and adds the ConfirmNavigationRequest method. By implementing this interface on your view or view model class, you allow them to participate in the navigation sequence in a way that allows them to interact with the user so that the user can confirm or cancel the navigation. You will often use an Interaction Request object, as described in in Advanced MVVM Scenarios, to display a confirmation pop-up window.
Note: The ConfirmNavigationRequest method is called on the active view or view model, similar to the OnNavigatedFrom method described earlier.
The ConfirmNavigationRequest method provides two parameters, a reference to the current navigation context as described earlier, and a callback method that you can call when you want navigation to continue. For this reason, the callback is known as a continuation callback. You can store a reference to the continuation callback so the application can call it after it finishes interacting with the user. If your application interacts with the user through an Interaction Request object, you can chain the call to the continuation callback to the callback from the interaction request. The following diagram illustrates the overall process.
Navigation operation is initiated via a RequestNavigate call.
If the view or view model implements IConfirmNavigation, call ConfirmNavigationRequest.
The view model raises the interaction request event.
The view displays the confirmation pop-up window and awaits the user's response.
The interaction request callback is invoked when the user closes the pop-up window.
Continuation callback is invoked to continue or cancel the pending navigation operation.
The navigation operation is completed or canceled.
To illustrate this, look at the View-Switching Navigation Quick Start. This application provides the ability for the user to compose a new email using the ComposeEmailView and ComposeEmailViewModel classes. The view model class implements the IConfirmNavigation interface. If the user navigates, such as by clicking the Calendar button, when they are composing an email, the ConfirmNavigationRequest method will be called so that the view model can confirm the navigation with the user. To support this, the view model class defines an interaction request, as shown in the following code example.
In the ComposeEmailView class, an interaction request trigger is defined, and data is bound to the ConfirmExitInteractionRequest property on the view model. When the interaction request is made, a simple pop-up window will be displayed to the user.
The ConfirmNavigationRequest method on the ComposeEmailVewModel class is called if the user attempts to navigate while an email is being composed. The implementation of this method invokes the interaction request defined earlier so that the user can confirm or cancel the navigation operation.
The callback for the interaction request is called when the user clicks the buttons in the confirmation pop-up window to confirm or cancel the operation. This callback simply calls the continuation callback, passing in the value of the Confirmed flag, and causing the navigation to continue or be canceled.
Note: It should be noted that after the interaction request event is raised, the ConfirmNavigationRequest method immediately returns so that the user can continue to interact with the UI of the application. When the user clicks the OK or Cancel buttons on the pop-up window, the callback method of the interaction request is made, which in turn calls the continuation callback to complete the navigation operation. All the methods are called on the UI thread. Using this technique, no background threads are required.
Using this mechanism, you can control if the navigation request is carried out immediately or is deferred, pending an interaction with the user or some other asynchronous interaction (for example, as a result of a web service request). To enable navigation to proceed, you can simply call the continuation callback method, passing true to indicate that it can continue. Similarly, you can pass false to indicate that the navigation should be canceled.
If you want to defer navigation, you can store a reference to the continuation callback you can then call when the interaction with the user (or web service) completes. The navigation operation will be pending until you call the continuation callback.
If the user initiates another navigation operation in the meantime, the navigation request then becomes canceled. In this case, calling the continuation callback has no effect because the navigation operation to which it relates is no longer current. Similarly, if you decide not to call the continuation callback, the navigation operation will be pending until it is replaced with a new navigation operation.
The NavigationContext class provides access to the region navigation service, which is responsible for coordinating the sequence of operations during navigation within a region. It provides access to the region in which navigation is taking place, and to the navigation journal associated with that region. The region navigation service implements the IRegionNavigationService, which is defined as follows.
Because the region navigation service implements the INavigateAsync interface, you can initiate navigation within the parent region by calling its RequestNavigate method. The Navigating event is raised when a navigation operation is initiated. The Navigated event is raised when navigation within a region is completed. The NavigationFailed is raised if an error was encountered during navigation.
The Journal property provides access to the navigation journal associated with the region. The navigation journal implements the IRegionNavigationJournal interface, which is defined as follows.
You can obtain and store a reference to the region navigation service within a view during navigation via the OnNavigatedTo method call. By default, Prism provides a simple stack-based journal that allows you to navigate forward or backward within a region.
You can use the navigation journal to allow the user to navigate from within the view itself. In the following example, the view model implements a GoBack command, which uses the navigation journal within the host region. Therefore, the view can display a Back button that allows the user to easily navigate back to the previous view within the region. Similarly, you can implement a GoForward command to implement a wizard style workflow.
You can implement a custom journal for a region if you need to implement a specific workflow pattern within that region.
Note: The navigation journal can only be used for region-based navigation operations that are coordinated by the region navigation service. If you use view discovery or view injection to implement navigation within a region, the navigation journal will not be updated during navigation and cannot be used to navigate forward or backward within that region.
When using the Navigation Journal, it can be useful to display intermediary pages like splash screens, loading pages or dialogs. It is desirable that these pages should not revisited via calls to IRegionNavigationJournal.GoForward() or IRegionNavigationJournal.GoBack(). This behaviour can be achieved by implementing the IJournalAware interface.
Pages can opt-out of being added to the journal history by implementing IJournalAware on the View or View Model and returning false from PersistInHistory().
Prism region navigation was designed to address a wide range of common scenarios and challenges that you may face when implementing navigation in a loosely-coupled, modular application that uses the MVVM pattern and a dependency injection container, such as Unity, or the Managed Extensibility Framework (MEF). It also was designed to support navigation confirmation and cancellation, navigation to existing views, navigation parameters and navigation journaling.
By supporting navigation within Prism regions, it also supports navigation within a wide range of layout controls and supports the ability to change the layout of the application's UI without affecting its navigation structure. It also supports pseudo-synchronous navigation, which allows for rich user interaction during navigation.
However, the Prism region navigation was not designed to replace WPF's navigation framework. Instead, Prism region navigation was designed to be used side-by-side with the WPF navigation framework.
The WPF navigation framework is difficult to use to support the MVVM pattern and dependency injection. It is also based on a Frame control that provides similar functionality in terms of journaling and navigation UI. You can use the WPF navigation framework alongside Prism region navigation, though it may be easier and more flexible to implement navigation using only Prism regions.
The following illustration provides an overview of the sequence of operations during a navigation operation. It is provided for reference so that you can see how the various elements of the Prism region navigation work together during a navigation request.
For more information about Prism regions, see Composing the User Interface.
For more information about the MVVM pattern and Interaction Request pattern, see Implementing the MVVM Pattern and Advanced MVVM Scenarios.
For more information about the Interaction Request object, Using Interaction Request Objects in Advanced MVVM Scenarios.
For more information about the Visual State Manager, see VisualStateManager Class on MSDN.
For more information about using Microsoft Blend behaviors, see Working with built-in behaviors on MSDN.
For more information about creating custom behaviors with Microsoft Blend, see Creating Custom Behaviors on MSDN.


text:
Press Release - 2013 EU Budget: Cyprus presidency brokers agreement on Council's position
Today the Permanent Representatives Committee (COREPER) endorsed the Council's draft position on the 2013 EU budget, confirming herewith the technical agreement reached last week in the Budget Committee on the basis of a compromise text by the Cyprus Presidency.
The Council is expected to formally adopt its position on July 24. The Council wants to limit the payments' increase to 2.79% compared to 2012 and the increase of commitments to 1.27% (the Commission proposed + 6.85% in payments and +2.05% in commitments).
"The agreement on the Council's position for next year's budget is the first tangible success of the Cyprus Presidency and is the first indispensable step for concluding the negotiations with the European Parliament later this year", said Vassos Shiarly, the Cyprus Finance Minister.
"As many member states, the Council had to make some difficult choices and revisit all its priorities. The Council's position strongly focuses on growth enhancing measures, in line with the Europe 2020 strategy for growth and jobs, while limiting the burden on national public finances in times of fiscal consolidation by decreasing appropriately other headings," said Mr Shiarly.
"Budget negotiations within the Council have been a particularly challenging task this year due to the budgetary constraints of the member states, the economic situation and the fact that 2013 is the last year of the current multiannual financial framework," Mr Shiarly concluded.
Procedure to follow
If the European Parliament adopts amendments to the Council's position by the end of October, which are not acceptable to the Council, a twenty-one-day-conciliation-period starts on October 24, leading to a decisive Conciliation meeting on November 9, between Council and European Parliament.
In absolute figures, the Council's position amounts to EUR 132.70 bn in payments (corresponding to 0.99% of the EU's GNI) and EUR 149.78 bn in commitments (leaving a margin of EUR 3.58 bn under the overall ceiling of the current MFF).
Commitment Appropriations
Payment Appropriations
Billion Euros
1 – Sustainable Growth
Sub 1a – Competitiveness
Sub 1b – Cohesion
2 – Preservation and Management of Natural Resources
Of which for market related expenditure and direct aids
3 – Citizenship, Freedom Security and Justice
Sub 3a – Freedom, Security and Justice
Sub 3b - Citizenship
4 – EU as a Global Player
5 – Administration
Telephone: +32 27395152

redpajama_set_name: RedPajamaCommonCrawl


text:
Bosses Regularly Get Away with Ripping-Off Their Workers
09/06/2017 by Zeb Holmes & Ugur Nedim
A recent decision by the Fair Work Ombudsman (FWO) highlights the leniency that is frequently afforded to employers who illegally underpay their employees.
Former CDPP prosecutor Robert Corr highlights the fact that it is rare for bosses who rip-off their workers to be criminally prosecuted or even subjected to civil litigation or a complaint, which is in stark contrast to the treatment of employees who are suspected of fraud, larceny as a servant and embezzlement.
On 25 May 2017, the FWO issued a media release concerning the initiation of proceedings in the Federal Circuit Court against JPA Manchester Pty Ltd, which trades as 'Benson Australia' in retail outlets throughout Sydney, and online.
The company was alleged to have underpaid an employee in the sum of $60,000 over a four-year period. The employee was a Chinese immigrant who had worked at the company's Redfern and Miranda stores. He was paid at a flat rate of $9 an hour, despite being entitled to an award rate of $18.99 for ordinary hours.
The company also allegedly failed to pay annual leave entitlements, and doctored pay slips and accounts to avoid detection.
Serial offender
This is not the only time JPA Manchester has fallen foul of the law by underpaying employees.
The owner of the company, Mr Jia Ping Ou, publicly committed to revamping the company's workplace practices after underpaying another Sydney employee more than $27,000 between 2010 and 2014, paying her as little as $8 an hour.
"It is completely unacceptable to continue to allegedly blatantly underpay an employee after being put on notice to comply," Fair Work Ombudsman Natalie James remarked in the most recent decision.
Despite the conduct, JPA Manchester was merely ordered to pay outstanding entitlements, accept an audit at the direction of the FWO and commit to retraining managerial staff.
In light of the lenient penalty, Mr Corr posed the following scenario:
"Imagine if a worker illegally kept $30,000 and then $60,000 of their boss' money", adding that he or she would likely face criminal prosecution for one or more offences.
A recent report by the University of Melbourne found that only a small percentage of businesses, mostly small businesses, changed their workplace practices as a result of the risk of specific regulatory activities by the Fair Work Ombudsman. The report noted that most businesses thought the risk of getting caught for underpaying workers was "highly unlikely", "unlikely", or "50/50" at best.
This means employers perceive the risk of being called to account for ripping off worker as negligible.
"When the risk is seen as better than a coin toss, and there's no danger of a real prosecution, is it any wonder that wage rip-offs are widespread?", Mr Corr asks.
Illegal exploitation of workers is prevalent
According to the FWO's annual report, the agency audited more than 4530 businesses in 2015-16, finding that more than one-third had committed "monetary contraventions".
Over the past two years, a number of the country's biggest and best-known retail and hospitality companies have been exposed as underpaying young and foreign workers. The companies include Coles-Myer, Woolworths, McDonald's, 7-Eleven, Caltex, Bakers Delight and Costco.
7-Eleven, for example, has been ordered to repay workers $59 million, after systematically underpaying its employees.
Civil liability fails to act as a deterrent
The existing regime is clearly failing to deter rogue employers from shirking their legal obligations.
In one example, an Adelaide company was fined $196,000 by the Federal Court after underpaying 46 of its employees by more than $2.5 million. Many of the employees were over 60 years of age, and were not paid the relevant wages, casual loadings, penalty rates or annual leave entitlements.
The company had continued to engage in this conduct despite threats of civil action, and many believe employers must be criminally prosecuted if there is to be any chance of deterring such misconduct.
Criminal prosecutions
The FWO's Litigation Policy states that matters should be referred to the CDPP for potential criminal prosecution where a relevant breach has occurred.
However, the last time a criminal prosecution was mentioned in a FWO annual report was in 2008. This may be due to the fact that it is often difficult to prove that an employer has engaged in conduct amounting to fraud, as the offence requires proof beyond reasonable doubt of both "dishonesty" and "deception". The situation has led to calls for a specific criminal offence to be enacted in respect of underpaying employees.
According Mr Corr, "Until the Ombudsman toughens up, and starts to take real action against recidivist and criminal employers, a significant minority of Australia's business community will continue to see the illegal exploitation of workers as a risk worth taking."
Zeb Holmes
Zeb Holmes is a lawyer with a passion for social justice who advocates criminal law reform, and a member of the content team at Sydney Criminal Lawyers®.
Zeb's
The Poor Are Criminalised, While the Crimes of the Rich Are Overlooked
The Wealthy and Powerful Getting Away with Tax Fraud
An Unfair Dismissal? An Interview with Former Police Constable Hugh Brennan
Job Vacancy: Low Pay with Sexist Men
Beware of Callers Claiming to be from Government Agencies
Geoffrey Rush Smashes Telegraph "Out of the Park" in Defamation Lawsuit
SEE PREVIOUS NSW Police Fail to Secure Crime Scenes When Officers Are Suspected of Serious Crimes
SEE NEXT NSW Lawyer Struck Off For Producing False Evidence


BEIJING, China (CNN) -- Heavy snow blanketed Beijing on Sunday, shutting roads, disrupting public transit, and delaying or canceling at least 200 flights, state media reported.
Some parts of Beijing received 12 centimeters (about 5 inches) of snow Sunday, China Daily said.
As of mid-morning, more than 200 flights had been postponed or canceled at Beijing Capital International Airport, the newspaper reported.
"Luckily, we are still in the new year holiday. More people could be affected tomorrow," said area resident Liu Juan, according to China Daily.
Liu was out enjoying views of snow, which had led to dozens of bus routes being delayed or suspended, the newspaper said.
Temperatures were expected to fall to lows of minus 10 degrees Celsius (14 degrees Fahrenheit) on Sunday, the Central Meteorological Station said, according to China Daily.
Monday's forecast was for a low of minus 19 Celsius (minus 2 degrees Fahrenheit).
-- CNN's John Vause contributed to this report.


text:
Q: Why does it highlight the whole div easily when I click on space css php? Do you have any css code to stop this highlight thing on chrome. Usually, we quickly double click on space of a website, it will highlight the whole div, but my website is very easy to be highlight, so I want to know do I have to put some css code, something like text-decoration:none, help, appreciate.

A: Use user-select: CSS property:
div {
    -webkit-user-select: none;  /* Chrome all / Safari all */
    -moz-user-select: none;     /* Firefox all */
    -ms-user-select: none;      /* IE 10+ */

    /* No support for these yet, use at own risk */
    -o-user-select: none;
    user-select: none;
}

redpajama_set_name: RedPajamaStackExchange


text:
La Ronda Final de la Clasificación de Concacaf para la Copa Mundial de Fútbol de 2006 fue la etapa que determina la clasificación a la Copa Mundial de Fútbol de 2006. Se llevó a cabo del 9 de febrero al 12 de octubre de 2005. México, Estados Unidos y Costa Rica se clasificaron a la Copa del Mundo tras finalizar en las primeras tres posiciones de la ronda, mientras que Trinidad y Tobago se clasificó al vencer en la repesca a Baréin 2:1.

Equipos participantes

Clasificación

Evolución de la clasificación

Resultados

Jornada 1

Jornada 2

Jornada 3

Jornada 4

Jornada 5

Jornada 6

Jornada 7

Jornada 8

Jornada 9

Jornada 10

Goleadores
6 goles
 Francisco Fonseca
 Stern John

4 goles
 Carlos Ruiz
 Jared Borgetti

3 goles
 Carlos Hernández
 Paulo Wanchope
 Brian McBride
 Landon Donovan
 Jaime Lozano

2 goles

 Walter Centeno
 Rónald Gómez
 Roy Myrie

 Álvaro Saborío
 Eddie Johnson
 Eddie Lewis

 Steve Ralston
 Dwight Pezzarossi
 Gonzalo Romero

 Luis Pérez
 Sinha
 Luis Tejada

1 gol

 Whayne Wilson
 DaMarcus Beasley
 Carlos Bocanegra
 Kyle Martino
 Taylor Twellman
 Freddy García

 Guillermo Ramírez
 Mario Rodríguez
 Élmer Ponciano
 Selvin Poniciano
 Edwin Villatoro

 Guillermo Franco
 Rafael Márquez
 Ramón Morales
 Pável Pardo
 Roberto Brown

 Jorge Dely Valdés
 Carlos Edwards
 Angus Eve
 Russell Latapy
 Dennis Lawrence

Autogoles

 Gustavo Cabrera ()

 Felipe Baloy ()

 Marvin Andrews ()

Enlaces externos
RSSSF - 2006 World Cup Qualification

Clasificación de Concacaf para la Copa Mundial de Fútbol de 2006

redpajama_set_name: RedPajamaWikipedia


The 10th HealthGrid conference started this week in Amsterdam at the AMC. The conference is held in conjunction with the 4th International Workshop on Science Gateways for LifeSciences (IWSG-Life) that will start this afternoon.
HealthGrid2012 started Monday with two tutorial sessions. I missed a part of Tom Visser's interesting session about Academic HPC cloud computing but managed to fully attend the second session on Grid Portal development focused on Biomedical Image and Signal Processing of Jie Wu, René Siewert and Dagmar Krefting from the Charite University Hospital and University for Applied Sciences.
During the tutorial sessions, everyone was very concentrated.
Not all participants had completed their homework (we should have performed the preparatory steps before the conference) but the Berlin crew was very helpful and willing to give us a second change.
I stopped with the DIY exercise Monday evening, halfway the second manual, not because the information was insufficient or unclear (in contrary) but just to get some sleep.
If you could not attend the tutorial session but are still interested in building your own Liferay portlets for the grid, here is the information.
1. The first step is a preparatory step: you should install Eclipse, Liferay (bundled with Tomcat) and Cog jGlobus libraries at your local machine. This is very good described in the preparation manual. It takes about one hour.
2. The second step deals with the configuration and setup of an example: this is also very clearly described in the tutorial handout. Average time is estimated about two hours.
After following the two manuals of Jie Wu, René Siewert and Dagmar Krefting you should be able to take the next step in building your own system.


text:
Temple City hands San Gabriel 5th straight loss…
SportsHigh School Sports
Temple City hands San Gabriel 5th straight loss with 43-0 win
By The Pasadena Star-News | pasadenastarnews@dfmdev.com |
SAN GABRIEL >> The Temple City Rams used a 22-point first quarter to take control of the game and beat the host San Gabriel Matadors 43-0 in a nonleague game Friday night.
Temple City (2-2) handed San Gabriel (0-5) not only its fifth straight loss, but also its fifth consecutive scoreless game.
The Rams got on the board early when, on the second play of the game, running back Jimmy Morinaga took the handoff at his own 36 yard line and ran 55 yards before being run out of bounds at the Matador 19. Two plays later, quarterback Rico Salcido connected with Paul Kosavich on a 15-yard touchdown pass. The extra point was missed but Temple City had the early 6-0 lead with 10:52 left in the first quarter.
On fourth down from the 12, San Gabriel decided to punt. But a bad snap went over the punter's head and out of the end zone for a safety. And the Rams extended their lead to 8-0 with 8:44 left in the first quarter.
Following the free kick, Temple City struck again quickly. This time, Brad Chi ran 44 yards for the touchdown and a 15-0 lead with 7;27 left in the first quarter.
Nic Starling's 2-yard touchdown run with :56 left closed out the first-quarter scoring and made it 22-0 Temple City.
Morinaga scored the first of three consecutive touchdowns of the game in the second quarter. With 7:55 left before halftime, Morinaga took the ball and ran 25 yards for the score and a 29-0 lead.
After a scoreless third quarter, Morinaga scored his second touchdown of the game. On the first play of the fourth quarter, he took a handoff and ran 39 yards to make it 36-0.
And Morinaga closed out the scoring for the Rams when his 8-yard touchdown run made it a 43-0 final.
Morinaga rushed 13 times for 172 yards and three touchdowns.
The Pasadena Star-News
Los Angeles Chargers |
Kellen Moore 'really, really excited' to get started with Chargers


Public workers' rights are under attack in Wisconsin. Mrs. Ripp -one of my favorite teacher bloggers – lives in Wisconsin.
Teachers are not made in college, they become them in the classroom. Teachers reach out to anyone that enters their worlds, and they impact every single aspect of this American life. Support them, cherish them, and right now, fight for them and their rights. We are here to help America succeed and grow, not to take the blame.
'We Are One' – Candlelight Vigil In Solidarity with Wisconsin Workers – Tuesday, February 22nd -West Steps of the State Capitol in Sacramento, CA – 5:30-7:30pm.
Do you find yourself sitting at your desk jaws clenched, wondering where your concentration has gone? Or is it just me?
Sarah from Pink of Perfection invites readers to share ideas on How To Find Calm In the Work Day. Do you have anything to add?
Doing one thing at a time is one of Sarah's calming tips and one I struggle to follow – especially online.
Recently, I've been spending much less time on social media (Facebook and Twitter) – I've been on a sort of accidental Social Media Diet as Tammy from Rowdy Kittens calls it. Check out her video for tips on how to ease yourself away from the online.
Photo shoot number one took place this week and the results are amazing!
I've got a photographer for a second photo shoot (thanks Vanessa!). It is looking like the end of March – right before the deadline. Details will follow (like the exact date and location) – please leave me a comment if you are interested.
The Flying Yogini has been writing about the Curvy Yoga Revolution.
This entry was posted in Best of the Blogs I Read and tagged Curvy Yoga, curvy yogis, finding calm, It's All Yoga, Mrs. Ripp, Pink of Perfection, Rowdy Kittens, social media diet, The Flying Yogini, The Happiness Project, unplugging, Vanessa Vichit-Vadakan by Teacher Goes Back to School. Bookmark the permalink.
Love the "I am a teacher" excerpt. We've definitely been taking the blame for most of the ills in education.
Congratulations on the first photo shoot!
I'd love to participate in this; please notify me of the date/location of the March shoot if you can use me. Thanks!


Sometimes it's cold and dark, sometimes it's lively and colorful. The sea has many things to teach and is still hiding lots and lots from us. You do know that we know more about most planets and satellites in the solar system than we know about the depths of Earth's oceans! Well, for now, there's this new pack of exclusive items to help you wrap your mind around that.
Under the Sea…that does bring a song to mind!


Here is the complete tutorial and step by step instructions on how to unlock Samsung Galaxy S Blaze 4G SGH-T769 by Unlock Code so that you can use with any gsm carrier.
Codes2unlock.com is proud to announce that we are the direct source for Unlocking Samsung Galaxy S Blaze 4G SGH-T769. We provide a fast, easy and secure way to unlock with LOWEST PRICE GUARANTEED. After unlocking you can use it with any gsm network.
*Important Note - Due to latest change called "Region Lock" of new Samsung devices, your Galaxy S 4G Blaze SGH-T769 must be activated with original carrier first before proceeding to Unlocking Samsung Galaxy S Blaze 4G. If you try to unlock your Samsung Galaxy SGH-T769 without activating with original carrier you may not be able to permanently unlock your device.
1. Samsung Galaxy S Blaze 4G Unlock Code on your email.
2. Samsung Galaxy S Blaze 4G Unlocking Instructions on your email.
1. Please make sure your Samsung Galaxy S Blaze 4G has been activated with original carrier.
5. Your Samsung Galaxy S Blaze 4G is now Permanently unlocked!
There is no risk of damage in unlocking of your Samsung Galaxy S Blaze 4G by Code.
Is samsung galaxy s7 worth the price, heard that the battery life is short? is anyone using this ??


The RLED30Slave is designed to work with RLED30CV4 modules where the length of tape exceeds the capacity of the RLED30CV4. The RLED30Slave is fed the output signal from the RLED30CV4 and allows a further length of tape to be controlled from the same base RLED30CV4 unit.
This method of slaving is more cost effective than having multiple RLED30CV4 units but importantly allows colour cycling to remain in sync where multiple RLED30CV4 units may drift due to slight differences in the internal clocks.


text:
Q: htaccess redirect http to https causes redirect loop I have edited my .htaccess file to redirect any http request to https://mydomain.se however, this has cause the website to fall in redirect loop. I have looked at the other solutions and compared them however I detected nothing wrong.
RewriteEngine On
RewriteCond %{HTTP_HOST} ^(www\.)(.+) [OR]
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} ^(www\.)?(.+)
RewriteRule ^ https://%2%{REQUEST_URI} [R=301,L]

If it does help, domain is bitech.se

A: Your RewriteCond seems to always match, as the HTTPS version redirects back to the HTTPS over and over.
Try this instead:
RewriteCond %{HTTPS} !=on

A: I'm using following settings to redirect every HTTP traffic to HTTPS with the exact requested path:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,L]


This trail follows the former railway line between Kaltbad and Rigi Scheidegg (1874 – 1931). It's entirely flat except for the very last part, making it the ideal trail for a pleasant stroll. Along the way there are plenty of reminders of the former railway to be discovered, such as old railway bridges and a tunnel. There's even a disused train carriage that has been converted into a holiday home, a water tank for the old steam locomotives as well as several kilometre signs. The view of the Alps and the Schwyz basin is divine. From Rigi Scheidegg you can ride the aerial cable car back down to Goldau via Kräbel.


EMS World Media and EMS World EXPO is where decision makers turn for vital out-of-hospital healthcare information.
Launched in 1972 as "Emergency Medical Services" Magazine, we were the first to deliver cutting edge education and product information to the emergency medical service community. Over 45 years later, EMS World Magazine, and our Spanish language publication Revista, educates the industry through thought-leading editorial and innovative product coverage. Our print, digital and social media coverage of news, product information and training tools are designed to educate and inform. EMS World EXPO is the largest EMS event in the United States bringing over 40 countries together to share best practice and experience.


text:
The Hayden pups, their first big (5) litter Governor: Feed grounds necessary in Wyoming
Why cheatgrass wins
By Ralph Maughan On July 16, 2007 · 22 Comments · In Grazing and Livestock, Wildfire, Wildlife Habitat
The major culprit in almost all of the big lower elevation fires in the interior West is cheatgrass, which has a nicer name of downy brome (Bromus tectorum), probably given for the way it is during the brief period is it growing, green, and not ripening.
Cheatgrass has taken over the West, greatly increasing fire danger, damage, and harming wildlife habitat, causing stream erosion, etc. Global warming or not, there will be more and more fires as cheat grass spreads because that is a major way it wipes out its native competitors — fire.
It is an annual grass, and it is the first grass to sprout with late summer rains. It usually gets a good start before winter and continues in the early spring. If the autumn is dry, it sprouts in early spring. It is very shallow rooted, sucking the up moisture and nitrogen that native seeds need to sprout as well as shading them out. Cheatgrass is a tremendous producer of seeds, far exceeding native bunchgrasses.
Once it starts to move in, almost always as the result of some disturbance that creates bare ground, it is almost inevitable that it will convert most of the area into dry brown grass for most of the year, replacing semi-arid country shrubs and native grasses with a dreary monoculture. This will happen slowly if there is no fire, but with a fire it is almost inevitable and the annual probability of a fire increases with the proportion that is cheatgrass.
Great Basin wild rye and cheatgrass. Photo by Ralph Maughan
I took this photo of a tall perennial bunchgrass (Great Basin wild rye) and cheatgrass near Pocatello, Idaho in early July. To the casual observer it might seem the wild rye is doing great (it's tall and green even though it was been half eaten by cows) and the cheatgrass dry and dead, but the wild rye is doomed even without a fire. That is a terrible thing because wild rye has very deep roots to seek out water in mid-summer, and these roots serve to hold the soil in place. Cheatgrass is only slightly better than a slope of bare soil.
I can't tell if the cheatgrass was grazed before it ripened or not because it goes to seed even if cattle or sheep are put in to eat it during its brief "downy phase." It can't be eaten when it is ripe like in the photo because the seeds are very hard and sharp (you've probably gotten it in your socks — itch!).
Perennial bunch grasses can't stand heavy grazing. If the rest of that green wild rye is eaten by a cow, it will be so weak when it sprouts next year that it will probably be overrun by the cheatgrass (no fire necessary). The wild rye's seeds don't have much of a chance sprouting in the cheatgrass, and cows have already chomped off all but one seed stalk on this bunch anyway.
Cheatgrass begins to invade an area most often by dirt roads or vehicle tracks, usually in conjunction with cattle grazing. Heavy grazing leaves bare spots, and the first seeds to sprout on these bare spots will be cheat grass once an infestation is nearby. The cattle also spread the cheatgrass seeds and trample them in, for good measure.
Overgrazed range (sagebrush steppe) with all the native grass eaten. Bare ground, the perfect spot for cheatgrass to sprout and then soon burn, destroying the sagebrush which has already been weakened by cattle trampling. This photo in the Owyhee country (BLM) of SW Idaho was taken this year (2007) by Katie Fite. A fair portion of it that has been invaded by cheatgrass has burned this year.
More information. Cheatgrass: the Invader the won the West.
22 Responses to Why cheatgrass wins
That is a serious problem. I think I've seen it around here but I'm not sure. Unfortunately, it won't get better until..
This is why I am motivated to act. It is a disaster that's coming. It's pretty obvious isn't it?
Eric's right. It is pretty obvious. And scientists with the federal agencies – both BLM and Forest Service, as well as researchers at USGS who have been working on sagebrush habitat fragmentation and loss, all know that sagebrush is doomed if we keep abusing it with cattle and sheep grazing. Yet, under Bush and Norton, and continuing under Bush and Kempthorne (despite Kempthorne Happy Talk about "wildlife habitat initiatives"), it's just like the censorship that has occurred in other government agencies — in relation to climate change. NEVER admit that grazing disturbance must end if cheatgrass is ever to be controlled and prevented from dominating the Interior West and destroying places we all love …
So basically 20,000 public lands welfare ranchers have a death grip on science policies applied to western public lands.
KT or anyone with knowledge about noxious weeds…. ..Seems the preferred treatment for noxious weeds(knapweed, leafy spurge, houndstongue etc) in my area is to spray with "tordon" and or "milestone", then follow up with sheep to finish whatever weeds are left. Does this open up the possibility of an invasion of cheatgrass?
Weeds thrive in areas of disturbance in wild lands – just like in the margins of a garden. Unless you get perennial vegetation established on the sites where you have sprayed Tordon, and/or trampled and grazed with sheep or goats – it certainly does open the door for cheatgrass/brome or other weed invasion.
Maybe BE, who I believe has a horticulture degree, among other talents, has some insights on Tordon, its persistence, and ecological effects?
I've seen areas in the Lost River Valley on BLM lands in the Antelope Creek watershed where an obvious herbicide event had occurred, and all the tall Basin big sagebrush and native grass had been killed, and the ONLY thing surviving and thriving was the leafy spurge. And sites in northern Nevada where ALL the remaining sagebrush, roses and mesic vegetation at the margins of cowed-out springs and seeps had been sprayed – dried skeletons of shrubs left – and the landscape a couple years later was a carpet of cowpies and white top and cheatgrass.
And the sheep and goat grazing? Perhaps it will knock weeds back in the short-term, but unless you alleviate disturbance to the site and establish perennials and intact microbiotic crusts – the weeds will be back.
The policy being followed on our public lands is basically a dis-integrated, instead of "integrated" weed mgmt strategy. Spray and walk away. Sheep and retreat.
Right now the comment period is open on a Final BLM Westwide Weed EIS – where the BLM continues its disastrous policies tha are leading to all the cheatgrass-fueled fires. BLM's solution to weed/fuels problems across the western states is aimed at enriching Monsanto and Dow Elanco, and more of the same old Bush Healthy Forest "fuels reduction" projects. AND the BLM Weed EIS provides NO honest effort whatsoever to address the role of livestock grazing and trampling in promoting weeds. The only thing that seems to matter is the big government contracts the chemical companies will get.
be says:
tordon is said to be persistent in arid landscapes for up to 4 years. this is Dow's own assesment. and yes – anything that disturbs the soil threatens cheat invasion. another scary thing about cheat is that it is evolving to encroach on higher and higher elevations…
the important thing to understand, from my perspective, is that disturbance of the soil is the enemy here. the best defense against weed infiltration is intact and healthy native communities and the microbiotic soil crusts which takes years to develop in arid conditions. that's humbling.
the tendency of BLM is to solve the problem with anthropogenic force. there must be a "treatment". unfortunately, especially in the case of cheat, is that the "treatments" prescribed are egregiously aggressive with our landscapes (prescribed burn then spray then burn – or the like). these aggresive treatments are very disturbing and as such, there is no chemical in this world that can be laced across our children's public land and water supply that will prevent the weeds from outcompeting on these new swaths of landscape – especially when grazing is a given variable.
in fact, rarely are the real costs of spraying considered. does the spray sterilize the soil and remove necessary soil conditions for natives (ex: mychorrizal communities which promote native germination, vigor) – the soil itself has much life – a metabolism – nutrient levels, the conditions natives evolved in conjunction with, are altered when chemical salts are laced.
weeds are another externality cost of the livestock industry — bladed roads only "necessary" to subsidize permittee access to an allotment. water developments/pipelines tearing up the soil and providing venues for weed seed, and then the cattle themselves – churning the soil and altering native vigor, inflating nitrogen levels (which weeds are able to benefit from but not as much natives), and directly transporting seed on site – but also from where-ever the bovines were trucked in from. i own land in AZ adjacent to a state allotment – you should see the mesquite spread down there – it ain't natural.
spraying is a way of making the externality costs of livestock production on public lands less visible – they're kicking the can into a less visible realm.
they use the industry science in their risk assesments.
they test in vaccuums (i.e. they don't assess active ingredients toxicity in conjunction with the surfactants – or the baseline chemical levels – the toxicity of the chemical's degradates, or the transformational products).
they develop anecdotal programs on plots which aren't grazed, and then project that level of efficacy for their programs onto public lands that will be immediately grazed (disturbance once again being the aggravating factor in weed infestation).
they re-seed treated lands with plants more palatable to cattle rather than with the native communities which if given rest/retirement have the greatest chance at resisting re-infestation – or at least promoting the vigor and actual natural habitat for wildlife.
i guess the point i'm trying to make is. if agency attempts at mitigating weeds is to be made – DO SO IN GOOD FAITH – be willing to mitigate the causal contributions – not just treat the symptoms.
our public lands are like a lung-cancer patient whose visit to the doctor (agency) ends in chemo treatment after chemo treatment – but the doctory never thinks to tell the patient to quit smoking…
Monte says:
Cheatgrass is worse and worse here in Montana, particularly in the last couple years. We have treated areas of spotted knapweed with Tordon that are now solid cheatgrass. If it is present, it will fill in the gaps.
One solution might be naturally-occurring plant pathogens as are being tested to control Canada Thistle and Yellowstar Thistle. But the real best way to control is by mitigating causal contributions as be said.
An large monetary investment in the restoration of native vegetation plus the elimination of livestock needs to be be made in places where cheatgrass has taken over or is invading.
Onf of most important things that can be done is to restore beaver to degraded streams, assuming there are still willows, cottonwood, or aspen for them to work with and eat. Expanding the green zone around streams and raising the humidity serves as a fire break. Thats what beaver ponds usually do.
I think 10-billion dollars of the right kind of investment would pay for itself in reduced fire fighting costs, improved fish and wildlife habitat, and reduction in mosquito habitat (think of West Nile virus).
Of course, they could easily waste the 10-billion by doing what BE refers to above.
As an example, they need to restore blue bunch wheatgrass, not blue bunch wheatgrass cultivars or non-natives such as crested wheatgress and its cultivars.
mikarooni says:
Ralph, what are you talking about when you differentiate between "blue bunch wheatgrass" and "blue bunch wheatgrass cultivars" and why is one better/worse than another in your view? I'm not necessarily challenging you; I'm asking honest questions. Please be as specific as you can spare the time to be and answer quickly because I use several types of blue bunch and related species (Granite Seed out of Lehi) and this year's shipment is on the way any day now. I'm assuming that you consider P7 to be a cultivar; but, what should I be worrying about? I started with the leftovers of someone else's horrific overgrazing and it has sure jumpstarted the recovery, with western, slender, and even thickspike now moving in. I understand about not using non-natives, but am less clear about the subtleties between a native and a "cultivar" of a native.
milkarooni,
I'm not a great expert on blue bunch wheatgrass, so maybe KT will chime in here, and you know more about it than I do, but here is what I am thinking.
If we are going to try to restore a site to various native species, we should use the native plants that grew on that site or a similar site. A cultivar is, as you know, is a plant that has been selected for certain characteristics and bred to express them.
From what I understand many of the blue bunch seedings in burned areas or otherwise "treated" areas are of cultivars that grow taller than the unmodified grass. If you plant these, you may get more forage from the cultivar, but you are obviously thinking about livestock grazing rather than fire reduction. Any wheatgrass is better than cheatgrass, but they will burn late in the summer. A taller wheatgrass will burn hotter than a shorter one. So, what I was trying to say not to plant cultivars that are designed to enhance livestock grazing. Use the native seed if it is available.
Yes, commonly available "cultivars" like Secar which is sold as bluebunch wheatgrass but really is not a bluebunch, have all spent many years being bred by Ag. Range researchers to be bigger coarser, more – essentially – "aggressive" than the typically shorter, less coarse native bluebunch wheatgrass ecotypes. Towards the end of this link, http://plants.usda.gov/plantguide/pdf/pg_pssp6.pdf you can see that Secar is not even the same Genus as native bluebunch wheatgrass. It was bred to make it produce more "forage" = and this results in more "fuel" – especially when agencies like BLM plant it in dense rows like a farm field.
Then, when you get this super-grass that is not really a native planted on "range" land in places like the Jarbidge BLM lands- you begin to see that, similarly to the Asian crested wheatgass and Siberian wheatgrass, cows don't like it very much. They eat all the other things first – yet BLM sets its measurements of how much "use"/utilization has occurred on the tallest, biggest grass – the cultivar. So then the stocking rate of cows remains high, and the interspaces get trampled – and overrun with cheatgrass, bur buttercup and other weeds.
And no one really knows how pollen from cultivars might cross with native bluebunch remaining on the site.
Mikarooni – Is your place grazed?
Ralph and kt, thanks. This is good information; I've been so fixated on eliminating bare ground that, as long as the plant books/maps say that the species is native to my general area and elevation, I've used it. I'll be more careful and double-check in the future. I haven't used Secar directly; but, it's likely that it's part of the P7 mix that I have used. I do hear what you are saying about different people, including some in BLM and NRCS, not being perfectly clear on what is and isn't native. One range specialist recommended paiute orchard grass and, when I asked him, a few times in a row, whether it was native, he told me "of course it is; it's paiute." It's really frustrating to be trying to get things done and have to spend time doing your own research because you have to suspect and personally validate every piece of information. I know; whine; whine.
Yes, I'm afraid my place is grazed; forgive me. My objective is the value of the property and restoration is an important part of my business plan; but, a rested allotment is a contested allotment and, without livestock, I would never have been allowed to fence out the ORVs that, combined with the previous overgrazing, had just flat stomped the place by the time I got it, which is why the price was low enough to enable me to sell my other holdings and get it in the first place. So, without the political connections to be allowed to raise bison, I raise registered longhorns, which drives the range management guys crazy, and, surprise, surprise, I actually still make money. I do keep my stocking rates way down, which also confuses the range management guys, and, left to range where they want, which is everywhere, longhorns behave like bison in that they are always on the move and don't stay in any one spot long enough to make a hole. I also don't have much problem with them being selective eaters. Whatever comes up out there, including cactus, juniper, whatever they have been selling me as blue bunch wheatgrass, and even the smaller twigs and bark off downed pine branches, they eat it all. They even actually seem to like whatever sporobolus species I have out there. So, except for Canadian thistle, which I try to kick out before it gets to seed, I haven't had problems with invasives yet, knock on wood.
My main fire concern is my overgrown woodland and forest areas. I understand that fire is a good thing; but, also understand that blackened property does not hold its scenic value. So, I'm leaving my trees much too dense to please the range management guys, but still making and hauling firewood as fast as I can, using the continuing presence of owls and other birds as an indicator.
Peter Kiermeier says:
Hi mikarooni, I think this is a invaluable insight for all of us into the troubles you face. Highly interesting!
Global warming processes act synergistically with cheatgrass – the hotter and drier it is at middle to higher elevations where cheatgrass may not yet have a foothold or dominate, the more likely it is that cheatgrass will be able to become established and spread in areas of disturbance there. Here are the states where it is a major problem: Washington and Oregon East of the Cascades, Idaho, Nevada, Utah – and increasingly Wyoming.
Other annual bromes, closely related to cheatgrass are now causing large fires in the Sonoran and Mojave deserts of Arizona and California – the saguaros and Joshua trees may be converted to annual brome weedlands – due to the disturbance-brome invasion-fire cycle – just like the depressing landscape of much of the Snake River Plain these days.
So in the face of these impending catastrophic losses of whole ecosystems, what are the scientists of the Bush Admin. doing? Frittering away precious time and energy in devising ways (such as the 10j Rule) to slaughter more wolves – and make life even easier for the public lands livestock industry – where the trampling hooves of cows and sheep are priming tens of millions of acres not yet invaded by cheatgrass or bromes FOR cheatgrass dominance – and eventual loss of nearly all native wildlife – and to just ugly, nasty places to hike, camp ,,, be.
Instead of wolf killing hearings, what are needed is planning and hearings on where livestock will be removed first in order to save those places from advancing cheatgrass. This ties into the broken Fire Policy, too. THe government spends millions, billions on "post-fire rehab" fire (building more cow fences, planting nice dense big flammable cow food grasses to help pepetuate and extend that cycle) – while applying those funds to buying out and permanently retiring public lands grazing permits is what should be done, instead.
kt, I sincerely agree with everything that you say, with a few caveats. I am afraid 1) that, by identifying the conservation movement with a pure push for a wholesale end to public lands grazing, we will create a political weapon that will more effectively be used against us than on our behalf and 2) that, with money being concentrated internationally into fewer and fewer hands and a new feudalism on the rise, public lands, for the foreseeable future, need to remain too much of a chaotic battleground of competing voices to enable the true evil, the new oligarchs, to see them as an easy target for privatization. Wolf Creek could happen everywhere. Even now, these oligarchic, for lack of a better term, interests are well represented in the "holding entities" that do business associated with our public lands, from beef to wood to minerals; the street public just doesn't see it because the use of various holding companies and equity firms shields so much from view nowadays. I fear that, if given the kind of federal deficit paralysis that the rightwing would love to orchestrate, the push to sell to these oligarchic interests would be strong indeed. I believe that pushing reforms in the way these lands are managed is our better bet. As a fellow political scientist, Ralph may see these factors; but, his postings are not clear on them.
Frankly, I look back on November of 2000 as a horrible disaster that was unintentionally, but very foolishly, aided and abetted by those in the environmental movement who demanded an untenable level of purity and wouldn't take anything less. Once the election was made close enough, through a splitting of our vote and it didn't take much, fraud could be used to handle the rest. The perennial weakness of each far end of the spectrum, ours and fortunately theirs as well, is that both extreme ends want it all and they both want it now, which is a highly constrained tactical environment that only the extremely self-confident are foolhardy enough to be comfortable in.
All seriousness aside, I have been very happy with the use of registered longhorns to meet my livestock requirements. They provided me with the required rationale to fence out the ORVs, although I still allow hikers through; they graze evenly and all across the range, without focusing on any one area or set of plants; their behavior, physical capabilities, and natural weaponry keeps me from having to worry about predators; and, raised on grass and genetically lean to begin with, they yield a product with better flavor and far lower fat and cholesterol.
Robert Hoskins says:
To add to this discussion, I would like to copy here a letter to the editor that appeared in this morning's Casper (Wyoming) Star Tribune. The author is Debra L. Donahue, professor of law at the University of Wyoming Law School. Ms. Donahue is author of the book, The Western Range Revisited, which called for removal of cattle from the fragile public lands of the southwest. In retaliation for the publication of this book, a bill was introduced in the Wyoming legislature that would have abolished the Law School. The bill didn't pass, but the message was sent; this sort of thing is typical for Wyoming. Luckily, Ms. Donahue had just received tenure, or she would have been in trouble. The university president at the time actively solicited comments from other (pro-livestock) professors at the university to criticize her argument and conclusions in public.
Ms. Donahue also holds a MA in Wildlife Ecology and has worked at the BLM. She knows her stuff.
Agency bears full responsibility
The federal government — Bureau of Land Management in particular — bears major responsibility for the Milford fire and many others currently burning in the West. As the agency itself has admitted, the chief culprits are livestock grazing and weeds, especially cheatgrass.
In a recent weed control Environmental Impact Statement, the BLM wrote: "Passive treatments, such as removing the cause of the disturbance (e.g., livestock …) may be more effective long-term than active treatments," such as herbicides, brush removal, etc. Yet the agency refuses to alter its grazing policies.
With every fire, range conditions get worse; eventually the damage is irreversible. Yet BLM perpetuates the degradation by permitting livestock to return.
Cheatgrass will never be removed or even controlled unless it is replaced with native perennial vegetation. And that will not happen as long as livestock grazing continues. Livestock, particularly cattle, "preferentially graze native species" (BLM's words). And "natural recovery … usually cannot occur unless grazing is completely discontinued" (Richard Stevens and Stephen Monsen, retired government scientists who edited a major report on restoring western ranges).
The BLM could stop the "downward spiral of ecological conditions" on public lands (again, its words). It has the authority to stop livestock grazing where it is causing damage. In fact, as long as it continues to allow grazing, it is violating both the letter and the spirit of the laws it operates under.
Our public lands are being sacrificed. The BLM is trading our heritage — native vegetation and wildlife, invaluable topsoil, water quality and yield, air quality and recreation opportunities — to satisfy the smallest group of public land users, to produce commodities that are produced much more efficiently elsewhere. It's long past time for the public to say, "Enough."
DEB DONAHUE, Jelm
Here's my response to "We have to keep ranchers supported in their welfare fiefdoms on our public lands": When Bush called for the sell-off of public lands – was it two year's ago? – There was public outrage — everywhere. Many people move to, and live in the West because of public lands recreation. The biggest sell-offs of public lands under Bush have come from the Nevada Wilderness Bills sponsored by Harry Reid – lubricated to passage because the legislated public land sell-offs in Lincoln and White Pine County were sugarcoated in a Wilderness package (along with the infamous Las Vegas water pipelines). Note: The floundering Owyhee Initiative would sell-off/give to ranchers as much as 75,000 acres – so it too would join this quid pro quo Wilderness Land Disposal pattern.
Cattle grazing is destroying public lands across much of the West by fostering cheatgrass and other weeds. We have to get the cattle off – if anything is going to be left. If grazing continues to convert everything to cheatgrass – much if the Interior West will become a biological desert/void. And there won't be any wildlife. Maybe a chukar or two.
Time to acknowledge the dire situation that is upon us, and end the nightmare of predator killing, weed spreading, and paranoid provincialism surrounding public lands grazing.
The federal government is going to be pouring massive amounts of our tax dollars into the aftermath of the 2007 fires – including millions to plant cow food and build "temporary" cow fences for $6000 or more an acre – all so that grazing can resume again in two years or less – and lock in a cheatgrass monoculture in perpetuity. Grazing afer only two growing seasons never allows time for native plant recovery and especially not for recovery of microbiotic crusts that protect soils from weeds.
A rational, science-based post-2007 fires policy would be: Apply all those $$$ about to be spent to perpetuate grazing to END grazing … the primary ecological irritant that is priming lands to become cheatgrass Hells, and facilitating Global Warming processes.
Correction in my previous comment – I meant $6000 or more a mile for fence costs – not an acre …
I could use suggestions on grass types & ordering sources.
I'm trying to get grasses to grow on an old mine dump at 10,000 feet in Colorado. It is a small area (50 yard by 200 yards). I am fortunate to be able to apply some water using rather simple drip irrigation, which functions from mid-June to early September due to weather.
I've used the mix of grass seed recommended by the Soil Conservation Service (ryes & brohmes as I recall). After 5 years of care I'm happy to see soil starting to form. I wonder if I should be finding some nitrogen fixers like lupine or fireweed (my small bunch of fireweed didn't come back this year; not sure why).
I'm a chemist by training, not a botanist. I could use recommendations of reading material.


text:
<?php
namespace Oro\Component\MessageQueue\Tests\Unit\Transport\Dbal;

use Doctrine\Common\Persistence\ManagerRegistry;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Schema\AbstractSchemaManager;
use Oro\Component\MessageQueue\Transport\Dbal\DbalConnection;
use Oro\Component\MessageQueue\Transport\Dbal\DbalLazyConnection;
use Oro\Component\Testing\ClassExtensionTrait;

class DbalLazyConnectionTest extends \PHPUnit\Framework\TestCase
{
    use ClassExtensionTrait;

    public function testShouldImplementConnectionInterface()
    {
        self::assertClassExtends(DbalConnection::class, DbalLazyConnection::class);
    }

    public function testCouldBeConstructedWithRequiredArguments()
    {
        new DbalLazyConnection($this->createManagerRegistryStub(), 'connection', 'table');
    }

    public function testShouldNotBeInitOnConstruct()
    {
        $connection = new DbalLazyConnection($this->createManagerRegistryStub(), 'connection', 'table');

        self::assertConnectionIsNotInit($connection);
    }

    public function testShouldInitDBALConnectionUsingRegistryAndConnectionName()
    {
        $dbalConnection = $this->createDBALConnectionMock();

        $registry = $this->createManagerRegistryMock();
        $registry
            ->expects(self::once())
            ->method('getConnection')
            ->with('theConnection')
            ->willReturn($dbalConnection)
        ;

        $connection = new DbalLazyConnection($registry, 'theConnection', 'table');

        //guard
        self::assertConnectionIsNotInit($connection);

        self::assertSame($dbalConnection, $connection->getDBALConnection());
        self::assertConnectionIsInit($connection);
    }

    public function testShouldNotInitOnCreateSessionMethodCall()
    {
        $connection = new DbalLazyConnection($this->createManagerRegistryStub(), 'connection', 'table');

        //guard
        self::assertConnectionIsNotInit($connection);

        $session = $connection->createSession();

        self::assertAttributeInstanceOf(DbalLazyConnection::class, 'connection', $session);
        self::assertConnectionIsNotInit($connection);
    }

    public function testShouldNotInitOnGetTableNameCall()
    {
        $connection = new DbalLazyConnection($this->createManagerRegistryStub(), 'connection', 'theTable');

        //guard
        self::assertConnectionIsNotInit($connection);

        self::assertEquals('theTable', $connection->getTableName());

        self::assertConnectionIsNotInit($connection);
    }

    public function testShouldNotInitOnGetOptionsCall()
    {
        $options = ['foo' => 'fooVal', 'bar' => 'barVal'];

        $connection = new DbalLazyConnection($this->createManagerRegistryStub(), 'connection', 'table', $options);

        //guard
        self::assertConnectionIsNotInit($connection);

        self::assertEquals($options, $connection->getOptions());

        self::assertConnectionIsNotInit($connection);
    }

    public function testShouldNotInitOnCloseIfNotInit()
    {
        $dbalConnection = $this->createDBALConnectionMock();
        $dbalConnection
            ->expects(self::never())
            ->method('close')
        ;

        $registry = $this->createManagerRegistryStub($dbalConnection);

        $connection = new DbalLazyConnection($registry, 'connection', 'table');

        //guard
        self::assertConnectionIsNotInit($connection);

        $connection->close();

        self::assertConnectionIsNotInit($connection);
    }

    public function testShouldCallCloseInitOnCloseIfNotInit()
    {
        $dbalConnection = $this->createDBALConnectionMock();
        $dbalConnection
            ->expects(self::once())
            ->method('close')
        ;

        $registry = $this->createManagerRegistryStub($dbalConnection);

        $connection = new DbalLazyConnection($registry, 'connection', 'table');

        $connection->getDBALConnection();

        //guard
        self::assertConnectionIsInit($connection);

        $connection->close();
    }

    private static function assertConnectionIsNotInit(DbalLazyConnection $connection)
    {
        self::assertAttributeSame(false, 'isInit', $connection);
    }

    private static function assertConnectionIsInit(DbalLazyConnection $connection)
    {
        self::assertAttributeSame(true, 'isInit', $connection);
    }

    /**
     * @return \PHPUnit\Framework\MockObject\MockObject|ManagerRegistry
     */
    private function createManagerRegistryMock()
    {
        return $this->createMock(ManagerRegistry::class);
    }

    /**
     * @return \PHPUnit\Framework\MockObject\MockObject|ManagerRegistry
     */
    private function createManagerRegistryStub($connection = null)
    {
        $registryMock = $this->createManagerRegistryMock();
        $registryMock
            ->expects(self::any())
            ->method('getConnection')
            ->willReturn($connection)
        ;

        return $registryMock;
    }

    /**
     * @return \PHPUnit\Framework\MockObject\MockObject|Connection
     */
    private function createDBALConnectionMock()
    {
        $schemaManager = $this->createMock(AbstractSchemaManager::class);

        $dbalConnection = $this->createMock(Connection::class);
        $dbalConnection
            ->expects($this->any())
            ->method('getSchemaManager')
            ->will($this->returnValue($schemaManager))
        ;

        return $dbalConnection;
    }
}

redpajama_set_name: RedPajamaGithub