//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(); } } } }