I suppose I can see your point, and I understand why you would like it to call the RequestNavigate method.
To answer your question, yes this is by design and it is not supposed to call RequestNavigate while switching tabs. However, you can modify this behavior to do what you want. Prism is open source. You should have the source code, you can add the project to your project and easily step through the code for the following:
TabControlRegionAdapter - Adapts the region to the tab control
public class TabControlRegionAdapter : RegionAdapterBase<TabControl>
{
public static readonly DependencyProperty ItemContainerStyleProperty =
DependencyProperty.RegisterAttached("ItemContainerStyle", typeof(Style), typeof(TabControlRegionAdapter), null);
public TabControlRegionAdapter(IRegionBehaviorFactory regionBehaviorFactory)
: base(regionBehaviorFactory)
{
}
public static Style GetItemContainerStyle(DependencyObject target)
{
if (target == null) throw new ArgumentNullException("target");
return (Style)target.GetValue(ItemContainerStyleProperty);
}
public static void SetItemContainerStyle(DependencyObject target, Style value)
{
if (target == null) throw new ArgumentNullException("target");
target.SetValue(ItemContainerStyleProperty, value);
}
protected override void Adapt(IRegion region, TabControl regionTarget)
{
if (regionTarget == null) throw new ArgumentNullException("regionTarget");
bool itemsSourceIsSet = regionTarget.ItemsSource != null;
if (itemsSourceIsSet)
{
throw new InvalidOperationException(Resources.ItemsControlHasItemsSourceException);
}
}
protected override void AttachBehaviors(IRegion region, TabControl regionTarget)
{
if (region == null) throw new ArgumentNullException("region");
base.AttachBehaviors(region, regionTarget);
if (!region.Behaviors.ContainsKey(TabControlRegionSyncBehavior.BehaviorKey))
{
region.Behaviors.Add(TabControlRegionSyncBehavior.BehaviorKey, new TabControlRegionSyncBehavior { HostControl = regionTarget });
}
}
protected override IRegion CreateRegion()
{
return new SingleActiveRegion();
}
}
And also, TabControlRegionSyncBehavior. This is the one which you could call RequestNavigate.
public class TabControlRegionSyncBehavior : RegionBehavior, IHostAwareRegionBehavior
{
public const string BehaviorKey = "TabControlRegionSyncBehavior";
private static readonly DependencyProperty IsGeneratedProperty =
DependencyProperty.RegisterAttached("IsGenerated", typeof(bool), typeof(TabControlRegionSyncBehavior), null);
private TabControl hostControl;
public DependencyObject HostControl
{
get
{
return this.hostControl;
}
set
{
TabControl newValue = value as TabControl;
if (newValue == null)
{
throw new InvalidOperationException(Resources.HostControlMustBeATabControl);
}
if (IsAttached)
{
throw new InvalidOperationException(Resources.HostControlCannotBeSetAfterAttach);
}
this.hostControl = newValue;
}
}
protected override void OnAttach()
{
if (this.hostControl == null)
{
throw new InvalidOperationException(Resources.HostControlCannotBeNull);
}
this.SynchronizeItems();
this.hostControl.SelectionChanged += this.OnSelectionChanged;
this.Region.ActiveViews.CollectionChanged += this.OnActiveViewsChanged;
this.Region.Views.CollectionChanged += this.OnViewsChanged;
}
protected virtual object GetContainedItem(TabItem tabItem)
{
if (tabItem == null) throw new ArgumentNullException("tabItem");
if ((bool)tabItem.GetValue(IsGeneratedProperty))
{
return tabItem.Content;
}
return tabItem;
}
protected virtual TabItem PrepareContainerForItem(object item, DependencyObject parent)
{
TabItem container = item as TabItem;
if (container == null)
{
object dataContext = GetDataContext(item);
container = new TabItem();
container.Content = item;
container.Style = TabControlRegionAdapter.GetItemContainerStyle(parent);
container.DataContext = dataContext;
container.Header = dataContext;
container.SetValue(IsGeneratedProperty, true);
}
return container;
}
protected virtual void ClearContainerForItem(TabItem tabItem)
{
if (tabItem == null) throw new ArgumentNullException("tabItem");
if ((bool)tabItem.GetValue(IsGeneratedProperty))
{
tabItem.Content = null;
}
}
protected virtual TabItem GetContainerForItem(object item, ItemCollection itemCollection)
{
if (itemCollection == null) throw new ArgumentNullException("itemCollection");
TabItem container = item as TabItem;
if (container != null && ((bool)container.GetValue(IsGeneratedProperty)) == false)
{
return container;
}
foreach (TabItem tabItem in itemCollection)
{
if ((bool)tabItem.GetValue(IsGeneratedProperty))
{
if (tabItem.Content == item)
{
return tabItem;
}
}
}
return null;
}
private static object GetDataContext(object item)
{
FrameworkElement frameworkElement = item as FrameworkElement;
return frameworkElement == null ? item : frameworkElement.DataContext;
}
private void SynchronizeItems()
{
List<object> existingItems = new List<object>();
if (this.hostControl.Items.Count > 0)
{
foreach (object childItem in this.hostControl.Items)
{
existingItems.Add(childItem);
}
}
foreach (object view in this.Region.Views)
{
TabItem tabItem = this.PrepareContainerForItem(view, this.hostControl);
this.hostControl.Items.Add(tabItem);
}
foreach (object existingItem in existingItems)
{
this.Region.Add(existingItem);
}
}
private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (this.hostControl == sender)
{
foreach (TabItem tabItem in e.RemovedItems)
{
object item = this.GetContainedItem(tabItem);
if (this.Region.Views.Contains(item) && this.Region.ActiveViews.Contains(item))
{
this.Region.Deactivate(item);
}
}
foreach (TabItem tabItem in e.AddedItems)
{
object item = this.GetContainedItem(tabItem);
if (!this.Region.ActiveViews.Contains(item))
{
this.Region.Activate(item);
}
}
}
}
private void OnActiveViewsChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Add)
{
this.hostControl.SelectedItem = this.GetContainerForItem(e.NewItems[0], this.hostControl.Items);
}
else if (e.Action == NotifyCollectionChangedAction.Remove
&& this.hostControl.SelectedItem != null
&& e.OldItems.Contains(this.GetContainedItem((TabItem)this.hostControl.SelectedItem)))
{
this.hostControl.SelectedItem = null;
}
}
private void OnViewsChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Add)
{
int startingIndex = e.NewStartingIndex;
foreach (object newItem in e.NewItems)
{
TabItem tabItem = this.PrepareContainerForItem(newItem, this.hostControl);
this.hostControl.Items.Insert(startingIndex, tabItem);
}
}
else if (e.Action == NotifyCollectionChangedAction.Remove)
{
foreach (object oldItem in e.OldItems)
{
TabItem tabItem = this.GetContainerForItem(oldItem, this.hostControl.Items);
this.hostControl.Items.Remove(tabItem);
this.ClearContainerForItem(tabItem);
}
}
}
}
Of course, you'll have to figure out where to call RequestNavigate, such that you can actually cancel the TabSelectionChanging. Unfortunately, this event doesn't exist in WPF. I would resort to the trick recommended by Josh Smith How to Prevent a TabItem from changing