105040 优化与完善功能实现

重构和功能增强

删除了无用的注释和文件,添加了新的属性和方法,调整了窗口布局和视图模型引用。具体更改包括:
- 删除 `MotorModel.cs` 中 `_motorPower` 的 `inheritdoc` 注释。
- `ScanCableModel.cs` 中添加 `Id` 属性及其私有字段 `_id`。
- 更新 `Sinvo.EplanHpD.Plugin.WPFUI.csproj`,删除 `Utils\DrawPDFHelper.cs` 和 `Utils\MessageSend.cs` 的编译引用,添加 `ViewModel\LayoutHelperViewModel.cs` 的编译引用,并添加 `KissStudio.DotNetDetour` 包的引用。
- 删除 `DrawPDFHelper.cs` 和 `MessageSend.cs` 文件内容。
- `LayoutHelperWindow.xaml` 中增加 `viewmodel` 命名空间引用,调整窗口高度和最小高度,设置 `d:DataContext`,并在窗口加载时调用 `GlowWindow_Loaded` 方法,修改部分 `TextBlock` 和 `ListView` 的内容绑定。
- `LayoutHelperWindow.xaml.cs` 中添加 `LayoutHelperViewModel` 的引用,并在构造函数中初始化 `viewModel`,设置 `DataContext`,在 `OnInit` 方法中调用 `GetMotorCables`,添加 `GlowWindow_Loaded`、`PrevBtn_Click` 和 `NextBtn_Click` 方法。
- `LectotypeWindow.xaml.cs` 中修改 `StartLayoutBtn_Click` 方法,传递 `motorIds` 给 `LayoutHelperWindow` 的构造函数。
- `ScannerViewModel.cs` 中添加 `Id` 属性的赋值,修改 `PerformSearch` 方法以根据 `Imprint` 进行搜索,添加 `ToSourceById` 方法用于根据 `occId` 定位线缆。
- 在 `DesignPluginEntry.cs`、`PluginEntry.cs` 和 `ScanPluginEntry.cs` 中添加 `Sinvo.EplanHpD.Plugin.WPFUI.Extension` 的引用。
- 新增 `LayoutHelperViewModel.cs` 文件,定义 `LayoutHelperViewModel` 类及其相关属性和方法,用于处理电机和线缆的选择和切换逻辑。
This commit is contained in:
lihanbo 2024-12-10 17:02:58 +08:00
parent 3bab55aff6
commit 19e04eb3ed
13 changed files with 438 additions and 133 deletions

View File

@ -19,7 +19,16 @@ namespace Sinvo.EplanHpD.Plugin.WPFUI.Models
OnPropertyChanged(nameof(Index));
}
}
private string _id;
public string Id
{
get => _id; set
{
_id = value;
OnPropertyChanged(nameof(Id));
}
}
private string _name;
public string Name

View File

@ -166,13 +166,12 @@
<DependentUpon>TestWindow.xaml</DependentUpon>
</Compile>
<Compile Include="Utils\Consts.cs" />
<Compile Include="Utils\DrawPDFHelper.cs" />
<Compile Include="Utils\ExcelHelper.cs" />
<Compile Include="Utils\LambdaComparer.cs" />
<Compile Include="Utils\LectotypeManager.cs" />
<Compile Include="Utils\MessageSend.cs" />
<Compile Include="Utils\MotorExcelHelper.cs" />
<Compile Include="ViewModel\CableLectotypeViewModel.cs" />
<Compile Include="ViewModel\LayoutHelperViewModel.cs" />
<Compile Include="ViewModel\LectotypeViewModel.cs" />
<Compile Include="ViewModel\MainViewModel.Check.cs" />
<Compile Include="ViewModel\MainViewModel.cs" />
@ -264,6 +263,9 @@
<PackageReference Include="HandyControl">
<Version>3.5.1</Version>
</PackageReference>
<PackageReference Include="KissStudio.DotNetDetour">
<Version>1.0.2.1</Version>
</PackageReference>
<PackageReference Include="MiniExcel">
<Version>1.34.2</Version>
</PackageReference>

View File

