Trying to implement front controller for Avalon Navigation application
Avalon Navigation application is pretty much closer to web behavior. There is one Host (Browser / Windows) that can display different content (HTML pages/Panels). Navigation application is based on one form and several panels that can be hosts and changed by using the main page Navigate function. So I thought it will be nice to implement “front controller” in Navigation application to impose predefine logic on panel flow.
To implement front controller I need to find event that occur when navigation between panels took place so I can intercept and decide which panel will be load. When navigation event happened I need to get access to the source Panel with the user input and the destination Panel (some times I want to impose certain behavior or view on Panel by user data).
The easiest part was to find navigation event that let me interrupt the navigation. Navigated event is happened just before the target panel is loaded. The content attribute of NavigationEventArgs, which pass to the events, holds the destination page. The problem is how to get the source page. The solution that I use right now (and I don’t please with) is to use UIContext Reserved2 attribute, which is unused in by Avalon to set the source panel from the source panel itself before navigating and to use the value preserved in Reserved2 while processing Navigated event to get source panel data and to use it :
private void OnNavigated(Object sender, NavigationEventArgs e)
{
backButton.IsEnabled = wNavContainer.CanGoBack;
forwardButton.IsEnabled = wNavContainer.CanGoForward;
object Src = ((FlowPanel)e.Content).Context.Reserved2;
if (Src is FlowPanel)
{
UIElementCollection oCol = ((FlowPanel)Src).Children;
foreach (UIElement oControl in oCol)
{
if (oControl is TextBox)
{
if (((TextBox)oControl).ID == "ID" && ((TextBox)oControl).Text != "ID")
{
((FlowPanel)e.Content).Context.Reserved2 = null;
this.Navigate(new Uri("Pane" + ((TextBox)oControl).Text + ".xaml", false, true));
}
}
}
}
}
The panel from it point of view need to set Reserved2 to the panel before navigation :
private void ButtonClick(object sender, ClickEventArgs e)
{
this.Context.Reserved2 = this;
((NavigationWindow)Application.MainWindow).Navigate(new Uri("Pane2.xaml", false, true));
}
Beside using UIContext every thing works as expected. If the user types any number in panel textbox and then click a button to navigate to other page. I catch the navigation event and change the navigation course by using the source panel controls data. I think that it will be nice if Microsoft let us to preserve data between pages through UIContext.