using FWindSoft.Data; using System.Collections.ObjectModel; using System.Linq; using System.Windows; using System.Windows.Controls; using System.Windows.Input; namespace FWindSoft.Wpf.Controls { /* * 暂时先不支持内容给窗体赋值 */ //[ContentProperty("WChildren")] [TemplatePart(Name = PART_Child, Type = typeof(NavigationBar))] public class NavigationBar : Control { #region 附加属性 /// /// 窗体启动参数,根据Parameter在load中初始化 /// public static readonly DependencyProperty ParameterProperty = DependencyProperty.RegisterAttached("Parameter", typeof(NParameter), typeof(NavigationBar), new PropertyMetadata(null, null)); [AttachedPropertyBrowsableForType(typeof(NChildWindow))] public static NParameter GetParameter(DependencyObject obj) { return obj.GetValue(ParameterProperty) as NParameter; } [AttachedPropertyBrowsableForType(typeof(NChildWindow))] public static void SetParameter(DependencyObject obj, object value) { obj.SetValue(ParameterProperty, value); } #endregion #region 静态信息管理 private static NavigationBar m_CurrentNavigation; /// /// 当前导航信息 /// public static NavigationBar CurrentNavigation { get { if (m_CurrentNavigation == null) { m_CurrentNavigation = new NavigationBar(); } return m_CurrentNavigation; } } #endregion static NavigationBar() { DefaultStyleKeyProperty.OverrideMetadata(typeof(NavigationBar), new FrameworkPropertyMetadata(typeof(NavigationBar))); Jump = new RoutedCommand("跳转", typeof(NavigationBar)); CommandManager.RegisterClassCommandBinding(typeof(NavigationBar), new CommandBinding(Jump, OnJumpCommand, CanExecuteJump)); GoBack = new RoutedCommand("返回", typeof(NavigationBar)); CommandManager.RegisterClassCommandBinding(typeof(NavigationBar), new CommandBinding(GoBack, OnGoBackCommand, CanExecuteGoBack)); } public NavigationBar() { NavigationItems = new ReadOnlyObservableCollection(m_NavigationItems = new ObservableCollection()); } public const string PART_Child = "PART_Child"; public override void OnApplyTemplate() { base.OnApplyTemplate(); ChildContainer = GetTemplateChild(PART_Child) as ScrollViewer; } private ScrollViewer ChildContainer{ get; set; } #region 依赖属性 public static readonly DependencyProperty ShowWindowProperty = DependencyProperty.Register("ShowWindow", typeof(NChildWindow), typeof(NavigationBar), new PropertyMetadata(null, null)); /// /// 关联显示属性集合 /// internal NChildWindow ShowWindow { get { return (NChildWindow)GetValue(ShowWindowProperty); } set { SetValue(ShowWindowProperty, value); } } private void RaiseChange() { ShowWindow = GetCurrentWindow(); //ShowWindow.InvalidateVisual(); this.GoBackVisible= this.NavigationItems != null && this.NavigationItems.Count > 1; if (this.NavigationItems != null) { this.NavigationItems.ToList().ForEach(i => i.Refresh()); } } #endregion #region 操作与队列相似 private ObservableCollection m_NavigationItems; public ReadOnlyObservableCollection NavigationItems { get; private set; } /// /// 添加导航项 /// /// private void AddNavigationItem(NavigationItem item) { this.m_NavigationItems.Add(item); RaiseChange(); } /// /// 移除导航项 /// /// private void RemoveNavigationItem(NavigationItem item) { var useItem = this.m_NavigationItems.LastOrDefault(p => p.Window ==item.Window); if (useItem != null) { var index=this.m_NavigationItems.IndexOf(useItem); var allItems = this.m_NavigationItems.ToList(); this.m_NavigationItems.Clear(); for (int i = 0; i < index; i++) { this.m_NavigationItems.Add(allItems[i]); } RaiseChange(); } } #endregion /* * 调用子窗体show方法,增加找到最近的一个赋值,也可以直接赋值 * 调用窗体的Close方法,移除找到最近的一个赋值 * * 导航样式为:当前:A-->B-->C */ public void Remove(NChildWindow window) { var nParameter = GetParameter(window); if (nParameter != null && nParameter.IsClear) { this.m_NavigationItems.Clear(); return; } RemoveNavigationItem(new NavigationItem(window)); } public void Add(NChildWindow window) { var nParameter = GetParameter(window); if (nParameter != null && nParameter.IsClear) { this.m_NavigationItems.Clear(); return; } AddNavigationItem(new NavigationItem(window)); // RaiseChange(); } /// /// 获取当前的窗体 /// /// public NChildWindow GetCurrentWindow() { if (this.m_NavigationItems == null || !this.m_NavigationItems.Any()) return DefaultWindow; return this.m_NavigationItems.LastOrDefault().Window; } /// /// 默认窗体 /// public NChildWindow DefaultWindow { get; set; } #region 跳转命令相关 /// /// 跳转命令 /// public static RoutedCommand Jump { get; private set; } private static void OnJumpCommand(object sender, ExecutedRoutedEventArgs e) { NavigationBar bar = sender as NavigationBar; if (bar != null) { NavigationItem item = e.Parameter as NavigationItem; //所谓跳转,移除跳转项目后面所有的选项 var index=bar.NavigationItems.IndexOf(item); if (index < bar.NavigationItems.Count - 1) { bar.RemoveNavigationItem(bar.NavigationItems[index + 1]); } } } private static void CanExecuteJump(object sender, CanExecuteRoutedEventArgs e) { NavigationBar bar = sender as NavigationBar; if (bar != null) { NavigationItem item = e.Parameter as NavigationItem; if (item == null || bar.NavigationItems.Last() == item) { e.CanExecute = false; return; } } e.CanExecute = true; } #endregion #region 返回相关 /// /// 跳转命令 /// public static RoutedCommand GoBack { get; private set; } private static void OnGoBackCommand(object sender, ExecutedRoutedEventArgs e) { NavigationBar bar = sender as NavigationBar; if (bar != null) { if (bar.NavigationItems != null && bar.NavigationItems.Count > 1) { NavigationItem item = bar.NavigationItems[bar.NavigationItems.Count - 2]; //所谓跳转,移除跳转项目后面所有的选项 var index = bar.NavigationItems.IndexOf(item); if (index < bar.NavigationItems.Count - 1) { bar.RemoveNavigationItem(bar.NavigationItems[index + 1]); } } } } private static void CanExecuteGoBack(object sender, CanExecuteRoutedEventArgs e) { NavigationBar bar = sender as NavigationBar; if (bar != null) { e.CanExecute = bar.GoBackVisible; } e.CanExecute = true; } public static readonly DependencyProperty GoBackVisibleProperty = DependencyProperty.Register("GoBackVisible", typeof(bool), typeof(NavigationBar), new PropertyMetadata(false, null)); /// /// 关联显示属性集合 /// internal bool GoBackVisible { get { return (bool)GetValue(GoBackVisibleProperty); } set { SetValue(GoBackVisibleProperty, value); } } #endregion #region 逐步扩展 /// /// 刷新存量窗体的加载状态【延迟到显示是起作用】 /// public void RefreshWindows() { for (int i = 0; i < this.m_NavigationItems.Count; i++) { var item = this.m_NavigationItems[i]; item.Window?.ResetLoadData(); } } /// /// 刷新上一个窗体状态 /// public void RefreshPreWinddow() { if (this.NavigationItems != null && this.NavigationItems.Count > 1) { NavigationItem item = this.NavigationItems[this.NavigationItems.Count - 2]; item.Window.ResetLoadData(); } } #endregion protected override void OnPreviewMouseWheel(MouseWheelEventArgs e) { base.OnPreviewMouseWheel(e); if (ChildContainer != null) { var uiElement = e.OriginalSource as UIElement; if (uiElement == null) { return; } var useScroll=uiElement.GetParentTypeSelf(); while (useScroll != null && useScroll.ComputedVerticalScrollBarVisibility == Visibility.Collapsed) { useScroll = useScroll.GetParentType(); } if (useScroll == ChildContainer) { var eventArg = new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta); eventArg.RoutedEvent = UIElement.MouseWheelEvent; eventArg.Source = this; ChildContainer.RaiseEvent(eventArg); } } } } /// /// 封装操作实体,直接将控件绑定到Items,将出现可是话树重叠的情况 /// public class NavigationItem:BasePropertyChanged { internal NavigationItem(NChildWindow window) { this.Window = window; } internal NavigationItem() { } public void Refresh() { RaisePropertyChanged(nameof(WindowDisplay)); } /// /// 导航窗体使用参数 /// //public NParameter NParameter { get; set; } /// /// 关联窗体 /// public NChildWindow Window { get; set; } /// /// 窗体描述 /// public string WindowDisplay { get { if (Window == null) return "Null"; return Window.Title; } } } }