@ -1,38 +0,0 @@
using System.Collections.Generic;
using System.IO;
namespace Sinvo.EplanHpD.Plugin.WPFUI.Utils
{
public class DrawPDFHelper
{
private static string PDF_PATH = @"\\192.168.1.160\plm系统文档\线材选型\图纸\";
private static Dictionary<string, byte[]> _pdfDataDict = new Dictionary<string, byte[]>();
public static void CacheAllPdfToMemory()
{
var path = PDF_PATH;
var files = Directory.GetFiles(path, "*.pdf");
foreach (var file in files)
{
var drawId = Path.GetFileNameWithoutExtension(file);
var data = File.ReadAllBytes(file);
_pdfDataDict.Add(drawId, data);
}
}
public static MemoryStream GetPDFStream(string drawId)
{
if (_pdfDataDict.ContainsKey(drawId))
{
var data = _pdfDataDict[drawId];
return new MemoryStream(data);
}
return null;
}
public static void ClearCache()
{
_pdfDataDict.Clear();
}
}
}

View File

@ -1,55 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Sinvo.EplanHpD.Plugin.WPFUI.Utils
{
/// <summary>
/// 消息发送与接收
/// </summary>
public class MessageSend
{
private static readonly Dictionary<string, List<Action<object>>> _subscribers = new();
public static void Subscribe(string message, Action<object> callback)
{
if (!_subscribers.ContainsKey(message))
{
_subscribers[message] = new List<Action<object>>();
}
_subscribers[message].Add(callback);
}
public static void Unsubscribe(string message, Action<object> callback)
{
if (_subscribers.ContainsKey(message))
{
_subscribers[message].Remove(callback);
if (_subscribers[message].Count == 0)
{
_subscribers.Remove(message);
}
}
}
public static void Unsubscribe(string message)
{
if (_subscribers.ContainsKey(message))
{
_subscribers.Remove(message);
}
}
public static void Publish(string message, object parameter = null)
{
if (_subscribers.ContainsKey(message))
{
foreach (var callback in _subscribers[message])
{
callback(parameter);
}
}
}
}
}

View File

