- 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)
134 lines
4.4 KiB
C#
134 lines
4.4 KiB
C#
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));
|
||
}
|
||
}
|
||
}
|