using System; using System.Collections.Generic; using System.Linq; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using GalaSoft.MvvmLight; using GalaSoft.MvvmLight.Views; using SubCabinetSolution.Views; namespace SubCabinetSolution.Utils { public class NavigationService : ViewModelBase, INavigationService { private readonly Dictionary<string, Uri> _pagesByKey; private readonly List<string> _historic; private string _currentPageKey; #region Properties public string CurrentPageKey { get => _currentPageKey; private set { Set(() => CurrentPageKey, ref _currentPageKey, value); } } public object Parameter { get; private set; } #endregion #region Ctors and Methods public NavigationService() { _pagesByKey = new Dictionary<string, Uri>(); _historic = new List<string>(); } public void GoBack() { if (_historic.Count <= 1) return; _historic.RemoveAt(_historic.Count - 1); NavigateTo(_historic.Last(), "Back"); } public void NavigateTo(string pageKey) { NavigateTo(pageKey, "Next"); } public virtual void NavigateTo(string pageKey, object parameter) { lock (_pagesByKey) { if (!_pagesByKey.ContainsKey(pageKey)) { throw new ArgumentException($@"No such page: {pageKey} ", nameof(pageKey)); } // 设置应用主窗口,name要注意和xaml保持一致 var cabinetWindow = Application.Current.Windows .Cast<Window>() .FirstOrDefault(window => window is CabinetWindow) as CabinetWindow; if (GetDescendantFromName(cabinetWindow, "CabinetFunctionFrame") is Frame frame) { frame.Source = _pagesByKey[pageKey]; } Parameter = parameter; if (parameter.ToString().Equals("Next")) { _historic.Add(pageKey); } CurrentPageKey = pageKey; } } public void Configure(string key, Uri pageType) { lock (_pagesByKey) { if (_pagesByKey.ContainsKey(key)) { _pagesByKey[key] = pageType; } else { _pagesByKey.Add(key, pageType); } } } private static FrameworkElement GetDescendantFromName(DependencyObject parent, string name) { var count = VisualTreeHelper.GetChildrenCount(parent); if (count < 1) { return null; } for (var i = 0; i < count; i++) { if (!(VisualTreeHelper.GetChild(parent, i) is FrameworkElement frameworkElement)) continue; if (frameworkElement.Name == name) { return frameworkElement; } frameworkElement = GetDescendantFromName(frameworkElement, name); if (frameworkElement != null) { return frameworkElement; } } return null; } #endregion } }