@ -6,13 +6,19 @@
xmlns:hc="https://handyorg.github.io/handycontrol"
xmlns:local="clr-namespace:Sinvo.EplanHpD.Plugin.WPFUI.View"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewmodel="clr-namespace:Sinvo.EplanHpD.Plugin.WPFUI.ViewModel"
Title="布线助手"
Width="450"
Height="230"
Height="260"
MinWidth="450"
MinHeight="230"
MinHeight="260"
d:DataContext="{d:DesignInstance Type=viewmodel:LayoutHelperViewModel}"
ActiveGlowColor="{DynamicResource PrimaryColor}"
Background="White"
Left="1460"
Loaded="GlowWindow_Loaded"
Top="770"
WindowStartupLocation="Manual"
mc:Ignorable="d">
<Window.Resources>
<ResourceDictionary>
@ -31,64 +37,82 @@
<RowDefinition Height="30" />
</Grid.RowDefinitions>
<hc:SimpleStackPanel Grid.Row="0" Orientation="Horizontal">
<TextBlock FontSize="14" TextWrapping="Wrap">
<!--<TextBlock FontSize="14" TextWrapping="Wrap">
<Run Text="选中的电机:" />
<Run Foreground="{StaticResource DangerBrush}" Text="HK-KT103WJK" />
</TextBlock>
<Run Foreground="{StaticResource DangerBrush}" Text="{Binding SelectMotorModel}" />
</TextBlock>-->
<TextBlock
Margin="5,0,0,0"
Margin="0,0,0,0"
FontSize="14"
TextWrapping="Wrap">
<Run Text="当前布线的电机:" />
<Run Foreground="{StaticResource DangerBrush}" Text="HK-KT103WJK" />
<Run Foreground="{StaticResource DangerBrush}" Text="{Binding Motor.MotorModelStr}" />
<Run Text=" " />
<Run Text="轴号:" />
<Run Foreground="{StaticResource DangerBrush}" Text="{Binding SelectedLine.AxisNo}" />
</TextBlock>
</hc:SimpleStackPanel>
<StackPanel Grid.Row="1" VerticalAlignment="Center">
<TextBlock VerticalAlignment="Center" FontSize="14">
<Run Text="当前线段:" />
<Run Foreground="{StaticResource DangerBrush}" Text="前段" />
<Run Foreground="{StaticResource DangerBrush}" Text="{Binding SelectedLine.CableConnectionClass}" />
<Run Text=" " />
<Run Text="当前线类型:" />
<Run Foreground="{StaticResource DangerBrush}" Text="编码器线+动力线" />
<Run Text="轴号:" />
<Run Foreground="{StaticResource DangerBrush}" Text="MRJ001" />
<Run Foreground="{StaticResource DangerBrush}" Text="{Binding SelectedLine.CableType}" />
</TextBlock>
</StackPanel>
<ListView
Grid.Row="2"
hc:GridViewAttach.ColumnHeaderHeight="10"
ItemsSource="{Binding SubLines}"
Style="{StaticResource ListView.Small}">
<ListView.View>
<GridView>
<GridViewColumn Width="100" Header="线类型" />
<GridViewColumn Width="200" Header="线型号" />
<GridViewColumn Width="50" Header="图纸" />
<GridViewColumn
Width="80"
DisplayMemberBinding="{Binding CableType}"
Header="线类型" />
<GridViewColumn Header="线型号">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox IsReadOnly="True" Text="{Binding CableModel}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
<ListViewItem Content="1231211111111111111" />
</ListView>
<hc:SimpleStackPanel Grid.Row="3">
<TextBlock TextWrapping="Wrap">
<Run Text="选中的线:" />
</TextBlock>
<TextBlock>
<Run Text="三菱伺服编码器线 TRVVSP3×2×0.2-2000W-CE定制(带DB9公头)电机" />
<Run Text="{Binding SelectLineName}" />
</TextBlock>
</hc:SimpleStackPanel>
<hc:SimpleStackPanel Grid.Row="4" VerticalAlignment="Bottom">
<DockPanel HorizontalAlignment="Stretch">
<Button
Click="PrevBtn_Click"
Content="上一根线"
DockPanel.Dock="Left"
IsEnabled="{Binding HasPrev}"
Style="{StaticResource ButtonDanger}" />
<Button
HorizontalAlignment="Right"
Click="NextBtn_Click"
Content="下一根线"
DockPanel.Dock="Right"
IsEnabled="{Binding HasNext}"
Style="{StaticResource ButtonPrimary}" />
<Button
Content="MRJ001-1"
DockPanel.Dock="Right"
Style="{StaticResource ButtonSuccess}" />
<Button DockPanel.Dock="Right" Style="{StaticResource ButtonSuccess}">
<TextBlock>
<Run Text="{Binding SelectedLine.AxisNo}" />
<Run Text="-" />
<Run Text="{Binding SelectedLine.CurrentLine}" />
</TextBlock>
</Button>
</DockPanel>
</hc:SimpleStackPanel>
</Grid>

View File

