我理解你的观点,也明白你为什么想要调用RequestNavigate方法。
回答你的问题,是的,这是按设计要求的,不应该在切换选项卡时调用RequestNavigate。但是,你可以修改此行为以实现你的需求。Prism是开源的。你应该有源代码,可以将项目添加到你的项目中,并轻松地跟踪以下代码:
TabControlRegionAdapter-将区域适配到选项卡控件中
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();
}
}
同时,TabControlRegionSyncBehavior是您可以调用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);
}
}
}
}
当然,您需要找到在哪里调用RequestNavigate,以便您实际上可以取消TabSelectionChanging。不幸的是,WPF中不存在此事件。我建议采用Josh Smith在其博客文章"How to Prevent a TabItem from changing"中推荐的技巧。请参考
此链接。