Files
ADP/DeviceEditModule/ViewModels/DialogMangerViewModel.cs
2026-06-12 16:55:47 +08:00

136 lines
4.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Prism.Commands;
using Prism.Ioc;
using System;
using System.Collections.ObjectModel;
using System.Windows.Input;
using UIShare.PubEvent;
using UIShare.UIViewModel;
using UIShare.ViewModelBase;
namespace DeviceEditModule.ViewModels
{
/// <summary>
/// 弹窗管理器 ViewModel。
/// <para>
/// 职责:<br/>
/// 1. 订阅 <see cref="AddDialogTabEvent"/>,将外部弹窗注册为 Tab<br/>
/// 2. 维护 <see cref="TagItems"/> 集合,控制选中/关闭逻辑;<br/>
/// 3. 最小化:通过 <see cref="MinimizeRequested"/> 事件通知 View 执行 P/Invoke 窗口操作;<br/>
/// 4. 关闭:调用 <see cref="RequestClose"/>。
/// </para>
/// </summary>
public class DialogMangerViewModel : DialogViewModelBase, IDisposable
{
#region
/// <summary>所有 Tab 项集合,绑定到标签条的 ItemsControl。</summary>
public ObservableCollection<DialogTabItemVM> TagItems { get; } = new();
private DialogTabItemVM? _selectedTag;
/// <summary>当前激活的 Tab其 Content 显示在内容区。</summary>
public DialogTabItemVM? SelectedTag
{
get => _selectedTag;
set => SetProperty(ref _selectedTag, value);
}
/// <summary>是否没有任何 Tab用于绑定空状态提示的 Visibility。</summary>
public bool HasNoTabs => TagItems.Count == 0;
#endregion
#region
public ICommand MinimizeCommand { get; }
public ICommand CloseCommand { get; }
#endregion
#region
/// <summary>
/// View 订阅此事件后,在事件回调里执行 P/Invoke 最小化。
/// 这样 ViewModel 无需引用任何 UI 或 Win32 类型。
/// </summary>
public event EventHandler? MinimizeRequested;
public event EventHandler? RestoreRequested;
#endregion
public DialogMangerViewModel(IContainerProvider containerProvider) : base(containerProvider)
{
MinimizeCommand = new DelegateCommand(OnMinimize);
CloseCommand = new DelegateCommand(OnClose);
// 订阅来自其他模块的"添加 Tab"事件
_eventAggregator.GetEvent<AddDialogTabEvent>().Subscribe(OnAddTab, ThreadOption.UIThread);
_eventAggregator.GetEvent<CancelMinimizeEvent>().Subscribe(()=>RestoreRequested.Invoke(this, EventArgs.Empty));
}
#region
private void OnMinimize() => MinimizeRequested?.Invoke(this, EventArgs.Empty);
private void OnClose()
{
// 关闭前清空所有 Tab释放内容引用
TagItems.Clear();
SelectedTag = null;
RequestClose.Invoke();
}
#endregion
#region Tab
/// <summary>收到事件:创建 Tab 并追加到集合,自动切换选中。</summary>
private void OnAddTab(DialogTabInfo info)
{
var tab = new DialogTabItemVM(OnSelectTab, OnCloseTab)
{
Title = info.Title,
Content = info.Content
};
TagItems.Add(tab);
RaisePropertyChanged(nameof(HasNoTabs));
ActivateTab(tab);
}
/// <summary>激活(选中)指定 Tab其余全部取消选中。</summary>
private void OnSelectTab(DialogTabItemVM tab) => ActivateTab(tab);
/// <summary>关闭指定 Tab自动选中相邻 Tab或清空内容区。</summary>
private void OnCloseTab(DialogTabItemVM tab)
{
int idx = TagItems.IndexOf(tab);
TagItems.Remove(tab);
RaisePropertyChanged(nameof(HasNoTabs));
if (TagItems.Count == 0)
{
SelectedTag = null;
return;
}
// 优先选左侧邻 Tab无左侧则选当前索引已向左移一位
ActivateTab(TagItems[Math.Max(0, idx - 1)]);
}
private void ActivateTab(DialogTabItemVM tab)
{
foreach (var t in TagItems)
t.IsSelected = false;
tab.IsSelected = true;
SelectedTag = tab;
}
#endregion
public void Dispose()
{
_eventAggregator.GetEvent<AddDialogTabEvent>().Unsubscribe(OnAddTab);
}
}
}