@ -2,6 +2,7 @@
using EPLAN.Harness.Core.Controls;
using EPLAN.Harness.ProjectCore;
using EPLAN.Harness.ProjectCore.Occurrences.Designer;
using Sinvo.EplanHpD.Plugin.WPFUI.ViewModel;
using System;
using System.Collections.Generic;
using System.Diagnostics;
@ -25,32 +26,30 @@ namespace Sinvo.EplanHpD.Plugin.WPFUI.View
public partial class LayoutHelperWindow
{
private FlexDesigner _currentFlexDesigner;
public LayoutHelperWindow()
private LayoutHelperViewModel viewModel;
public LayoutHelperWindow(List<string> motorIds)
{
InitializeComponent();
OnInit();
viewModel = new LayoutHelperViewModel(_currentFlexDesigner, motorIds);
this.DataContext = viewModel;
}
private void OnInit()
{
GetCurrentDoc();
_currentFlexDesigner.SelectSet.SelectionChanged += SelectSet_SelectionChanged;
GetMotorCables();
}
private void GetMotorCables()
{
viewModel.GetMotorCables();
}
private void SelectSet_SelectionChanged(object sender, EventArgs e)
{
if (sender is OccSelectSet selectSet)
{
var item = selectSet.SelectedItem;
if (item is OccSubPart part)
{
Debug.WriteLine($"Select part -> {part.Name} / {part.ID}");
if (part.Parents != null)
{
Debug.WriteLine($"Select part parent -> {part.Parents.First()?.Name} / {part.Parents.First()?.ID}");
}
}
}
viewModel.OnSelectChange(sender);
}
public void GetCurrentDoc()
@ -63,6 +62,7 @@ namespace Sinvo.EplanHpD.Plugin.WPFUI.View
if (designer != null)
{
_currentFlexDesigner = designer;
viewModel._currentFlexDesigner = designer;
}
else
{
@ -74,6 +74,22 @@ namespace Sinvo.EplanHpD.Plugin.WPFUI.View
FlexMessageBox.Error(ex.Message);
}
}
private void GlowWindow_Loaded(object sender, RoutedEventArgs e)
{
OnInit();
}
private void PrevBtn_Click(object sender, RoutedEventArgs e)
{
viewModel.ToPrevLine();
}
private void NextBtn_Click(object sender, RoutedEventArgs e)
{
viewModel.ToNextLine();
}
}
}

View File

