//using Prism.Ioc;
//using System;
//using System.Windows;
//using System.Windows.Controls;
//using System.Windows.Threading;
//namespace YY.Admin.Views.Control
//{
// ///
// /// TabContentView.xaml 的交互逻辑
// ///
// public partial class TabContentView : UserControl
// {
// public TabContentView()
// {
// InitializeComponent();
// this.Loaded += TabContentView_Loaded;
// this.Unloaded += TabContentView_Unloaded;
// }
// private bool _navigated = false;
// private void TabContentView_Loaded(object sender, RoutedEventArgs e)
// {
// try
// {
// if (string.IsNullOrWhiteSpace(RegionName))
// return;
// var regionManager = ContainerLocator.Current.Resolve();
// // 把内部 ContentControl 注册为 region(基于 RegionName)
// RegionManager.SetRegionName(PART_ContentHost, RegionName);
// RegionManager.SetRegionManager(PART_ContentHost, regionManager);
// // 延迟导航,确保 region 真正注册到 RegionManager 并且模板生成为止
// if (!_navigated && !string.IsNullOrEmpty(ViewName))
// {
// Dispatcher.BeginInvoke(new Action(() =>
// {
// try
// {
// // 再次检查 region 是否存在并执行导航
// if (regionManager.Regions.ContainsRegionWithName(RegionName))
// {
// regionManager.RequestNavigate(RegionName, ViewName);
// }
// else
// {
// // 如果 region 仍然不存在,尝试 RequestNavigate(Prism 通常会创建 region)
// regionManager.RequestNavigate(RegionName, ViewName);
// }
// }
// catch (Exception ex)
// {
// System.Diagnostics.Debug.WriteLine($"TabContentView 导航异常: {ex.Message}");
// }
// }), DispatcherPriority.Background);
// _navigated = true;
// }
// }
// catch (Exception ex)
// {
// System.Diagnostics.Debug.WriteLine($"TabContentView_Loaded 出错: {ex.Message}");
// }
// }
// private void TabContentView_Unloaded(object sender, RoutedEventArgs e)
// {
// try
// {
// if (!string.IsNullOrWhiteSpace(RegionName))
// {
// var regionManager = ContainerLocator.Current.Resolve();
// if (regionManager.Regions.ContainsRegionWithName(RegionName))
// {
// var region = regionManager.Regions[RegionName];
// region.RemoveAll();
// regionManager.Regions.Remove(RegionName);
// }
// }
// }
// catch (Exception ex)
// {
// System.Diagnostics.Debug.WriteLine($"TabContentView_Unloaded 清理异常: {ex.Message}");
// }
// }
// #region RegionName DP
// public static readonly DependencyProperty RegionNameProperty =
// DependencyProperty.Register(nameof(RegionName), typeof(string), typeof(TabContentView), new PropertyMetadata(null));
// public string RegionName
// {
// get => (string)GetValue(RegionNameProperty);
// set => SetValue(RegionNameProperty, value);
// }
// #endregion
// #region ViewName DP
// public static readonly DependencyProperty ViewNameProperty =
// DependencyProperty.Register(nameof(ViewName), typeof(string), typeof(TabContentView), new PropertyMetadata(null));
// public string ViewName
// {
// get => (string)GetValue(ViewNameProperty);
// set => SetValue(ViewNameProperty, value);
// }
// #endregion
// }
//}
using Prism.Ioc;
using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Threading;
namespace YY.Admin.Views.Control
{
public partial class TabContentView : UserControl
{
public TabContentView()
{
InitializeComponent();
this.Loaded += TabContentView_Loaded;
this.Unloaded += TabContentView_Unloaded;
this.IsVisibleChanged += TabContentView_IsVisibleChanged;
this.DataContextChanged += TabContentView_DataContextChanged;
}
private bool _navigated = false;
private IRegionManager _regionManager;
private DispatcherOperation _pendingNavigationOp;
#region DPs
public static readonly DependencyProperty RegionNameProperty =
DependencyProperty.Register(nameof(RegionName), typeof(string), typeof(TabContentView), new PropertyMetadata(null, OnRegionOrViewNameChanged));
public string RegionName
{
get => (string)GetValue(RegionNameProperty);
set => SetValue(RegionNameProperty, value);
}
public static readonly DependencyProperty ViewNameProperty =
DependencyProperty.Register(nameof(ViewName), typeof(string), typeof(TabContentView), new PropertyMetadata(null, OnRegionOrViewNameChanged));
public string ViewName
{
get => (string)GetValue(ViewNameProperty);
set => SetValue(ViewNameProperty, value);
}
#endregion
private void TabContentView_Loaded(object sender, RoutedEventArgs e)
{
try
{
if (string.IsNullOrWhiteSpace(RegionName))
return;
_regionManager = ContainerLocator.Current.Resolve();
// 确保 region/manager 设置在后续导航前准备好(但不要重复注册 region 这里)
// We will call PrepareRegionForRegistration inside EnsureNavigateIfNeeded before actual registration.
EnsureNavigateIfNeeded();
}
catch (Exception ex)
{
Debug.WriteLine($"TabContentView_Loaded 出错: {ex.Message}");
}
}
private void TabContentView_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
=> EnsureNavigateIfNeeded();
private void TabContentView_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
=> EnsureNavigateIfNeeded();
private void EnsureNavigateIfNeeded()
{
try
{
if (_navigated)
return;
if (string.IsNullOrWhiteSpace(RegionName) || string.IsNullOrWhiteSpace(ViewName))
return;
if (!IsLoaded || !IsVisible)
return;
if (_regionManager == null)
_regionManager = ContainerLocator.Current.Resolve();
// 在注册 region 之前准备 host(清理旧 region 与清空 Content),避免 Prism 抛 Content 非空异常
PrepareRegionForRegistration();
// 取消之前挂起的导航(保证最后一次胜出)
if (_pendingNavigationOp != null && _pendingNavigationOp.Status == DispatcherOperationStatus.Pending)
{
Debug.WriteLine($"取消挂起导航: region={RegionName}, view={ViewName}");
_pendingNavigationOp.Abort();
_pendingNavigationOp = null;
}
var desiredView = ViewName;
var desiredRegion = RegionName;
_pendingNavigationOp = Dispatcher.BeginInvoke(new Action(() =>
{
try
{
if (_regionManager == null)
_regionManager = ContainerLocator.Current.Resolve();
// 现在把 PART_ContentHost 注册为一个 region(设置 RegionName/RegionManager)
// 注意:如果前面清理正确,这里不会再触发 ContentControl already has content 错误
RegionManager.SetRegionName(PART_ContentHost, desiredRegion);
RegionManager.SetRegionManager(PART_ContentHost, _regionManager);
Debug.WriteLine($"开始 RequestNavigate -> region={desiredRegion}, view={desiredView}");
_regionManager.RequestNavigate(desiredRegion, desiredView, result =>
{
try
{
if (result.Success == true)
{
_navigated = true;
Debug.WriteLine($"导航成功: region={desiredRegion}, view={desiredView}");
}
else
{
_navigated = false;
Debug.WriteLine($"导航失败: region={desiredRegion}, view={desiredView}, error={result.Exception?.Message}");
}
}
catch (Exception ex)
{
_navigated = false;
Debug.WriteLine($"导航回调异常: {ex.Message}");
}
});
}
catch (Exception ex)
{
Debug.WriteLine($"调度导航异常: {ex.Message}");
}
finally
{
_pendingNavigationOp = null;
}
}), DispatcherPriority.Background);
Debug.WriteLine($"调度导航: Region={RegionName}, View={ViewName}, Loaded={IsLoaded}, Visible={IsVisible}, navigated={_navigated}");
}
catch (Exception ex)
{
Debug.WriteLine($"EnsureNavigateIfNeeded 异常: {ex.Message}");
}
}
///
/// 在注册 region 之前清理宿主控件与 RegionManager 中可能残留的 region。
/// 这一步是防止 Prism 在 adapt 时因为 ContentControl.Content 非空而抛异常。
///
private void PrepareRegionForRegistration()
{
try
{
// 如果 RegionManager 中已存在同名 region,则先移除它(并 RemoveAll 内容)
if (_regionManager != null && _regionManager.Regions.ContainsRegionWithName(RegionName))
{
try
{
var existing = _regionManager.Regions[RegionName];
existing.RemoveAll();
_regionManager.Regions.Remove(RegionName);
Debug.WriteLine($"已移除旧 region: {RegionName}");
}
catch (Exception ex)
{
Debug.WriteLine($"移除旧 region 发生异常: {ex.Message}");
}
}
// 如果宿主 ContentControl 已经有内容,清空它(很关键)
if (PART_ContentHost != null && PART_ContentHost.Content != null)
{
Debug.WriteLine($"清空 PART_ContentHost.Content (原内容类型: {PART_ContentHost.Content.GetType().Name})");
PART_ContentHost.Content = null;
}
}
catch (Exception ex)
{
Debug.WriteLine($"PrepareRegionForRegistration 异常: {ex.Message}");
}
}
private void TabContentView_Unloaded(object sender, RoutedEventArgs e)
{
try
{
// 取消挂起导航
if (_pendingNavigationOp != null && _pendingNavigationOp.Status == DispatcherOperationStatus.Pending)
{
_pendingNavigationOp.Abort();
_pendingNavigationOp = null;
}
// 清理 region 与宿主内容
if (!string.IsNullOrWhiteSpace(RegionName))
{
var rm = _regionManager ?? ContainerLocator.Current.Resolve();
try
{
if (rm != null && rm.Regions.ContainsRegionWithName(RegionName))
{
var region = rm.Regions[RegionName];
region.RemoveAll();
rm.Regions.Remove(RegionName);
Debug.WriteLine($"卸载并移除 region: {RegionName}");
}
}
catch (Exception ex)
{
Debug.WriteLine($"TabContentView_Unloaded 清理 region 异常: {ex.Message}");
}
}
if (PART_ContentHost != null && PART_ContentHost.Content != null)
{
PART_ContentHost.Content = null;
Debug.WriteLine($"Unloaded: 清空 PART_ContentHost.Content");
}
}
catch (Exception ex)
{
Debug.WriteLine($"TabContentView_Unloaded 清理异常: {ex.Message}");
}
finally
{
_navigated = false;
}
}
private static void OnRegionOrViewNameChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is TabContentView tc)
{
// 新参数到来,允许再次导航
tc._navigated = false;
// 取消旧挂起导航
if (tc._pendingNavigationOp != null && tc._pendingNavigationOp.Status == DispatcherOperationStatus.Pending)
{
tc._pendingNavigationOp.Abort();
tc._pendingNavigationOp = null;
}
// 尝试导航(这一调用会在 Loaded/可见时真正执行)
tc.EnsureNavigateIfNeeded();
}
}
}
}