NavisworksTransport/src/UI/WPF/ViewModels/AliasNodeViewModel.cs
tian d358c31a7d feat: inline editing with click-to-edit, TextBox overlay, Focus+SelectAll
- Grid overlay: TextBox covers TextBlock when editing (no more dual display)
- EditValue property: auto-initialized to DisplayName on edit start
- Click on already-selected node enters inline edit (PreviewMouseLeftButtonDown)
- Right-click auto-selects node before context menu
- TextBox IsVisibleChanged: Focus + SelectAll on Loaded priority
- XAML Visibility moved to Style setter (fix DataTrigger precedence)
- Light yellow background (#FFFFFDE6)
2026-05-31 15:52:03 +08:00

134 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 System;
using System.ComponentModel;
using System.Windows.Input;
using Autodesk.Navisworks.Api;
namespace NavisworksTransport.UI.WPF.ViewModels
{
/// <summary>
/// 别名树单节点 ViewModel。
/// 支持 INotifyPropertyChanged 以驱动 TreeView 实时更新。
/// </summary>
public class AliasNodeViewModel : INotifyPropertyChanged
{
private string _displayName;
private string _originalName;
private string _alias;
private bool _isEditing;
private bool _isOrphan;
private bool _hasAlias;
private int _childCount;
/// <summary>节点的序列化标识 key</summary>
public string NodeKey { get; set; }
/// <summary>Navisworks ModelItem 引用(用于选中同步的比较)</summary>
public Autodesk.Navisworks.Api.ModelItem ModelItem { get; set; }
/// <summary>当前显示文本(别名优先,无别名回退到原名)</summary>
public string DisplayName
{
get => _displayName;
set { _displayName = value; OnPropertyChanged(nameof(DisplayName)); }
}
/// <summary>Navisworks 原始名称(只读)</summary>
public string OriginalName
{
get => _originalName;
set { _originalName = value; OnPropertyChanged(nameof(OriginalName)); }
}
/// <summary>用户别名</summary>
public string Alias
{
get => _alias;
set
{
_alias = value;
HasAlias = !string.IsNullOrEmpty(value);
// 更新显示文本
DisplayName = HasAlias ? value : (OriginalName ?? "?");
OnPropertyChanged(nameof(Alias));
}
}
/// <summary>是否处于就地编辑状态</summary>
public bool IsEditing
{
get => _isEditing;
set
{
if (_isEditing == value) return;
_isEditing = value;
OnPropertyChanged(nameof(IsEditing));
// 进入编辑时初始化 EditValue 为当前显示名
if (value)
EditValue = DisplayName;
}
}
/// <summary>编辑框的临时文本(进入编辑时初始化为 DisplayName</summary>
public string EditValue
{
get => _editValue;
set { _editValue = value; OnPropertyChanged(nameof(EditValue)); }
}
private string _editValue;
/// <summary>是否孤儿节点(模型结构变化后无法定位)</summary>
public bool IsOrphan
{
get => _isOrphan;
set { _isOrphan = value; OnPropertyChanged(nameof(IsOrphan)); }
}
/// <summary>是否有别名</summary>
public bool HasAlias
{
get => _hasAlias;
set { _hasAlias = value; OnPropertyChanged(nameof(HasAlias)); }
}
/// <summary>子节点数量(用于展开箭头)</summary>
public int ChildCount
{
get => _childCount;
set { _childCount = value; OnPropertyChanged(nameof(ChildCount)); OnPropertyChanged(nameof(HasChildren)); }
}
/// <summary>是否有子节点</summary>
public bool HasChildren => ChildCount > 0;
/// <summary>子节点集合</summary>
public System.Collections.ObjectModel.ObservableCollection<AliasNodeViewModel> Children { get; }
= new System.Collections.ObjectModel.ObservableCollection<AliasNodeViewModel>();
/// <summary>父节点引用(用于回溯路径)</summary>
public AliasNodeViewModel Parent { get; set; }
public AliasNodeViewModel()
{
StartEditCommand = new RelayCommand(() => IsEditing = true);
}
/// <summary>启动内联编辑的命令</summary>
public ICommand StartEditCommand { get; }
/// <summary>
/// 刷新显示文本(别名变更新调用)
/// </summary>
public void RefreshDisplay()
{
DisplayName = HasAlias ? Alias : (OriginalName ?? "?");
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}