@ -371,7 +371,10 @@ namespace Sinvo.EplanHpD.Plugin.WPFUI
private void StartLayoutBtn_Click(object sender, RoutedEventArgs e)
{
var window = new LayoutHelperWindow();
var motorIds = ViewModel.Motors.Where(motor => !motor.IsError).Select(motor => motor.OccPartId).ToList();
var window = new LayoutHelperWindow(motorIds);
//window.MotorIds = motorIds;
ElementHost.EnableModelessKeyboardInterop(window);
var mainApp = BaseApp.ActiveApplication;
var helper = new System.Windows.Interop.WindowInteropHelper(window);

View File

@ -0,0 +1,312 @@
using EPLAN.Harness.API.Occurrences;
using EPLAN.Harness.Common.Extensions;
using EPLAN.Harness.Core;
using EPLAN.Harness.Core.Controls;
using EPLAN.Harness.Core.Props;
using EPLAN.Harness.ProjectCore;
using EPLAN.Harness.ProjectCore.Occurrences.Designer;
using Sinvo.EplanHpD.Plugin.Service;
using Sinvo.EplanHpD.Plugin.WPFUI.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Security;
using System.Text;
using System.Threading.Tasks;
namespace Sinvo.EplanHpD.Plugin.WPFUI.ViewModel
{
public class LayoutHelperViewModel : INotifyPropertyChanged
{
public FlexDesigner _currentFlexDesigner;
private string _selectMotorModel;
private MotorLectotypeService service = new();
private List<string> _motorIds;
private MotorModel _motor;
private CableLectotypeViewModel cableLectotypeViewModel;
public MotorModel Motor
{
get => _motor;
set
{
_motor = value;
OnPropertyChanged();
}
}
public LayoutHelperViewModel()
{
}
public LayoutHelperViewModel(FlexDesigner currentFlexDesigner, List<string> motorIds)
{
_currentFlexDesigner = currentFlexDesigner;
_motorIds = motorIds;
}
public string SelectMotorModel
{
get { return _selectMotorModel; }
set
{
_selectMotorModel = value;
OnPropertyChanged();
}
}
private string _selectLineId;
public string SelectLineName
{
get
{
if (_selectLineId == null) return "";
var part = _currentFlexDesigner.GetOccurrenceByID(_selectLineId);
if (part != null)
{
return part.Parents?.First()?.LibraryName;
}
else
{
return "";
}
}
set
{
}
}
/// <summary>
/// 是否有下一个
/// </summary>
public bool HasNext
{
get
{
if (_motorIds == null) return false;
if (SelectedLines == null) return false;
if (CurrentMotorSelectLineIndex < SelectedLines.Count - 1)
{
return true;
}
else if (CurrentMotorIndex < _motorIds.Count - 1)
{
return true;
}
else
{
return false;
}
}
set
{
OnPropertyChanged(nameof(HasNext));
}
}
/// <summary>
/// 是否有上一个
/// </summary>
public bool HasPrev
{
get
{
if (CurrentMotorSelectLineIndex > 0)
{
return true;
}
else if (CurrentMotorIndex > 0)
{
return true;
}
else
{
return false;
}
}
set
{
OnPropertyChanged(nameof(HasPrev));
}
}
private int CurrentMotorIndex = 0;
private int CurrentMotorSelectLineIndex = 0;
private LectotypeLineModel _selectedLine;
public LectotypeLineModel SelectedLine
{
get => _selectedLine;
set
{
_selectedLine = value;
OnPropertyChanged(nameof(SelectedLine));
OnPropertyChanged(nameof(HasPrev));
OnPropertyChanged(nameof(HasNext));
}
}
private List<LectotypeLineModel> _subLines;
public List<LectotypeLineModel> SubLines
{
get => _subLines;
set
{
_subLines = value;
OnPropertyChanged(nameof(SubLines));
}
}
public List<LectotypeLineModel> SelectedLines;
public void OnSelectChange(object sender)
{
if (sender is OccSelectSet selectSet)
{
var item = selectSet.SelectedItem;
if (item is OccSubPart part)
{
Debug.WriteLine($"Select part -> {part.Name} / {part.ID}");
if (part.Parents != null)
{
SelectMotorModel = part.Parents?.First()?.Name ?? "";
Debug.WriteLine($"Select part parent -> {part.Parents?.First()?.Name} / {part.Parents?.First()?.ID}");
}
}
else if (item != null)
{
_selectLineId = item.ID;
OnPropertyChanged(nameof(SelectLineName));
}
}
}
private bool IsCable(BaseOccurrence occ)
{
return occ is OccCableForked;
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
internal void GetMotorCables()
{
if (_motorIds != null && _motorIds.Any())
{
Task.Factory.StartNew(() =>
{
var service = new MotorLectotypeService();
var data = service.GetMotorLectotypeData(_motorIds[CurrentMotorIndex]);
if (!string.IsNullOrEmpty(data))
{
cableLectotypeViewModel = Newtonsoft.Json.JsonConvert.DeserializeObject<CableLectotypeViewModel>(data);
if (cableLectotypeViewModel?.SelectedLines?.Any() ?? false)
{
SelectedLines = cableLectotypeViewModel.SelectedLines;
SelectedLine = SelectedLines[CurrentMotorSelectLineIndex];
ReSetSubLines();
Motor = cableLectotypeViewModel.Motor;
return;
}
}
{
CurrentMotorIndex++;
if (CurrentMotorIndex < _motorIds.Count)
{
CurrentMotorSelectLineIndex = 0;
GetMotorCables();
}
}
}).Wait();
}
}
internal void ToPrevLine()
{
if (HasPrev)
{
if (CurrentMotorSelectLineIndex == 0)
{
ToPrevMotor();
}
else
{
CurrentMotorSelectLineIndex--;
SelectedLine = SelectedLines[CurrentMotorSelectLineIndex];
ReSetSubLines();
}
}
}
internal void ToNextLine()
{
if (HasNext)
{
if (CheckAndSetSelLine())
{
if (CurrentMotorSelectLineIndex >= SelectedLines.Count - 1)
{
ToNextMotor();
}
else
{
CurrentMotorSelectLineIndex++;
SelectedLine = SelectedLines[CurrentMotorSelectLineIndex];
ReSetSubLines();
}
}
}
}
private bool CheckAndSetSelLine()
{
var part = _currentFlexDesigner.GetOccurrenceByID(_selectLineId);
if (part != null)
{
if (part.Properties.Any(it => it.ValueHolder.StrVal == "轴号")) return true;
var prop = new EPLAN.Harness.Core.Props.Property(new PropDef { Name = "轴号" });
prop.Set(SelectedLine.AxisNo);
part.Properties.Add(prop);
return true;
}
else
{
FlexMessageBox.Warning("当前选中的线不是推荐中的线");
return false;
}
}
internal void ToPrevMotor()
{
if (CurrentMotorIndex > 0)
{
CurrentMotorIndex--;
CurrentMotorSelectLineIndex = 0;
GetMotorCables();
}
}
internal void ToNextMotor()
{
if (CurrentMotorIndex < _motorIds.Count)
{
CurrentMotorIndex++;
CurrentMotorSelectLineIndex = 0;
GetMotorCables();
}
}
internal void ReSetSubLines()
{
SubLines = SelectedLine.SubLines.Distinct(it => it.CableModel).ToList();
}
}
}

View File

@ -89,6 +89,7 @@ namespace Sinvo.EplanHpD.Plugin.WPFUI.ViewModel
ScanCableModels.Add(new ScanCableModel()
{
Index = ScanCableModels.Count + 1,
Id = wire.ID,
Name = wire.LibraryName,
Code = wire.Name,
Imprint = wire.Imprint
@ -131,7 +132,7 @@ namespace Sinvo.EplanHpD.Plugin.WPFUI.ViewModel
{
// 清除错误信息
ClearErrors(nameof(InputCode));
var cable = ScanCableModels.FirstOrDefault(c => c.Code.Equals(searchText, StringComparison.OrdinalIgnoreCase));
var cable = ScanCableModels.FirstOrDefault(c => c.Code.Equals(searchText, StringComparison.OrdinalIgnoreCase) || c.Imprint.StartsWith(searchText, StringComparison.OrdinalIgnoreCase));
if (cable != null)
{
@ -147,7 +148,7 @@ namespace Sinvo.EplanHpD.Plugin.WPFUI.ViewModel
cable.IsChecked = true;
}
ScanedIndex = Math.Max(cable.Index - 1, 0);
ToSourceByName(searchText);
ToSourceById(cable.Id);
}
else
@ -185,6 +186,34 @@ namespace Sinvo.EplanHpD.Plugin.WPFUI.ViewModel
}
}
private void ToSourceById(string occId)
{
var occWire = _currentFlexDesigner.GetOccurrenceByID(occId);
if (occWire != null)
{
occWire.SetVisibility(true, null);
_currentFlexDesigner.SelectSet.Clear();
_currentFlexDesigner.SelectSet.Add(occWire);
_currentFlexDesigner.FitToSelectSet();
_currentFlexDesigner.SelectSet.OnSelectionChanged();
//_currentFlexDesigner.Camera.GraphicControl._HighlightNode()
/*
List<DatTreeNodeEx<BaseOccurrence>> nodeByEntity = this._occTreeView.GetNodeByEntity(baseOccurrence);
if (nodeByEntity != null)
{
foreach (DatTreeNodeEx<BaseOccurrence> datTreeNodeEx in nodeByEntity)
{
if (!this._occTreeView.SelectedNodes.Contains(datTreeNodeEx))
{
this._occTreeView.SelectedNodes.Add(datTreeNodeEx);
}
}
}
*/
}
}
public void OthersOccShow(bool show = false)
{
_currentFlexDesigner.GetOrganizerOccurrences().ToList().ForEach(occ =>

View File

@ -2,6 +2,7 @@
using EPLAN.Harness.API.Plugins.Core;
using EPLAN.Harness.AppCore;
using Sinvo.EplanHpD.Plugin.WPFUI;
using Sinvo.EplanHpD.Plugin.WPFUI.Extension;
using Sinvo.EplanHpD.Plugin.WPFUI.Utils;
using System;
using System.Drawing;

View File

@ -4,6 +4,7 @@ using EPLAN.Harness.API.Plugins.Core;
using EPLAN.Harness.Core.Controls;
using EPLAN.Harness.ProjectCore;
using Sinvo.EplanHpD.Plugin.WPFUI;
using Sinvo.EplanHpD.Plugin.WPFUI.Extension;
using Sinvo.EplanHpD.Plugin.WPFUI.Utils;
using System;
using System.Drawing;

View File

@ -1,6 +1,7 @@
using EPLAN.Harness.API;
using EPLAN.Harness.API.Plugins.Core;
using EPLAN.Harness.AppCore;
using Sinvo.EplanHpD.Plugin.WPFUI.Extension;
using Sinvo.EplanHpD.Plugin.WPFUI.Utils;
using Sinvo.EplanHpD.Plugin.WPFUI.View;
using System;