Region boundary/control placement

Nov 26, 2013 at 12:51 AM
Hi,
I have a scenario where I have a main region and a navigation region. Each region contains one view at a time. The regions would optimally be constructed like so:

Image

The main region would contain a view with an "Action" button that triggers execution of that view. The navigation region contains buttons that allow the user to skip a particular view in the main region and proceed to the next. Due to the alignment of the Action button, I have not been able to accomplish this scenario.

My workaround is to put the Action button in its own region (and view) like this:

Image

I am sharing the viewmodel for Main Region and Action Region by composing a shared instance of the viewmodel.

I have tried composite commands but the text of the button changes with each view which involves more complexity. I would simply like to have a single view for the main region and in that view have a button which appears to the right of the navigation region as shown in the first image.

Is this possible?
Thank you,
David A.
Nov 26, 2013 at 1:56 PM
Hi David,

Based on my understanding, the layout you are describing could be simply achieved by overlapping both regions (content controls) in a one single Grid cell. This could be done by defining first the Main content control filling the entire window, so then you would define the Navigation content control with its proper height, width, and horizontal and vertical alignment.
By doing this, the Navigation Region would appear over the Main Region after their views get resolved acording to the content control order definition.

Nevertheless, you could define a separate region for the Action button and use the EventAggregator in order to raise an event from the Action Button's ViewModel, and subscribe to it on every Main ViewModel.

To accomplish this approach, you would need to receive the EventAggregator throw constructor on the Action ViewModel and each one of the Main Region's ViewModel. You could use one only Action Button's View which it always would publish the same event, and then each Main ViewModel would perform the job that corresponds on the specified "ActionEventHandler" method.

In order to do this, you would need to subscribe to the "ActionTriggeredEvent" on each Main ViewModel constructor as shown below:
public MainViewModel1(IEventAggregator eventAggregator, ..){
    ...
    ActionTriggeredEvent actionTriggeredEvent = eventAggregator.Get<ActionTriggeredEvent>();
    actionTriggeredEvent.Subscribe(ActionEventHandler, ThreadOption.UIThread);
}

public void ActionEventHandler(){
     // execute tasks..
}
The Event would be published from inside the CommandHandler method as follows:
this.eventAggregator.GetEvent<ActionTriggeredEvent>().Publish();
Notice that you would need to make your "ActionTriggeredEvent" inherit from CompositePresentationEvent:
public class ActionTriggeredEvent : CompositePresentationEvent<string>{}
For more information about EventAggregation, you could refer to the following PRISM Guide chapter on MSDN:

I hope this helped you,
Gabriel Ostrowsky
https://blogs.southworks.net/gostrowsky
Nov 26, 2013 at 5:21 PM
Gabriel,

Your response is greatly appreciated, and solved my problem. I started going down the road of the pub/sub EventAggregation, but I also had to change the content (text) of the button depending on the view and it seemed like overkill to have to implement a separate EventAggregator for that as well.

The solution you provided with the overlapping content controls was exactly what I was looking for.

Thank you for taking the time to help me out!
David A.