设备编辑管理界面

This commit is contained in:
hsc
2026-06-12 10:00:13 +08:00
parent ffb22e1f20
commit 02d9923474
23 changed files with 2098 additions and 16 deletions

View File

@@ -0,0 +1,135 @@
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);
}
}
}