解决TreeView的TreeView_SelectedItemChanged事件被多次调用的问题
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
using AutoMapper;
|
using AutoMapper;
|
||||||
using DMS.Application.DTOs;
|
using DMS.Application.DTOs;
|
||||||
using DMS.Core.Models;
|
using DMS.Core.Models;
|
||||||
|
using DMS.Infrastructure.Models;
|
||||||
using DMS.WPF.ViewModels.Items;
|
using DMS.WPF.ViewModels.Items;
|
||||||
|
|
||||||
namespace DMS.WPF.Profiles
|
namespace DMS.WPF.Profiles
|
||||||
@@ -13,6 +14,8 @@ namespace DMS.WPF.Profiles
|
|||||||
.ReverseMap();
|
.ReverseMap();
|
||||||
CreateMap<Variable, VariableItemViewModel>()
|
CreateMap<Variable, VariableItemViewModel>()
|
||||||
.ReverseMap();
|
.ReverseMap();
|
||||||
|
CreateMap<OpcUaNode, OpcUaNodeItemViewModel>()
|
||||||
|
.ReverseMap();
|
||||||
CreateMap<VariableItemViewModel, VariableItemViewModel>();
|
CreateMap<VariableItemViewModel, VariableItemViewModel>();
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
|
using AutoMapper;
|
||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using CommunityToolkit.Mvvm.Input;
|
using CommunityToolkit.Mvvm.Input;
|
||||||
|
using DMS.Core.Enums;
|
||||||
|
using DMS.Core.Helper;
|
||||||
using DMS.Core.Models;
|
using DMS.Core.Models;
|
||||||
using DMS.Helper;
|
using DMS.Helper;
|
||||||
using DMS.Infrastructure.Interfaces.Services;
|
using DMS.Infrastructure.Interfaces.Services;
|
||||||
@@ -17,10 +20,10 @@ public partial class ImportOpcUaDialogViewModel : DialogViewModelBase<List<Varia
|
|||||||
private string _endpointUrl = "opc.tcp://127.0.0.1:4855"; // 默认值
|
private string _endpointUrl = "opc.tcp://127.0.0.1:4855"; // 默认值
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private OpcUaNode _rootOpcUaNode;
|
private OpcUaNodeItemViewModel _rootOpcUaNode;
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private ObservableCollection<Variable> _selectedNodeVariables;
|
private ObservableCollection<VariableItemViewModel> _selectedNodeVariables;
|
||||||
|
|
||||||
public List<Variable> SelectedVariables { get; set; } = new List<Variable>();
|
public List<Variable> SelectedVariables { get; set; } = new List<Variable>();
|
||||||
|
|
||||||
@@ -39,15 +42,15 @@ public partial class ImportOpcUaDialogViewModel : DialogViewModelBase<List<Varia
|
|||||||
private Session _session;
|
private Session _session;
|
||||||
|
|
||||||
private readonly IOpcUaService _opcUaService;
|
private readonly IOpcUaService _opcUaService;
|
||||||
|
private readonly IMapper _mapper;
|
||||||
private CancellationTokenSource _cancellationTokenSource;
|
private CancellationTokenSource _cancellationTokenSource;
|
||||||
|
|
||||||
public ImportOpcUaDialogViewModel(IOpcUaService opcUaService)
|
public ImportOpcUaDialogViewModel(IOpcUaService opcUaService,IMapper mapper)
|
||||||
{
|
{
|
||||||
//OpcUaNodes = new ObservableCollection<OpcUaNode>();
|
SelectedNodeVariables = new ObservableCollection<VariableItemViewModel>();
|
||||||
SelectedNodeVariables = new ObservableCollection<Variable>();
|
|
||||||
this._opcUaService = opcUaService;
|
this._opcUaService = opcUaService;
|
||||||
RootOpcUaNode = new OpcUaNode() { DisplayName = "根节点", NodeId = Objects.ObjectsFolder };
|
this._mapper = mapper;
|
||||||
|
RootOpcUaNode = new OpcUaNodeItemViewModel() { DisplayName = "根节点", NodeId = Objects.ObjectsFolder, IsExpanded = true };
|
||||||
_cancellationTokenSource = new CancellationTokenSource();
|
_cancellationTokenSource = new CancellationTokenSource();
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -65,6 +68,7 @@ public partial class ImportOpcUaDialogViewModel : DialogViewModelBase<List<Varia
|
|||||||
|
|
||||||
if (_opcUaService.IsConnected)
|
if (_opcUaService.IsConnected)
|
||||||
{
|
{
|
||||||
|
IsConnected=true;
|
||||||
ConnectButtonText = "已连接";
|
ConnectButtonText = "已连接";
|
||||||
IsConnectButtonEnabled = false;
|
IsConnectButtonEnabled = false;
|
||||||
}
|
}
|
||||||
@@ -72,7 +76,8 @@ public partial class ImportOpcUaDialogViewModel : DialogViewModelBase<List<Varia
|
|||||||
|
|
||||||
// 浏览根节点
|
// 浏览根节点
|
||||||
|
|
||||||
await _opcUaService.BrowseNode(RootOpcUaNode);
|
var childrens= await _opcUaService.BrowseNode(_mapper.Map<OpcUaNode>(RootOpcUaNode));
|
||||||
|
RootOpcUaNode.Children = _mapper.Map<ObservableCollection<OpcUaNodeItemViewModel>>(childrens);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -85,6 +90,18 @@ public partial class ImportOpcUaDialogViewModel : DialogViewModelBase<List<Varia
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[RelayCommand]
|
||||||
|
private async void PrimaryButton()
|
||||||
|
{
|
||||||
|
await _opcUaService.DisconnectAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
[RelayCommand]
|
||||||
|
private async void CloseButton()
|
||||||
|
{
|
||||||
|
await _opcUaService.DisconnectAsync();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 处理来自服务器的数据变化通知
|
/// 处理来自服务器的数据变化通知
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -97,176 +114,69 @@ public partial class ImportOpcUaDialogViewModel : DialogViewModelBase<List<Varia
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//private async Task BrowseNodes(ObservableCollection<OpcUaNode> nodes, NodeId parentNodeId)
|
|
||||||
//{
|
|
||||||
// try
|
|
||||||
// {
|
|
||||||
// Opc.Ua.ReferenceDescriptionCollection references;
|
|
||||||
// byte[] continuationPoint = null;
|
|
||||||
|
|
||||||
// _session.Browse(
|
|
||||||
// null, // RequestHeader
|
|
||||||
// new ViewDescription(),
|
|
||||||
// parentNodeId,
|
|
||||||
// 0u,
|
|
||||||
// BrowseDirection.Forward,
|
|
||||||
// Opc.Ua.ReferenceTypeIds.HierarchicalReferences,
|
|
||||||
// true,
|
|
||||||
// (uint)Opc.Ua.NodeClass.Object | (uint)Opc.Ua.NodeClass.Variable,
|
|
||||||
// out continuationPoint,
|
|
||||||
// out references
|
|
||||||
// );
|
|
||||||
|
|
||||||
// foreach (var rd in references)
|
private bool _isLoadingNodeVariables = false;
|
||||||
// {
|
|
||||||
// NodeType nodeType = NodeType.Folder; // 默认是文件夹
|
|
||||||
// if ((rd.NodeClass & NodeClass.Variable) != 0)
|
|
||||||
// {
|
|
||||||
// nodeType = NodeType.Variable;
|
|
||||||
// }
|
|
||||||
// else if ((rd.NodeClass & NodeClass.Object) != 0)
|
|
||||||
// {
|
|
||||||
// nodeType = NodeType.Object;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// var opcUaNode = new OpcUaNode(rd.DisplayName.Text, (NodeId)rd.NodeId, nodeType);
|
public async Task LoadNodeVariables(OpcUaNodeItemViewModel node)
|
||||||
// nodes.Add(opcUaNode);
|
|
||||||
|
|
||||||
// // 如果是文件夹或对象,添加一个虚拟子节点,用于懒加载
|
|
||||||
// if (nodeType == NodeType.Folder || nodeType == NodeType.Object)
|
|
||||||
// {
|
|
||||||
// opcUaNode.Children.Add(new OpcUaNode("Loading...", NodeId.Null, NodeType.Folder)); // 虚拟节点
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// catch (Exception ex)
|
|
||||||
// {
|
|
||||||
// NlogHelper.Error($"浏览 OPC UA 节点失败: {parentNodeId} - {ex.Message}", ex);
|
|
||||||
// NotificationHelper.ShowError($"浏览 OPC UA 节点失败: {parentNodeId} - {ex.Message}", ex);
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
//public async Task LoadNodeVariables(OpcUaNode node)
|
|
||||||
//{
|
|
||||||
//if (node.NodeType == NodeType.Variable)
|
|
||||||
//{
|
|
||||||
// // 如果是变量节点,直接显示它
|
|
||||||
// SelectedNodeVariables.Clear();
|
|
||||||
// SelectedNodeVariables.Add(new Variable
|
|
||||||
// {
|
|
||||||
// Name = node.DisplayName,
|
|
||||||
// NodeId = node.NodeId.ToString(),
|
|
||||||
// OpcUaNodeId = node.NodeId.ToString(),
|
|
||||||
// ProtocolType = ProtocolType.OpcUA,
|
|
||||||
// IsActive = true // 默认选中
|
|
||||||
// });
|
|
||||||
// return;
|
|
||||||
//}
|
|
||||||
|
|
||||||
//if (node.IsLoaded || node.IsLoading)
|
|
||||||
//{
|
|
||||||
// return; // 已经加载或正在加载
|
|
||||||
//}
|
|
||||||
|
|
||||||
//node.IsLoading = true;
|
|
||||||
//node.Children.Clear(); // 清除虚拟节点
|
|
||||||
|
|
||||||
//try
|
|
||||||
//{
|
|
||||||
// Opc.Ua.ReferenceDescriptionCollection references;
|
|
||||||
// byte[] continuationPoint = null;
|
|
||||||
|
|
||||||
// _session.Browse(
|
|
||||||
// null, // RequestHeader
|
|
||||||
// new ViewDescription(),
|
|
||||||
// node.NodeId,
|
|
||||||
// 0u,
|
|
||||||
// BrowseDirection.Forward,
|
|
||||||
// Opc.Ua.ReferenceTypeIds.HierarchicalReferences,
|
|
||||||
// true,
|
|
||||||
// (uint)Opc.Ua.NodeClass.Object | (uint)Opc.Ua.NodeClass.Variable,
|
|
||||||
// out continuationPoint,
|
|
||||||
// out references
|
|
||||||
// );
|
|
||||||
|
|
||||||
// foreach (var rd in references)
|
|
||||||
// {
|
|
||||||
// NodeType nodeType = NodeType.Folder;
|
|
||||||
// if ((rd.NodeClass & NodeClass.Variable) != 0)
|
|
||||||
// {
|
|
||||||
// nodeType = NodeType.Variable;
|
|
||||||
// }
|
|
||||||
// else if ((rd.NodeClass & NodeClass.Object) != 0)
|
|
||||||
// {
|
|
||||||
// nodeType = NodeType.Object;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// var opcUaNode = new OpcUaNode(rd.DisplayName.Text, (NodeId)rd.NodeId, nodeType);
|
|
||||||
// node.Children.Add(opcUaNode);
|
|
||||||
|
|
||||||
// if (nodeType == NodeType.Folder || nodeType == NodeType.Object)
|
|
||||||
// {
|
|
||||||
// opcUaNode.Children.Add(new OpcUaNode("Loading...", NodeId.Null, NodeType.Folder)); // 虚拟节点
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // 如果是变量,添加到右侧列表
|
|
||||||
// if (nodeType == NodeType.Variable)
|
|
||||||
// {
|
|
||||||
// // Read the DataType attribute
|
|
||||||
// ReadValueId readValueId = new ReadValueId
|
|
||||||
// {
|
|
||||||
// NodeId = opcUaNode.NodeId,
|
|
||||||
// AttributeId = Attributes.DataType,
|
|
||||||
// // You might need to specify IndexRange and DataEncoding if dealing with arrays or specific encodings
|
|
||||||
// };
|
|
||||||
|
|
||||||
// DataValueCollection results;
|
|
||||||
// DiagnosticInfoCollection diagnosticInfos;
|
|
||||||
|
|
||||||
// _session.Read(
|
|
||||||
// null, // RequestHeader
|
|
||||||
// 0, // MaxAge
|
|
||||||
// TimestampsToReturn.Source,
|
|
||||||
// new ReadValueIdCollection { readValueId },
|
|
||||||
// out results,
|
|
||||||
// out diagnosticInfos
|
|
||||||
// );
|
|
||||||
|
|
||||||
// string dataType = string.Empty;
|
|
||||||
|
|
||||||
// if (results != null && results.Count > 0 && results[0].Value != null)
|
|
||||||
// {
|
|
||||||
// // Convert the NodeId of the DataType to a readable string
|
|
||||||
// NodeId dataTypeNodeId = (NodeId)results[0].Value;
|
|
||||||
// dataType = _session.NodeCache.GetDisplayText(dataTypeNodeId);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// SelectedNodeVariables.Add(new Variable
|
|
||||||
// {
|
|
||||||
// Name = opcUaNode.DisplayName,
|
|
||||||
// OpcUaNodeId = opcUaNode.NodeId.ToString(),
|
|
||||||
// ProtocolType = ProtocolType.OpcUA,
|
|
||||||
// IsActive = true, // Default selected
|
|
||||||
// DataType = dataType // Assign the read DataType
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// node.IsLoaded = true;
|
|
||||||
//}
|
|
||||||
//catch (Exception ex)
|
|
||||||
//{
|
|
||||||
// NlogHelper.Error($"加载 OPC UA 节点变量失败: {node.NodeId} - {ex.Message}", ex);
|
|
||||||
// NotificationHelper.ShowError($"加载 OPC UA 节点变量失败: {node.NodeId} - {ex.Message}", ex);
|
|
||||||
//}
|
|
||||||
//finally
|
|
||||||
//{
|
|
||||||
// node.IsLoading = false;
|
|
||||||
//}
|
|
||||||
//}
|
|
||||||
|
|
||||||
public ObservableCollection<Variable> GetSelectedVariables()
|
|
||||||
{
|
{
|
||||||
return new ObservableCollection<Variable>(SelectedVariables);
|
// 防止重复加载
|
||||||
|
if (_isLoadingNodeVariables)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_isLoadingNodeVariables = true;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
SelectedNodeVariables.Clear();
|
||||||
|
|
||||||
|
if (node.NodeClass == NodeClass.Variable)
|
||||||
|
{
|
||||||
|
// 如果是变量节点,直接显示它
|
||||||
|
SelectedNodeVariables.Add(new VariableItemViewModel
|
||||||
|
{
|
||||||
|
Name = node.DisplayName,
|
||||||
|
OpcUaNodeId = node.NodeId.ToString(),
|
||||||
|
Protocol = ProtocolType.OpcUa,
|
||||||
|
IsActive = true // 默认选中
|
||||||
|
});
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 加载节点的子项
|
||||||
|
node.IsExpanded = true;
|
||||||
|
node.IsSelected = true;
|
||||||
|
|
||||||
|
var childrens = await _opcUaService.BrowseNode(_mapper.Map<OpcUaNode>(node));
|
||||||
|
foreach (var children in childrens)
|
||||||
|
{
|
||||||
|
var opcNodeItem = _mapper.Map<OpcUaNodeItemViewModel>(children);
|
||||||
|
if (children.NodeClass == NodeClass.Variable)
|
||||||
|
{
|
||||||
|
SelectedNodeVariables.Add(new VariableItemViewModel
|
||||||
|
{
|
||||||
|
Name = children.DisplayName, // 修正:使用子节点的显示名称
|
||||||
|
OpcUaNodeId = children.NodeId.ToString(),
|
||||||
|
Protocol = ProtocolType.OpcUa,
|
||||||
|
IsActive = true // 默认选中
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
node.Children.Add(opcNodeItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
NlogHelper.Error($"加载 OPC UA 节点变量失败: {node.NodeId} - {ex.Message}", ex);
|
||||||
|
NotificationHelper.ShowError($"加载 OPC UA 节点变量失败: {node.NodeId} - {ex.Message}", ex);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_isLoadingNodeVariables = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
49
DMS.WPF/ViewModels/Items/OpcUaNodeItemViewModel.cs
Normal file
49
DMS.WPF/ViewModels/Items/OpcUaNodeItemViewModel.cs
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
using DMS.Infrastructure.Models;
|
||||||
|
using Opc.Ua;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
|
||||||
|
namespace DMS.WPF.ViewModels.Items
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// OPC UA节点的视图模型。
|
||||||
|
/// </summary>
|
||||||
|
public partial class OpcUaNodeItemViewModel : ObservableObject
|
||||||
|
{
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private NodeId? _nodeId;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private string? _displayName;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private NodeClass _nodeClass;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private object? _value;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private OpcUaNodeItemViewModel? _parentNode;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private ObservableCollection<OpcUaNodeItemViewModel> _children = new ObservableCollection<OpcUaNodeItemViewModel>();
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private bool _isExpanded;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private bool _isSelected;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 默认构造函数(用于设计时支持)。
|
||||||
|
/// </summary>
|
||||||
|
public OpcUaNodeItemViewModel()
|
||||||
|
{
|
||||||
|
// 设计时数据支持
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
|
||||||
using Opc.Ua;
|
|
||||||
using System.Collections.ObjectModel;
|
|
||||||
|
|
||||||
namespace DMS.WPF.ViewModels.Items
|
|
||||||
{
|
|
||||||
public partial class OpcUaNodeViewModel : ObservableObject
|
|
||||||
{
|
|
||||||
[ObservableProperty]
|
|
||||||
private string _displayName;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private NodeId _nodeId;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private NodeType _nodeType;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private bool _isExpanded;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private bool _isLoading;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private bool _isLoaded;
|
|
||||||
|
|
||||||
public ObservableCollection<OpcUaNodeViewModel> Children { get; set; }
|
|
||||||
|
|
||||||
public OpcUaNodeViewModel(string displayName, NodeId nodeId, NodeType nodeType)
|
|
||||||
{
|
|
||||||
DisplayName = displayName;
|
|
||||||
NodeId = nodeId;
|
|
||||||
NodeType = nodeType;
|
|
||||||
Children = new ObservableCollection<OpcUaNodeViewModel>();
|
|
||||||
|
|
||||||
// 如果是文件夹或对象,添加一个虚拟子节点,用于懒加载
|
|
||||||
if (nodeType == NodeType.Folder || nodeType == NodeType.Object)
|
|
||||||
{
|
|
||||||
Children.Add(new OpcUaNodeViewModel("Loading...", NodeId.Null, NodeType.Folder)); // 虚拟节点
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum NodeType
|
|
||||||
{
|
|
||||||
Folder,
|
|
||||||
Object,
|
|
||||||
Variable
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -8,10 +8,10 @@
|
|||||||
xmlns:vm="clr-namespace:DMS.WPF.ViewModels.Dialogs"
|
xmlns:vm="clr-namespace:DMS.WPF.ViewModels.Dialogs"
|
||||||
Title="从OPC UA服务器导入变量"
|
Title="从OPC UA服务器导入变量"
|
||||||
d:DataContext="{d:DesignInstance vm:ImportOpcUaDialogViewModel}"
|
d:DataContext="{d:DesignInstance vm:ImportOpcUaDialogViewModel}"
|
||||||
PrimaryButtonClick="ContentDialog_PrimaryButtonClick"
|
CloseButtonCommand="{Binding CloseButtonCommand}"
|
||||||
|
CloseButtonText="取消"
|
||||||
|
PrimaryButtonCommand="{Binding PrimaryButtonCommand}"
|
||||||
PrimaryButtonText="导入"
|
PrimaryButtonText="导入"
|
||||||
SecondaryButtonClick="ContentDialog_SecondaryButtonClick"
|
|
||||||
SecondaryButtonText="取消"
|
|
||||||
mc:Ignorable="d">
|
mc:Ignorable="d">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
@@ -47,6 +47,7 @@
|
|||||||
|
|
||||||
<!-- 节点树 -->
|
<!-- 节点树 -->
|
||||||
<TreeView
|
<TreeView
|
||||||
|
Name="treeView"
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Grid.Column="0"
|
Grid.Column="0"
|
||||||
Margin="0,0,10,0"
|
Margin="0,0,10,0"
|
||||||
@@ -67,6 +68,18 @@
|
|||||||
<TextBlock Text="{Binding DisplayName}" />
|
<TextBlock Text="{Binding DisplayName}" />
|
||||||
</HierarchicalDataTemplate>
|
</HierarchicalDataTemplate>
|
||||||
</TreeView.ItemTemplate>
|
</TreeView.ItemTemplate>
|
||||||
|
<TreeView.ItemContainerStyle>
|
||||||
|
<Style BasedOn="{StaticResource {x:Type TreeViewItem}}" TargetType="{x:Type TreeViewItem}">
|
||||||
|
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
|
||||||
|
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
|
||||||
|
<Setter Property="FontWeight" Value="Normal" />
|
||||||
|
<Style.Triggers>
|
||||||
|
<Trigger Property="IsSelected" Value="True">
|
||||||
|
<Setter Property="FontWeight" Value="Bold" />
|
||||||
|
</Trigger>
|
||||||
|
</Style.Triggers>
|
||||||
|
</Style>
|
||||||
|
</TreeView.ItemContainerStyle>
|
||||||
</TreeView>
|
</TreeView>
|
||||||
|
|
||||||
<!-- 变量列表 -->
|
<!-- 变量列表 -->
|
||||||
|
|||||||
@@ -1,7 +1,13 @@
|
|||||||
|
using DMS.Helper;
|
||||||
|
using DMS.Services;
|
||||||
|
using DMS.WPF.Helper;
|
||||||
|
using DMS.WPF.ViewModels.Dialogs;
|
||||||
|
using DMS.WPF.ViewModels.Items;
|
||||||
|
using iNKORE.UI.WPF.Modern.Controls;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using DMS.WPF.ViewModels.Dialogs;
|
using System.Windows.Threading;
|
||||||
using iNKORE.UI.WPF.Modern.Controls;
|
|
||||||
|
|
||||||
namespace DMS.WPF.Views.Dialogs;
|
namespace DMS.WPF.Views.Dialogs;
|
||||||
|
|
||||||
@@ -10,32 +16,58 @@ namespace DMS.WPF.Views.Dialogs;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class ImportOpcUaDialog : ContentDialog
|
public partial class ImportOpcUaDialog : ContentDialog
|
||||||
{
|
{
|
||||||
|
private const int ContentAreaMaxWidth = 1200;
|
||||||
|
private const int ContentAreaMaxHeight = 800;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public ImportOpcUaDialog()
|
public ImportOpcUaDialog()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
this.Opened += OnOpened;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ContentDialog_PrimaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
|
private void OnOpened(ContentDialog sender, ContentDialogOpenedEventArgs args)
|
||||||
{
|
{
|
||||||
// 在这里处理导入逻辑,例如获取选中的变量
|
//修改对话框内容的最大宽度和最大高度
|
||||||
// ViewModel.ImportSelectedVariables();
|
var backgroundElementBorder = VisualTreeFinder.FindVisualChildByName<Border>(this, "BackgroundElement");
|
||||||
}
|
backgroundElementBorder.MaxWidth = ContentAreaMaxWidth;
|
||||||
|
backgroundElementBorder.MaxWidth = ContentAreaMaxHeight;
|
||||||
private void ContentDialog_SecondaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
|
|
||||||
{
|
|
||||||
// 处理取消逻辑
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void TreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
|
private async void TreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
|
||||||
{
|
{
|
||||||
// if (e.NewValue is OpcUaNode selectedNode)
|
try
|
||||||
// {
|
{
|
||||||
// await ViewModel.LoadNodeVariables(selectedNode);
|
//防止多次调用
|
||||||
// }
|
object selectedObj = this.treeView.SelectedItem;
|
||||||
|
if (SelectedItemChanged != null)
|
||||||
|
{
|
||||||
|
Dispatcher.BeginInvoke(DispatcherPriority.Background, SelectedItemChanged, selectedObj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
NotificationHelper.ShowError($"选择节点时发生了错误:{ex.Message}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//事件
|
||||||
|
public async void SelectedItemChanged(object selectedObj)
|
||||||
|
{
|
||||||
|
if (selectedObj is OpcUaNodeItemViewModel selectedNode)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (this.DataContext is ImportOpcUaDialogViewModel viewModel)
|
||||||
|
{
|
||||||
|
await viewModel.LoadNodeVariables(selectedNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void Selector_OnSelectionChanged(object sender, SelectionChangedEventArgs args)
|
private void Selector_OnSelectionChanged(object sender, SelectionChangedEventArgs args)
|
||||||
{
|
{
|
||||||
// if (args.AddedItems!=null && args.AddedItems.Count>0)
|
// if (args.AddedItems!=null && args.AddedItems.Count>0)
|
||||||
|
|||||||
Reference in New Issue
Block a user