弹窗优化
This commit is contained in:
@@ -27,7 +27,7 @@ namespace DeviceEditModule.ViewModels
|
|||||||
/// <summary>所有 Tab 项集合,绑定到标签条的 ItemsControl。</summary>
|
/// <summary>所有 Tab 项集合,绑定到标签条的 ItemsControl。</summary>
|
||||||
public ObservableCollection<DialogTabItemVM> TagItems { get; } = new();
|
public ObservableCollection<DialogTabItemVM> TagItems { get; } = new();
|
||||||
|
|
||||||
/// <summary>以 Tab 标题为 key 追踪已打开的 Tab,防止重复打开。</summary>
|
/// <summary>以设备指纹为 key 追踪已打开的 Tab,防止同一物理设备重复打开。</summary>
|
||||||
private readonly Dictionary<string, DialogTabItemVM> _tabDictionary = new();
|
private readonly Dictionary<string, DialogTabItemVM> _tabDictionary = new();
|
||||||
|
|
||||||
private DialogTabItemVM? _selectedTag;
|
private DialogTabItemVM? _selectedTag;
|
||||||
@@ -87,11 +87,11 @@ namespace DeviceEditModule.ViewModels
|
|||||||
|
|
||||||
#region Tab 管理
|
#region Tab 管理
|
||||||
|
|
||||||
/// <summary>收到事件:若 Tab 已存在则激活,否则创建并追加到集合。</summary>
|
/// <summary>收到事件:若指纹已存在则激活,否则创建并追加到集合。</summary>
|
||||||
private void OnAddTab(DialogTabInfo info)
|
private void OnAddTab(DialogTabInfo info)
|
||||||
{
|
{
|
||||||
// 已有相同标题的 Tab → 直接激活,不重复创建
|
// 已有相同指纹的 Tab → 直接激活,不重复创建
|
||||||
if (_tabDictionary.TryGetValue(info.Title, out var existing))
|
if (!string.IsNullOrEmpty(info.Fingerprint) && _tabDictionary.TryGetValue(info.Fingerprint, out var existing))
|
||||||
{
|
{
|
||||||
ActivateTab(existing);
|
ActivateTab(existing);
|
||||||
return;
|
return;
|
||||||
@@ -99,11 +99,14 @@ namespace DeviceEditModule.ViewModels
|
|||||||
|
|
||||||
var tab = new DialogTabItemVM(OnSelectTab, OnCloseTab)
|
var tab = new DialogTabItemVM(OnSelectTab, OnCloseTab)
|
||||||
{
|
{
|
||||||
Title = info.Title,
|
Title = info.Title,
|
||||||
Content = info.Content
|
Fingerprint = info.Fingerprint,
|
||||||
|
Content = info.Content
|
||||||
};
|
};
|
||||||
|
|
||||||
_tabDictionary[info.Title] = tab;
|
if (!string.IsNullOrEmpty(info.Fingerprint))
|
||||||
|
_tabDictionary[info.Fingerprint] = tab;
|
||||||
|
|
||||||
TagItems.Add(tab);
|
TagItems.Add(tab);
|
||||||
RaisePropertyChanged(nameof(HasNoTabs));
|
RaisePropertyChanged(nameof(HasNoTabs));
|
||||||
ActivateTab(tab);
|
ActivateTab(tab);
|
||||||
@@ -116,7 +119,8 @@ namespace DeviceEditModule.ViewModels
|
|||||||
private void OnCloseTab(DialogTabItemVM tab)
|
private void OnCloseTab(DialogTabItemVM tab)
|
||||||
{
|
{
|
||||||
int idx = TagItems.IndexOf(tab);
|
int idx = TagItems.IndexOf(tab);
|
||||||
_tabDictionary.Remove(tab.Title);
|
if (!string.IsNullOrEmpty(tab.Fingerprint))
|
||||||
|
_tabDictionary.Remove(tab.Fingerprint);
|
||||||
TagItems.Remove(tab);
|
TagItems.Remove(tab);
|
||||||
RaisePropertyChanged(nameof(HasNoTabs));
|
RaisePropertyChanged(nameof(HasNoTabs));
|
||||||
|
|
||||||
|
|||||||
@@ -147,11 +147,14 @@ namespace TestingModule.ViewModels
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 4. 发布事件 → DialogMangerViewModel 接收后将此 View 添加为 Tab
|
// 4. 发布事件 → DialogMangerViewModel 接收后将此 View 添加为 Tab
|
||||||
// 标题格式:{当前作用域} - {设备名称},作为全局唯一 Tab 标识
|
// 标题格式:{当前作用域} - {设备名称}
|
||||||
|
// 去重依据:设备硬件指纹(同一物理设备不重复打开)
|
||||||
|
var fingerprint = DeviceManager.ExtractHardwareFingerprint(SelectedDevice);
|
||||||
_eventAggregator.GetEvent<AddDialogTabEvent>().Publish(new DialogTabInfo
|
_eventAggregator.GetEvent<AddDialogTabEvent>().Publish(new DialogTabInfo
|
||||||
{
|
{
|
||||||
Title = $"{_globalInfo.CurrentScope} - {SelectedDevice.DeviceName}",
|
Title = $"{_globalInfo.CurrentScope} - {SelectedDevice.DeviceName}",
|
||||||
Content = view
|
Fingerprint = fingerprint,
|
||||||
|
Content = view
|
||||||
});
|
});
|
||||||
|
|
||||||
// 5. 将窗口置顶(确保用户看到新增的 Tab)
|
// 5. 将窗口置顶(确保用户看到新增的 Tab)
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ namespace UIShare.GlobalVariable
|
|||||||
/// 根据设备配置提取唯一的硬件指纹字符串。
|
/// 根据设备配置提取唯一的硬件指纹字符串。
|
||||||
/// <para>Tcp → "Tcp:IP:Port";Serial → "Serial:PortName";无法识别则返回空字符串。</para>
|
/// <para>Tcp → "Tcp:IP:Port";Serial → "Serial:PortName";无法识别则返回空字符串。</para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static string ExtractHardwareFingerprint(DeviceInfoVM config)
|
public static string ExtractHardwareFingerprint(DeviceInfoVM config)
|
||||||
{
|
{
|
||||||
if (string.Equals(config.ConnectionType, "Tcp", StringComparison.OrdinalIgnoreCase)
|
if (string.Equals(config.ConnectionType, "Tcp", StringComparison.OrdinalIgnoreCase)
|
||||||
&& config.TcpConfig != null)
|
&& config.TcpConfig != null)
|
||||||
|
|||||||
@@ -10,6 +10,12 @@ namespace UIShare.UIViewModel
|
|||||||
/// <summary>Tab 标题(显示在标签页上)。</summary>
|
/// <summary>Tab 标题(显示在标签页上)。</summary>
|
||||||
public string Title { get; set; } = string.Empty;
|
public string Title { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设备硬件指纹(如 "Tcp:192.168.1.100:502"),用于去重判断,
|
||||||
|
/// 防止同一物理设备被重复打开多个 Tab。
|
||||||
|
/// </summary>
|
||||||
|
public string Fingerprint { get; set; } = string.Empty;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Tab 内容:传入一个已实例化的 <see cref="System.Windows.FrameworkElement"/>(通常是 UserControl),
|
/// Tab 内容:传入一个已实例化的 <see cref="System.Windows.FrameworkElement"/>(通常是 UserControl),
|
||||||
/// 由 ContentControl 直接承载展示。
|
/// 由 ContentControl 直接承载展示。
|
||||||
|
|||||||
@@ -21,6 +21,14 @@ namespace DeviceEditModule.ViewModels
|
|||||||
set => SetProperty(ref _title, value);
|
set => SetProperty(ref _title, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string _fingerprint = string.Empty;
|
||||||
|
/// <summary>设备硬件指纹,用于去重字典的 Key。</summary>
|
||||||
|
public string Fingerprint
|
||||||
|
{
|
||||||
|
get => _fingerprint;
|
||||||
|
set => SetProperty(ref _fingerprint, value);
|
||||||
|
}
|
||||||
|
|
||||||
private object? _content;
|
private object? _content;
|
||||||
/// <summary>Tab 内容区域(通常为 UserControl 实例)。</summary>
|
/// <summary>Tab 内容区域(通常为 UserControl 实例)。</summary>
|
||||||
public object? Content
|
public object? Content
|
||||||
|
|||||||
Reference in New Issue
Block a user