InfoPath 2007 brings with a slew of new features and functionality, but one thing we noticed is the deprecation of the OnAfterImport event.
OnAfterImport was useful for programming tasks that should happen after a merge attempt.
With 2007, the only merge-related event is the Merge event itself. But during this event the UI is locked up and some functionality is not available, like switching views. Presumably, this is because the built-in merge executes asynchronously and during the merge the UI shouldn't be mucked up. Unfortunately, there's no way to know when the built-in merge is complete, so we can't wait around to switch the view.
But using a known 2003 hack
http://spsfactory.blogspot.com/2006_08_01_spsfactory_archive.html, we can adapt it to get the view switched when the merge is complete.
This article assumes you have experience writing event handlers for InfoPath. Code samples are in C#.
The process works like this:
Assume we have two views, "Detail" and "Summary." Detail is the default view and Summary is the view we wish to switch to after a merge.
First, we'll add code for the following events: Merge and ContextChanged.
When the merge is called from the menu, the Merge event will fire. In this event we'll call the SetFocus method which will trigger a ContextChanged event. Finally, in the ContextChanged event, we're in a state that will allow us to switch views.
Here's the code.
First add a member variable (browser safe) that keeps some state info.
private object _redirect
{
get { return FormState["_redirect"]; }
set { FormState["_redirect"] = value; }
}
Next add the event handlers (or let InfoPath add them for you.)
public void InternalStartup()
{
EventManager.FormEvents.Merge += new MergeEventHandler(FormEvents_Merge);
EventManager.FormEvents.ContextChanged += new ContextChangedEventHandler(FormEvents_ContextChanged);
// this helps us with state
_redirect = false;
}
The first event that is trapped is the Merge event. This happens when the user selects the merge option from the file menu.
public void FormEvents_Merge(object sender, MergeEventArgs e)
{
// The built-in merge
// If you wrote a custom merge, your code would go here.
MergeForm(e.Xml);
// Set the redirect flag to true
_redirect = true;
// Change focus
// Note: if you focus is already on this field the ContextChanged
// event will not fire.
// Note: the SetFocus method works by selecting the text in the
// field specified. This will only work with controls that have
// text.
// Note: You cannot set focus to a field on a different view.
SetFocus("/my:myFields/my:FocusField");
e.CancelableArgs.Cancel = false;
}
private void SetFocus(string xpath)
{
try
{
// Find the field to set focus to and select the text (this will cause focus to change.)
XPathNavigator fieldToFocus = MainDataSource.CreateNavigator().SelectSingleNode(xpath, NamespaceManager);
this.CurrentView.SelectText(fieldToFocus);
}
catch (ArgumentException ex)
{
MessageBox.Show("The focus cannot be set to " + xpath);
}
}
Changing the focus will trigger the ContextChanged event. Since we can't SwitchView() inside of Merge, we'll have to wait until the ContextChanged event to switch views.
public void FormEvents_ContextChanged(object sender, ContextChangedEventArgs e)
{
if (e.ChangeType == "ContextNode")
{
// The XML selection or context has changed.
// if the redirect flag is on we want to switch views
// the flag will only be on if Merged was changed from false to true, and focus was changed
if ((bool)_redirect)
{
_redirect = false;
ViewInfos.SwitchView("Summary");
}
return;
}
}
Finally, we have a beer.
Cheers,
Daryl Moore