添加项目文件。

This commit is contained in:
“hsc”
2026-07-29 13:12:27 +08:00
parent d6da766e2d
commit 8cf45d36b9
297 changed files with 35814 additions and 0 deletions

View File

@@ -0,0 +1,153 @@
using Prism.Commands;
using Prism.Ioc;
using System;
using System.Collections.Generic;
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();
/// <summary>以设备指纹为 key 追踪已打开的 Tab防止同一物理设备重复打开。</summary>
private readonly Dictionary<string, DialogTabItemVM> _tabDictionary = 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释放内容引用并清除去重字典
_tabDictionary.Clear();
TagItems.Clear();
SelectedTag = null;
RequestClose.Invoke();
}
#endregion
#region Tab
/// <summary>收到事件:若指纹已存在则激活,否则创建并追加到集合。</summary>
private void OnAddTab(DialogTabInfo info)
{
// 已有相同指纹的 Tab → 直接激活,不重复创建
if (!string.IsNullOrEmpty(info.Fingerprint) && _tabDictionary.TryGetValue(info.Fingerprint, out var existing))
{
ActivateTab(existing);
return;
}
var tab = new DialogTabItemVM(OnSelectTab, OnCloseTab)
{
Title = info.Title,
Fingerprint = info.Fingerprint,
Content = info.Content
};
if (!string.IsNullOrEmpty(info.Fingerprint))
_tabDictionary[info.Fingerprint] = tab;
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);
if (!string.IsNullOrEmpty(tab.Fingerprint))
_tabDictionary.Remove(tab.Fingerprint);
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);
}
}
}