From c4a3f8db90530a727ffab77c3bb5bb7d782792bf Mon Sep 17 00:00:00 2001
From: alielie <alielie@git.com>
Date: 星期一, 25 八月 2025 15:50:27 +0800
Subject: [PATCH] 上传代码;
---
Plugin.ModelManage/Entity/ModelData.cs | 19
Plugin.SeqEditor/SettingPanel/LoopPanel.xaml.cs | 60
WPFProject/BuildCmd.bat | 12
WPFProject/Controls/MainTabControl.xaml | 41
HMI.LogViewer/LogViewer.xaml | 7
HMI.UI/Style/ScrollBarResource.xaml | 106
Plugin.TestResult/DataTable.xaml | 40
HMI.UI/Style/PanuonListView.xaml | 77
Plugin.ModelManage/AssemblyInfo.cs | 10
HMI.Core/Util/MSMQHelper.cs | 2
Plugin.TestBuilder/UI/InnerWindow.xaml.cs | 2
Plugin.TestResult/TestResultView.xaml.cs | 19
Plugin.TsExecution/Plugin.TsExecution.csproj | 5
HMI.UI/DpUtil/CanvasHelper.cs | 16
WPFProject/Lang/zh-CN/DOControl.json | 4
HMI.Core/DpUtil/PermissionHelper.cs | 47
Plugin.SeqEditor/Entity/EditablePO/StringValTestEPO.cs | 9
HMI.AlermInfoManage/AlarmSettingList.xaml.cs | 117
WPFProject/PanuonWindow.xaml.cs | 75
WPFProject/Lang/en-US/AlarmInfoManage.json | 1
HMI.ParameterManage/ParameterManage.xaml | 4
HMI.ParameterManage/TestItem.xaml | 4
Plugin.DODriverControl/Entity/DIOData.cs | 89
Plugin.SeqEditor/ViewModel/SeqEditorViewModel.cs | 11
Plugin.TestResult/ViewControl.xaml.cs | 90
HMI.AlermInfoManage/SimpleAlarm.xaml.cs | 100
WPFProject/Lang/zh-CN/ChangeModel.json | 25
HMI.UI/MDI/Workspace.xaml.cs | 366 +
Plugin.ChangeModel/ChangeModel.xaml.cs | 430 +
HMI.MenuManage/Modal/MenuModal.xaml.cs | 3
Plugin.DODriverControl/DOControl.xaml.cs | 141
HMI.UI/MDI/BottomBar.xaml.cs | 29
Plugin.TsExecution/TsExecution.xaml.cs | 533 +
HMI.Base/MaskControl.xaml | 32
Plugin.SeqEditor/SettingPanel/ActionPanel.xaml | 1
WPFProject/App.xaml | 2
HMI.MenuManage/Model/MenuManageModel.cs | 105
Plugin.TsSupport/Properties/AssemblyInfo.cs | 33
SimpleUtil/HMI.MQUtil/HMI.MQUtil.csproj | 49
WPFProject/Properties/app.manifest | 2
HMI.UI/Util/MsgBoxHelper.cs | 1
SimpleUtil/HMI.MQUtil/Properties/AssemblyInfo.cs | 33
WPFProject/Lang/en-US/ChangeModel.json | 25
HMI.Core/Entity/UserInfo.cs | 13
Plugin.SeqEditor/SeqEditor.xaml.cs | 9
SimpleUtil/HMI.SerialData.Util/SerialDataHelper.cs | 10
Plugin.ChangeModel/Entity/WorkOrderData.cs | 7
Plugin.DataBoard/DataBoard.xaml.cs | 2
Plugin.SeqEditor/Entity/EditablePO/NumValTestEPO.cs | 43
HMI.ParameterManage/ParameterSetting.xaml | 4
HMI.UI/Style/FormStyle.xaml | 10
Plugin.ModelManage/DataModal.xaml | 77
HMI.UI/RequirePasswordWindow.xaml.cs | 49
HMI.UI/MDI/InnerWindow.xaml.cs | 267 +
Plugin.TestBuilder/UI/Resize.cs | 5
Plugin.ChangeModel/AssemblyInfo.cs | 10
SimpleUtil/HMI.Simple.Util/ProductModelHelper.cs | 106
Plugin.ModelManage/ModelManage.xaml | 169
HMI.UI/Style/PanuonResource.xaml | 45
WPFProject/PanuonWindow.xaml | 274
Plugin.TsExecution/Entity/TestStep.cs | 1
Plugin.DODriverControl/ConfigModal.xaml | 54
Plugin.TsExecution/SingleControl.xaml | 168
WPFProject/WPFProject.sln | 81
HMI.Core/Api/IAlarmShow.cs | 13
HMI.UI/Controls/NumberInput.cs | 8
HMI.UI/MDI/BottomBar.xaml | 15
Plugin.DODriverControl/Plugin.DODriverControl.csproj | 28
HMI.Util/ExcelHelper.cs | 140
HMI.MenuManage/Modal/MenuModal.xaml | 3
HMI.LogViewer/LogViewer.xaml.cs | 2
HMI.UI/Converter/DataGridRowNumberConverter.cs | 31
HMI.AlermInfoManage/Modal/AlarmSettingModal.xaml.cs | 17
Plugin.ChangeModel/ChangeModel.xaml | 144
HMI.UI/TableComboBox.cs | 249 +
Plugin.ChangeModel/Plugin.ChangeModel.csproj | 27
HMI.MenuManage/MenuManage.xaml | 6
HMI.UI/EditBox.cs | 194
Plugin.DODriverControl/Api/ModBusTcpController.cs | 55
HMI.MenuManage/Modal/RoleModal.xaml.cs | 3
HMI.UI/Style/WindowResources.xaml | 1
HMI.UI/Resources/Icon/dot2.png | 0
HMI.UI/MaskControl.xaml | 58
Plugin.ChangeModel/Entity/ModelData.cs | 13
HMI.Base/PluginMaskControl.cs | 89
Plugin.TestBuilder/UI/InnerWindow.xaml | 6
HMI.UI/MaskControl.xaml.cs | 63
Plugin.TestResult/ViewControl.xaml | 7
Plugin.TestResult/DataTable.xaml.cs | 24
HMI.UI/HMI.UI.csproj | 75
Plugin.DODriverControl/ConfigModal.xaml.cs | 108
HMI.DataViewer/DataViewer.xaml | 1
Plugin.SeqEditor/SettingPanel/StringValTestPanel.xaml | 3
Plugin.ModelManage/DataModal.xaml.cs | 142
Plugin.ModelManage/ModelManage.xaml.cs | 300 +
HMI.Base/HMI.Base.csproj | 17
Plugin.ChangeModel/Entity/CmLogData.cs | 13
Plugin.DODriverControl/Api/PCIController.cs | 49
Plugin.MaterialOpt/MaterialOpt.xaml | 251 +
Plugin.DOControl/DOControl.xaml | 4
WPFProject/Lang/zh-CN/app.json | 1
HMI.MenuManage/MenuManage.xaml.cs | 140
HMI.MenuManage/RoleManage.xaml | 5
WPFProject/Utils/MainToastHandler.cs | 22
HMI.Core/Entity/PermissionData.cs | 24
HMI.UI/MDI/Workspace.xaml | 34
Plugin.MaterialOpt/Plugin.MaterialOpt.csproj | 27
SimpleUtil/HMI.MQUtil/MQConnector.cs | 110
Plugin.MaterialOpt/AssemblyInfo.cs | 10
Plugin.SeqEditor/Entity/StepUI.cs | 269 +
HMI.UI/Controls/VisualHost.cs | 30
HMI.Base/SimpleControl.cs | 59
HMI.UI/MDI/InnerWindow.xaml | 67
Plugin.TsSupport/Plugin.TsSupport.csproj | 58
HMI.UI/Util/ToastHelper.cs | 78
HMI.UnitTest/MainWindow.xaml.cs | 51
HMI.AlermInfoManage/Entity/AlarmText.cs | 14
Plugin.SeqEditor/Util/ItemData.cs | 57
HMI.UI/Controls/LightBall.cs | 43
Plugin.TsExecution/TsExecution.xaml | 305
Plugin.DODriverControl/DOControl.xaml | 22
HMI.UI/Style/MsgBoxStyle.xaml | 3
HMI.AlermInfoManage/AlarmSettingList.xaml | 236 +
HMI.UI/Converter/ReverseBoolConverter.cs | 27
Plugin.DODriverControl/Api/Dask.cs | 801 +++
Plugin.SeqEditor/SettingPanel/LoopPanel.xaml | 104
HMI.UI/RequirePasswordWindow.xaml | 33
HMI.UI/Resources/Icon/dot.svg | 12
Plugin.DODriverControl/DataModal.xaml.cs | 177
Plugin.TestBuilder/Plugin.TestBuilder.csproj | 1
HMI.UI/MDI/MinInnerWindow.xaml.cs | 42
Plugin.ModelManage/Plugin.ModelManage.csproj | 27
Plugin.DODriverControl/DataModal.xaml | 120
SimpleUtil/HMI.Simple.Util/HMI.Simple.Util.csproj | 5
HMI.AlermInfoManage/AlarmInfoManage.xaml | 261
HMI.UI/Themes/Generic.xaml | 145
HMI.AlermInfoManage/SimpleAlarm.xaml | 96
HMI.Core/HMI.Core.csproj | 5
HMI.UI/DpUtil/Resize.cs | 640 ++
HMI.Base/PluginLoader.cs | 76
WPFProject/WPFProject.csproj | 46
WPFProject/Login.xaml.cs | 125
HMI.IOMonitor/HMI.IOMonitor.csproj | 1
HMI.UI/MDI/MinInnerWindow.xaml | 24
HMI.AlermInfoManage/HMI.AlarmInfoManage.csproj | 19
Plugin.DOControl/Plugin.DOControl.csproj | 4
Plugin.DODriverControl/SingleControl.xaml | 365 +
HMI.AlermInfoManage/AlarmInfoManage.xaml.cs | 584 +
Plugin.JarUI/JarUI.xaml.cs | 3
HMI.AlermInfoManage/Model/XmlModel.cs | 19
Plugin.DODriverControl/Api/DaskHelper.cs | 132
Plugin.TestResult/Plugin.TestResult.csproj | 5
Plugin.TsExecution/SingleControl.xaml.cs | 58
HMI.Core/Api/AlarmShowHelper.cs | 24
HMI.UI/DpUtil/FormGroupHelper.cs | 24
Plugin.DODriverControl/AssemblyInfo.cs | 10
HMI.UI/Style/PanuonDataGrid.xaml | 31
Plugin.DODriverControl/Api/IDIOController.cs | 15
Plugin.DODriverControl/Entity/ConfigData.cs | 17
WPFProject/安装MSMQ.bat | 5
WPFProject/Login.xaml | 11
SimpleUtil/HMI.Simple.Util/SqliteHelper.cs | 238 +
WPFProject/Lang/zh-CN/AlarmInfoManage.json | 1
HMI.AlermInfoManage/Modal/AlarmSettingModal.xaml | 12
HMI.Base/SimpleMaskControl.cs | 79
HMI.MenuManage/UserManage.xaml | 5
Plugin.DOControl/DOControl.xaml.cs | 75
WPFProject/Controls/MainTabControl.xaml.cs | 23
/dev/null | 1
HMI.UI/Resources/Font/iconfont.ttf | 0
HMI.UI/Resources/Icon/dot.png | 0
Plugin.JarUI/JarUI.xaml | 2
SimpleUtil/HMI.Simple.Util/Parameter.cs | 2
Plugin.MaterialOpt/MaterialOpt.xaml.cs | 429 +
HMI.Base/Themes/Generic.xaml | 32
HMI.AlermInfoManage/Entity/AlarmSetting.cs | 13
Plugin.SeqEditor/SeqEditor.xaml | 107
HMI.SettingControl/SystemConfig.xaml | 1
HMI.SettingControl/SettingControl.xaml | 1
HMI.UnitTest/HMI.UnitTest.csproj | 8
WPFProject/Api/SQLite.Interop.dll | 0
Plugin.DODriverControl/SingleControl.xaml.cs | 568 ++
WPFProject/Lang/en-US/app.json | 1
Plugin.TsSupport/TestAppManager.cs | 17
184 files changed, 12,499 insertions(+), 1,215 deletions(-)
diff --git a/HMI.AlermInfoManage/AlarmInfoManage.xaml b/HMI.AlermInfoManage/AlarmInfoManage.xaml
index 74e1f8f..2d892d9 100644
--- a/HMI.AlermInfoManage/AlarmInfoManage.xaml
+++ b/HMI.AlermInfoManage/AlarmInfoManage.xaml
@@ -13,10 +13,20 @@
Background="{StaticResource WorkspaceBackground}"
Loaded="UserControl_Loaded"
d:DesignHeight="450" d:DesignWidth="800">
-
+ <UserControl.Resources>
+ <ResourceDictionary>
+ <ResourceDictionary.MergedDictionaries>
+ <ResourceDictionary Source="/HMI.UI;component/Style/PanuonListView.xaml"/>
+ </ResourceDictionary.MergedDictionaries>
+ </ResourceDictionary>
+ </UserControl.Resources>
<Border Style="{StaticResource CardBoarder}">
- <StackPanel>
- <DockPanel Margin="0,0,0,10">
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition/>
+ </Grid.RowDefinitions>
+ <DockPanel Grid.Row="0" Margin="0,0,0,10">
<StackPanel DockPanel.Dock="Right" Style="{StaticResource ButtonGroup}">
<Button Style="{StaticResource SettingBtn}" x:Name="settingBtn" Click="Button_Click"/>
<Button Style="{StaticResource RfhBtn}" x:Name="refreshBtn" Click="Button_Click"/>
@@ -27,63 +37,192 @@
VerticalAlignment="Center" HorizontalAlignment="Left" Text="{DynamicResource Alm.Title}"/>
</DockPanel>
- <DataGrid x:Name="table" Style="{StaticResource DefaultDataGrid}" ItemsSource="{Binding Datasource}">
- <DataGrid.Columns>
- <DataGridTemplateColumn Header="" Width="Auto" CanUserResize="False">
- <DataGridTemplateColumn.CellTemplate>
- <DataTemplate>
- <CheckBox VerticalAlignment="Center" IsChecked="{Binding Selected,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
- </DataTemplate>
- </DataGridTemplateColumn.CellTemplate>
- </DataGridTemplateColumn>
- <DataGridTemplateColumn Header="#" CanUserResize="False">
- <DataGridTemplateColumn.CellTemplate>
- <DataTemplate>
- <TextBlock Text="{Binding Converter={StaticResource rowNumber},
- RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGridRow},AncestorLevel=1}}"/>
- </DataTemplate>
- </DataGridTemplateColumn.CellTemplate>
- </DataGridTemplateColumn>
- <DataGridTextColumn Width="*" Binding="{Binding Source}">
- <DataGridTextColumn.Header>
- <TextBlock Text="{DynamicResource Alm.Source}"/>
- </DataGridTextColumn.Header>
- </DataGridTextColumn>
- <DataGridTextColumn Width="*" Binding="{Binding Code}">
- <DataGridTextColumn.Header>
- <TextBlock Text="{DynamicResource Alm.Code}"/>
- </DataGridTextColumn.Header>
- </DataGridTextColumn>
- <DataGridTextColumn Width="*" Binding="{Binding Info}">
- <DataGridTextColumn.Header>
- <TextBlock Text="{DynamicResource Alm.Info}"/>
- </DataGridTextColumn.Header>
- </DataGridTextColumn>
- <DataGridTextColumn Width="*" Binding="{Binding Time}">
- <DataGridTextColumn.Header>
- <TextBlock Text="{DynamicResource Alm.Time}"/>
- </DataGridTextColumn.Header>
- </DataGridTextColumn>
- <DataGridTemplateColumn Width="100" IsReadOnly="True" CanUserResize="False">
- <DataGridTemplateColumn.Header>
- <TextBlock Text="{DynamicResource App.Opt}"/>
- </DataGridTemplateColumn.Header>
- <DataGridTemplateColumn.CellTemplate>
- <DataTemplate>
- <StackPanel Orientation="Horizontal">
- <Button x:Name="editBtn" Style="{StaticResource EditLink}"
- Margin="0,0,10,0"
- Click="Button_Click"
- DataContext="{Binding }"/>
- <Button x:Name="delBtn" Style="{StaticResource DeleteLink}"
- DataContext="{Binding }"
- Click="Button_Click"/>
- </StackPanel>
- </DataTemplate>
- </DataGridTemplateColumn.CellTemplate>
- </DataGridTemplateColumn>
- </DataGrid.Columns>
- </DataGrid>
- </StackPanel>
+ <TabControl Grid.Row="1" Style="{StaticResource HeaderTabControl}">
+ <TabItem Header="鎶ヨ璁板綍">
+ <DockPanel>
+ <StackPanel DockPanel.Dock="Bottom" Orientation="Horizontal" HorizontalAlignment="Right">
+ <pu:Pagination
+ Height="36" Margin="10"
+ HorizontalAlignment="Left"
+ Foreground="Black"
+ ItemsBackground="Transparent"
+ ItemsCornerRadius="12"
+ ItemsSelectedBackground="{DynamicResource SecondPrimaryColor}"
+ x:Name="page"
+ CurrentPage="{Binding CurrentPage}"
+ MaxPage="{Binding MaxPage}"/>
+ </StackPanel>
+ <ListView x:Name="table" Style="{StaticResource DefaultListTable}"
+ VirtualizingPanel.VirtualizationMode="Standard"
+ ItemsSource="{Binding Datasource}">
+ <ListView.View>
+ <GridView>
+ <GridViewColumn Width="50">
+ <GridViewColumn.Header>
+ <TextBlock Text="#"/>
+ </GridViewColumn.Header>
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <TextBlock Text="{Binding Converter={StaticResource lvRowNumber},
+RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ListViewItem,AncestorLevel=1}}"/>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+
+ <GridViewColumn Width="300">
+ <GridViewColumn.Header>
+ <TextBlock Text="{DynamicResource Alm.Source}"/>
+ </GridViewColumn.Header>
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <Border Style="{StaticResource CellBorder}">
+ <TextBlock VerticalAlignment="Center" Text="{Binding Source}"/>
+ </Border>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+
+ <GridViewColumn Width="500">
+ <GridViewColumn.Header>
+ <TextBlock Text="{DynamicResource Alm.Code}"/>
+ </GridViewColumn.Header>
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <Border Style="{StaticResource CellBorder}">
+ <TextBlock VerticalAlignment="Center" Text="{Binding AlarmCode}"/>
+ </Border>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+
+ <GridViewColumn Width="800">
+ <GridViewColumn.Header>
+ <TextBlock Text="{DynamicResource Alm.Info}"/>
+ </GridViewColumn.Header>
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <Border Style="{StaticResource CellBorder}">
+ <TextBlock VerticalAlignment="Center" Text="{Binding AlarmInfo}"/>
+ </Border>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+ <GridViewColumn Width="200">
+ <GridViewColumn.Header>
+ <TextBlock Text="{DynamicResource Alm.Time}"/>
+ </GridViewColumn.Header>
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <Border Style="{StaticResource CellBorder}">
+ <TextBlock VerticalAlignment="Center" Text="{Binding Time}"/>
+ </Border>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+ </GridView>
+ </ListView.View>
+ </ListView>
+ <!--<DataGrid x:Name="table" Style="{StaticResource DefaultDataGrid}" ItemsSource="{Binding Datasource}">
+ <DataGrid.Columns>
+ <DataGridTemplateColumn Header="" Width="Auto" CanUserResize="False">
+ <DataGridTemplateColumn.CellTemplate>
+ <DataTemplate>
+ <CheckBox VerticalAlignment="Center" IsChecked="{Binding Selected,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
+ </DataTemplate>
+ </DataGridTemplateColumn.CellTemplate>
+ </DataGridTemplateColumn>
+ <DataGridTemplateColumn Header="#" CanUserResize="False">
+ <DataGridTemplateColumn.CellTemplate>
+ <DataTemplate>
+ <TextBlock Text="{Binding Converter={StaticResource rowNumber},
+ RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGridRow},AncestorLevel=1}}"/>
+ </DataTemplate>
+ </DataGridTemplateColumn.CellTemplate>
+ </DataGridTemplateColumn>
+ <DataGridTextColumn Width="*" Binding="{Binding Source}">
+ <DataGridTextColumn.Header>
+ <TextBlock Text="{DynamicResource Alm.Source}"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>
+ <DataGridTextColumn Width="*" Binding="{Binding AlarmCode}">
+ <DataGridTextColumn.Header>
+ <TextBlock Text="{DynamicResource Alm.Code}"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>
+ <DataGridTextColumn Width="*" Binding="{Binding AlarmInfo}">
+ <DataGridTextColumn.Header>
+ <TextBlock Text="{DynamicResource Alm.Info}"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>
+ <DataGridTextColumn Width="*" Binding="{Binding Time}">
+ <DataGridTextColumn.Header>
+ <TextBlock Text="{DynamicResource Alm.Time}"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>
+ </DataGrid.Columns>
+ </DataGrid>-->
+ </DockPanel>
+ </TabItem>
+ <TabItem Header="鎶ヨ淇℃伅">
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition/>
+ </Grid.RowDefinitions>
+
+ <DataGrid Grid.Row="1" x:Name="alarmTextTable" Visibility="Hidden" Style="{x:Null}">
+ <DataGrid.Columns>
+ <DataGridTemplateColumn Header="" Width="50"/>
+ <DataGridTextColumn x:Name="sb1" Width="*" Binding="{Binding AlarmCode}"/>
+ <DataGridTextColumn x:Name="sb2" Width="*" Binding="{Binding MAlarmText_CN}"/>
+ </DataGrid.Columns>
+ </DataGrid>
+ <ListView Grid.Row="1" Style="{StaticResource DefaultListTable}" ItemsSource="{Binding AlarmTexts}">
+ <ListView.View>
+ <GridView>
+ <GridViewColumn Width="50">
+ <GridViewColumn.Header>
+ <TextBlock Text="#"/>
+ </GridViewColumn.Header>
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <TextBlock Text="{Binding Converter={StaticResource lvRowNumber},
+RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ListViewItem,AncestorLevel=1}}"/>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+
+ <GridViewColumn Width="{Binding ActualWidth,ElementName=sb1}">
+ <GridViewColumn.Header>
+ <TextBlock Text="{DynamicResource Alm.Code}"/>
+ </GridViewColumn.Header>
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <Border Style="{StaticResource CellBorder}">
+ <TextBlock VerticalAlignment="Center" Text="{Binding AlarmCode}"/>
+ </Border>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+
+ <GridViewColumn Width="{Binding ActualWidth,Converter={StaticResource sbC},ConverterParameter=50,ElementName=sb2}">
+ <GridViewColumn.Header>
+ <TextBlock Text="{DynamicResource Alm.Info}"/>
+ </GridViewColumn.Header>
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <Border Style="{StaticResource CellBorder}">
+ <TextBlock VerticalAlignment="Center" Text="{Binding MAlarmText_CN}"/>
+ </Border>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+ </GridView>
+ </ListView.View>
+ </ListView>
+ </Grid>
+ </TabItem>
+ </TabControl>
+ </Grid>
</Border>
</hb:PluginControl>
diff --git a/HMI.AlermInfoManage/AlarmInfoManage.xaml.cs b/HMI.AlermInfoManage/AlarmInfoManage.xaml.cs
index f0feadd..c7891c0 100644
--- a/HMI.AlermInfoManage/AlarmInfoManage.xaml.cs
+++ b/HMI.AlermInfoManage/AlarmInfoManage.xaml.cs
@@ -1,15 +1,19 @@
-锘縰sing HMI.AlarmInfoManage.Entity;
-using HMI.AlarmInfoManage.Model;
+锘縰sing ConnectionUtil;
+using HMI.AlarmInfoManage.Entity;
using HMI.Base;
+using HMI.Core.Api;
using HMI.Core.Setting;
using HMI.Core.Util;
using HMI.UI.Util;
+using HMI.Util;
using Microsoft.Win32;
-using NPOI.XSSF.UserModel;
+using OPCConnection;
using Sharp7;
using SimensDriver;
using System;
using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Data;
using System.IO;
using System.Linq;
using System.Timers;
@@ -25,9 +29,16 @@
{
private string blockPath;
private string markPath;
- private string textSettingPath;
+ private string alarmTextPath;
+
+ private string opcIP = "127.0.0.1";
+ private int opcPort = 6543;
+ private int localPort = 18888;
+ private volatile bool isClosing = false;
+
+
+ private string dbPath;
private Simens plc = new Simens();
- private XmlUIModel Model;
private bool isHaveAlarm;
private bool isNewAlarm;
@@ -50,7 +61,7 @@
/// <summary>
/// 鎺ユ敹鎶ヨ鐨勯槦鍒�
/// </summary>
- private MSMQHelper alarmQueue = new MSMQHelper("LTHMI_Alarm");
+ private MSMQHelper alarmQueue = new MSMQHelper("HMI_Alarm");
/// <summary>
/// 鏃ュ織鐢熸垚鍣�
/// </summary>
@@ -59,6 +70,8 @@
/// 鍒锋柊鎶ヨ鐨勯槦鍒�
/// </summary>
private MSMQHelper alarmRefershToMain = new MSMQHelper("LTHMI_Alarm_Rrfresh");
+
+ private SCADAApi lTSCADAApi = new OPCClient();
/// <summary>
/// 鎶ヨ
@@ -80,15 +93,12 @@
/// <summary>
/// 浠g爜绠$悊
/// </summary>
- private List<AlarmSetting> alarmSettings = new List<AlarmSetting>();
+ private ObservableCollection<AlarmSetting> alarmSettings = new ObservableCollection<AlarmSetting>();
// <summary>
/// 鏍囧織浣嶆姤璀︾鐞�
/// </summary>
- private List<AlarmSetting> signAlarmSetting = new List<AlarmSetting>();
- /// <summary>
- /// 鎶ヨ鏂囨湰鍒楄〃
- /// </summary>
- private List<AlarmText> alarmTexts = new List<AlarmText>();
+ private ObservableCollection<AlarmSetting> markAlarmSetting = new ObservableCollection<AlarmSetting>();
+
/// <summary>
/// 浼犺嚦涓荤獥浣撶殑鎶ヨ淇℃伅
/// </summary>
@@ -97,17 +107,114 @@
private AlarmText alarm;
private SystemSetting systemSetting;
+ private ObservableCollection<AlarmText> datasource = new ObservableCollection<AlarmText>();
+
+ public ObservableCollection<AlarmText> Datasource
+ {
+ get { return datasource; }
+ set { Set(ref datasource, value); }
+ }
+
+ /// <summary>
+ /// 鎶ヨ鏂囨湰鍒楄〃
+ /// </summary>
+ private ObservableCollection<AlarmText> alarmTexts = new ObservableCollection<AlarmText>();
+ public ObservableCollection<AlarmText> AlarmTexts
+ {
+ get { return alarmTexts; }
+ set { Set(ref alarmTexts, value); }
+ }
+
+ public Dictionary<string, AlarmText> textMap = new Dictionary<string, AlarmText>();
+
+ private double size = 30;
+
+ private int currentPage = 0;
+ public int CurrentPage
+ {
+ get => currentPage;
+ set
+ {
+ Set(ref currentPage, value);
+ RefreshData();
+ }
+ }
+
+ private int maxPage = 0;
+ public int MaxPage
+ {
+ get => maxPage;
+ set
+ {
+ Set(ref maxPage, value);
+ }
+ }
public AlarmInfoManage()
{
+ DataContext = this;
systemSetting = SystemSetting.Instance;
InitializeComponent();
}
+ public override void SetBaseFolder(string folder)
+ {
+ base.SetBaseFolder(folder);
+ dbPath = Path.Combine(BaseFolder, "alarm.db");
+ alarmTextPath = Path.Combine(BaseFolder, "AlarmText.data");
+
+ blockPath = Path.Combine(BaseFolder, "BlockSetting.xml");
+ markPath = Path.Combine(BaseFolder, "MarkSetting.xml");
+ }
+
public override void InitFinish()
{
- Model = new XmlUIModel(BaseFolder);
- DataContext = Model;
+ if (!File.Exists(dbPath))
+ {
+ SqliteHelper.CreateDatabase(dbPath);
+ }
+ sqliteHelper = new SqliteHelper(dbPath);
+ sqliteHelper.ExecuteSql(@"CREATE TABLE IF NOT EXISTS Alarm (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ source TEXT NOT NULL,
+ alarmcode TEXT,
+ alarminfo TEXT,
+ time DATETIME);");
+
+ LoadAlarmSetting();
+ LoadAlarmText();
+
+ MonitorTimer = new Timer
+ {
+ Interval = 100,
+ };
+ MonitorTimer.Elapsed += MonitorTimer_Elapsed;
+ if (!lTSCADAApi.Connect2(opcIP, opcPort, localPort, out string errMsg))
+ {
+ //MsgBoxHelper.Error(this, errMsg);
+ }
+ else
+ {
+ this.MonitorTimer.Start();
+ }
+
+ PcTimer = new Timer
+ {
+ Interval = 100,
+ AutoReset = false
+ };
+ PcTimer.Elapsed += PcTimer_Elapsed;
+ PcTimer.Enabled = true;
+ }
+
+ public override void DoClose(object sender, EventArgs e)
+ {
+ isClosing = true;
+ PcTimer.Enabled = false;
+ PcTimer?.Dispose();
+
+ MonitorTimer.Enabled = false;
+ MonitorTimer?.Dispose();
}
private void Button_Click(object sender, RoutedEventArgs e)
@@ -119,7 +226,8 @@
OpenSettingWindow();
break;
case "refreshBtn":
- //Model.
+ LoadAlarmText();
+ RefreshPage(CurrentPage);
break;
case "importBtn":
ImportText();
@@ -131,11 +239,58 @@
private void OpenSettingWindow()
{
- AlarmSettingList listModal = new AlarmSettingList(blockPath, markPath, log)
+ AlarmSettingList listModal = new AlarmSettingList(blockPath, markPath,alarmSettings,markAlarmSetting, log)
{
Owner = Window.GetWindow(this)
};
listModal.ShowDialog();
+ alarmSettings = listModal.Datasource;
+ markAlarmSetting = listModal.MarkDatasource;
+ }
+
+ private void RefreshPage(int? page = null)
+ {
+ var sql = "SELECT COUNT (*) as num FROM Alarm;";
+ var dt = sqliteHelper.GetDataTable(sql);
+ if (dt.Rows.Count <= 0)
+ {
+ CurrentPage = 1;
+ MaxPage = 1;
+ return;
+ }
+ int count = int.Parse(dt.Rows[0]["num"].ToString());
+ MaxPage = (int)Math.Ceiling(count / size);
+
+ if (page != null)
+ {
+ CurrentPage = page.Value;
+ }
+ else if (CurrentPage > MaxPage)
+ {
+ CurrentPage = MaxPage;
+ }
+ }
+
+ private void RefreshData()
+ {
+ var list = new ObservableCollection<AlarmText>();
+ var sql = $"SELECT source, alarmcode, alarminfo, time FROM Alarm ORDER BY time DESC LIMIT ({CurrentPage - 1} * {size}), {size};";
+ var dt = sqliteHelper.GetDataTable(sql);
+ if (dt.Rows.Count > 0)
+ {
+ foreach (DataRow dr in dt.Rows)
+ {
+ var at = new AlarmText
+ {
+ Source = dr["source"].ToString(),
+ AlarmCode = dr["alarmcode"].ToString(),
+ AlarmInfo = dr["alarminfo"].ToString(),
+ Time = dr["time"].ToString(),
+ };
+ list.Add(at);
+ }
+ }
+ Datasource = list;
}
private void ImportText()
@@ -160,6 +315,60 @@
/// 瀵煎叆鎶ヨ浠g爜鏂囨湰
/// </summary>
/// <param name="excelFile">鐢靛瓙璁捐琛ㄦ牸鏂囦欢</param>
+ //private void ImportExcelAlarmText(string excelFile)
+ //{
+ // int index = 0;
+
+ // try
+ // {
+ // if (excelFile.IndexOf(".xlsm") < 0)
+ // {
+ // this.Warning(this.lang("Alm.OnlySupportXlsm"));
+ // return;
+ // }
+
+ // this.alarmTexts.Clear();
+ // XSSFWorkbook workbook = new XSSFWorkbook(excelFile);
+ // XSSFSheet sheet = (XSSFSheet)workbook.GetSheet("sheet1");
+ // XSSFRow row = null;
+
+ // for (int i = 2; i < (sheet.LastRowNum + 1); i++)
+ // {
+ // index = i;
+ // row = (XSSFRow)sheet.GetRow(i);
+ // if (row != null)
+ // {
+ // AlarmText alarm = new AlarmText();
+ // alarm.AlarmCode = row.Cells[0].StringCellValue;
+ // alarm.OpNo = row.Cells[1].StringCellValue;
+ // alarm.ModuleNo = row.Cells[2].StringCellValue;
+ // alarm.ModuleName_CN = row.Cells[3].StringCellValue;
+ // alarm.ModuleName_EN = row.Cells[4].StringCellValue;
+ // alarm.MAlarmCode = row.Cells[5].StringCellValue;
+ // alarm.MAlarmText_CN = row.Cells[6].StringCellValue;
+ // alarm.MAlarmText_EN = row.Cells[7].StringCellValue;
+ // this.alarmTexts.Add(alarm);
+ // }
+ // }
+
+ // if (sheet.LastRowNum > 0)
+ // {
+ // XmlHelper.SerializeToXml(textSettingPath, this.alarmTexts);
+ // }
+
+ // this.Success(this.lang("App.ImportSuccess"));
+ // }
+ // catch (Exception ex)
+ // {
+ // log.Error($"Row {index} AlarmText Import Failed.", ex);
+ // this.Error($"{this.lang("Alm.RowImportFailed", index)}: {ex.Message}");
+ // }
+ //}
+
+ /// <summary>
+ /// 瀵煎叆鎶ヨ浠g爜鏂囨湰
+ /// </summary>
+ /// <param name="excelFile">鐢靛瓙璁捐琛ㄦ牸鏂囦欢</param>
private void ImportExcelAlarmText(string excelFile)
{
int index = 0;
@@ -172,35 +381,14 @@
return;
}
- this.alarmTexts.Clear();
- XSSFWorkbook workbook = new XSSFWorkbook(excelFile);
- XSSFSheet sheet = (XSSFSheet)workbook.GetSheet("sheet1");
- XSSFRow row = null;
+ this.alarmTexts = new ObservableCollection<AlarmText>
+ (ExcelHelper.ReadFromExcel<AlarmText>(excelFile));
- for (int i = 2; i < (sheet.LastRowNum + 1); i++)
+ if (alarmTexts.Count > 0)
{
- index = i;
- row = (XSSFRow)sheet.GetRow(i);
- if (row != null)
- {
- AlarmText alarm = new AlarmText();
- alarm.AlarmCode = row.Cells[0].StringCellValue;
- alarm.OpNo = row.Cells[1].StringCellValue;
- alarm.ModuleNo = row.Cells[2].StringCellValue;
- alarm.ModuleName_CN = row.Cells[3].StringCellValue;
- alarm.ModuleName_EN = row.Cells[4].StringCellValue;
- alarm.MAlarmCode = row.Cells[5].StringCellValue;
- alarm.MAlarmText_CN = row.Cells[6].StringCellValue;
- alarm.MAlarmText_EN = row.Cells[7].StringCellValue;
- this.alarmTexts.Add(alarm);
- }
+ XmlHelper.SerializeToXml(alarmTextPath, this.alarmTexts);
}
-
- if (sheet.LastRowNum > 0)
- {
- XmlHelper.SerializeToXml(textSettingPath, this.alarmTexts);
- }
-
+ LoadAlarmText();
this.Success(this.lang("App.ImportSuccess"));
}
catch (Exception ex)
@@ -210,27 +398,57 @@
}
}
- private void UserControl_Loaded(object sender, RoutedEventArgs e)
+ private void LoadAlarmText()
{
- if (!string.IsNullOrEmpty(systemSetting.PlcIp))
+ try
{
- if (this.plc.isConnection)
+ textMap.Clear();
+ AlarmTexts = XmlHelper.DeserializeFromXml<ObservableCollection<AlarmText>>(alarmTextPath);
+ foreach (var text in AlarmTexts)
{
- this.plc.Simens_S7_ConnectPLC(systemSetting.PlcIp, 102, 0, 1, string.Empty);
+ textMap[text.AlarmCode] = text;
}
}
- MonitorTimer = new Timer
+ catch (Exception ex)
{
- Interval = 100,
- };
- MonitorTimer.Elapsed += MonitorTimer_Elapsed;
+ log.Error("LoadAlarmText Error.", ex);
+ AlarmTexts = new ObservableCollection<AlarmText>();
+ }
+ }
- PcTimer = new Timer
+ private void LoadAlarmSetting()
+ {
+ try
{
- Interval = 100,
- };
- PcTimer.Elapsed += PcTimer_Elapsed; ;
+ alarmSettings = XmlHelper.DeserializeFromXml<ObservableCollection<AlarmSetting>>(blockPath);
+ }
+ catch (Exception ex)
+ {
+ log.Error("LoadAlarmSetting Error.", ex);
+ alarmSettings = new ObservableCollection<AlarmSetting>();
+ }
+ try
+ {
+ markAlarmSetting = XmlHelper.DeserializeFromXml<ObservableCollection<AlarmSetting>>(markPath);
+ }
+ catch (Exception ex)
+ {
+ log.Error("LoadAlarmText Error.", ex);
+ markAlarmSetting = new ObservableCollection<AlarmSetting>();
+ }
+ }
+
+ private void UserControl_Loaded(object sender, RoutedEventArgs e)
+ {
+ //if (!string.IsNullOrEmpty(systemSetting.PlcIp))
+ //{
+ // if (this.plc.isConnection)
+ // {
+ // this.plc.Simens_S7_ConnectPLC(systemSetting.PlcIp, 102, 0, 1, string.Empty);
+ // }
+ //}
+ RefreshPage(1);
Loaded -= UserControl_Loaded;
}
@@ -242,25 +460,56 @@
this.alarmQueue.Receive(100, out string MessageID, out string MsgStr);
if (MessageID != string.Empty)
{
- log.Info(MsgStr);
switch (MessageID)
{
case "Clear":
- ////this.currentAlarmCachePc.RemoveAll(alarm => alarm.Source == "PC");
this.currentAlarmCachePc.Clear();
this.RefershAlarm();
break;
- default:
- AlarmText aalarm = this.alarmTexts.Find(alarm => alarm.AlarmCode == MsgStr);
- aalarm.Source = "PC";
- aalarm.Time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
- if ((aalarm != null) && (this.currentAlarmCachePc.Find(alarm => alarm.AlarmCode == aalarm.AlarmCode) == null))
+ case "AlarmCode":
+ AlarmText aalarm = AlarmTexts.FirstOrDefault(alarm => alarm.AlarmCode == MsgStr);
+ if (aalarm == null) break;
+ var data = new AlarmText {
+ Source = "PC",
+ AlarmCode = aalarm.AlarmCode,
+ AlarmInfo = aalarm.MAlarmText_CN,
+ Time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
+ };
+ //aalarm.Source = "PC";
+ //aalarm.Time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
+ if (this.currentAlarmCachePc.Find(alarm => alarm.AlarmCode == aalarm.AlarmCode) == null)
{
- this.currentAlarmCachePc.Add(aalarm);
+ this.currentAlarmCachePc.Add(data);
this.RefershAlarm();
this.isPcAlarmnumber = this.currentAlarmCachePc.Count;
}
-
+ break;
+ default:
+ string[] arr = MsgStr.Split(',');
+ string source = "PC";
+ string info = string.Empty;
+ if (arr.Length > 1)
+ {
+ source = arr[0];
+ info = arr[1];
+ }
+ else
+ {
+ info = MsgStr;
+ }
+ AlarmText newAlarm = new AlarmText
+ {
+ Source = source,
+ AlarmInfo = info,
+ Time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
+ };
+ if (this.currentAlarmCachePc
+ .Find(alarm => alarm.Source == newAlarm.Source && alarm.AlarmInfo == newAlarm.AlarmInfo) == null)
+ {
+ this.currentAlarmCachePc.Add(newAlarm);
+ this.RefershAlarm();
+ this.isPcAlarmnumber = this.currentAlarmCachePc.Count;
+ }
break;
}
}
@@ -271,79 +520,158 @@
}
finally
{
- PcTimer.Enabled = true;
+ if (!isClosing) PcTimer.Enabled = true;
}
}
+
+ //private void MonitorTimer_Elapsed_bak(object sender, ElapsedEventArgs e)
+ //{
+ // try
+ // {
+ // this.MonitorTimer.Enabled = false;
+ // isHaveAlarm = false;
+ // foreach (var item in signAlarmSetting)
+ // {
+ // //isHaveAlarm = isHaveAlarm ||
+ // // this.plc.Simens_S7_ReadBool_DB(item.DBAddress, item.StartAddress, item.Length);
+ // }
+
+ // ////鏈夋姤璀�
+ // if (isHaveAlarm)
+ // {
+ // this.isNewAlarm = false;
+ // this.currentAlarmCachePlc.Clear();
+ // RefreshDBSetting();
+ // for (int i = 0; i < ((int)alarmCodeBytes.Length / 4); i++)
+ // {
+ // int code = S7.GetDIntAt(alarmCodeBytes, 4 * i);
+ // ////鏈夋姤璀�
+ // if (code != 0)
+ // {
+ // string acode = string.Format("{0:d10}", code);
+ // alarm = AlarmTexts.FirstOrDefault(item => item.AlarmCode == acode);
+ // if (alarm != null)
+ // {
+ // alarm.Source = "PLC";
+ // alarm.Time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
+ // this.currentAlarmCachePlc.Add(alarm);
+ // ////鏈夋柊鎶ヨ
+ // if (this.preAlarmCachePlc.Find(alarm => alarm.AlarmCode == acode) == null)
+ // {
+ // this.isNewAlarm = true;
+ // this.SendLogMsg(alarm.ModuleName_CN + alarm.MAlarmText_CN);
+ // }
+ // }
+ // }
+ // }
+
+ // ////鏈夋柊鎶ヨ鍜屾姤璀﹀噺灏戞椂鍒锋柊鎶ヨ琛�
+ // if (this.isNewAlarm || (this.currentAlarmCachePlc.Count != this.preAlarmCachePlc.Count))
+ // {
+ // this.currentAlarmCachePlcToMain = XmlHelper.DeepClone(this.currentAlarmCachePlc);
+ // this.RefershAlarm();
+ // }
+
+ // this.preAlarmCachePlc.Clear();
+ // this.preAlarmCachePlc = XmlHelper.DeepClone(this.currentAlarmCachePlc);
+ // }
+ // else
+ // {
+ // if (this.preAlarmCachePlc.Count != 0 || this.currentAlarmCachePlcToMain.Count != 0 || this.currentAlarmCachePlc.Count != 0)
+ // {
+ // this.preAlarmCachePlc.Clear();
+ // this.currentAlarmCachePlcToMain.Clear();
+ // this.currentAlarmCachePlc.Clear();
+ // this.RefershAlarm();
+ // }
+ // }
+ // }
+ // catch (Exception ex)
+ // {
+ // log.Error("sdadsa", ex);
+ // }
+ // finally
+ // {
+ // this.MonitorTimer.Enabled = true;
+ // }
+ //}
private void MonitorTimer_Elapsed(object sender, ElapsedEventArgs e)
{
try
{
this.MonitorTimer.Enabled = false;
- isHaveAlarm = false;
- foreach (var item in signAlarmSetting)
+
+ if (!lTSCADAApi.IsConnected(out string errMsg))
{
- isHaveAlarm = isHaveAlarm ||
- this.plc.Simens_S7_ReadBool_DB(item.DBAddress, item.StartAddress, item.Length);
+ log.Warn($"OPCServer Connection Error. {errMsg}");
+ if (!lTSCADAApi.Connect2(opcIP, opcPort, localPort, out errMsg))
+ {
+ log.Warn($"OPCServer Try ReConnection Error. {errMsg}");
+ return;
+ }
}
- ////鏈夋姤璀�
- if (isHaveAlarm)
+ isHaveAlarm = false;
+ List<AlarmText> cache = new List<AlarmText>();
+ foreach (var item in alarmSettings)
{
- this.isNewAlarm = false;
- this.currentAlarmCachePlc.Clear();
- RefreshDBSetting();
- for (int i = 0; i < ((int)alarmCodeBytes.Length / 4); i++)
+ var name = $"{item.DBAddress}.{item.StartAddress}";
+ if (lTSCADAApi.DoFctReadSingle(name, out string alarmCode, out errMsg) && alarmCode != "0")
{
- int code = S7.GetDIntAt(alarmCodeBytes, 4 * i);
- ////鏈夋姤璀�
- if (code != 0)
+ isHaveAlarm = true;
+ if (!textMap.TryGetValue(alarmCode, out alarm)) {
+ continue;
+ }
+ var newAlarm = new AlarmText
{
- string acode = string.Format("{0:d10}", code);
- alarm = this.alarmTexts.Find(item => item.AlarmCode == acode);
- if (alarm != null)
- {
- alarm.Source = "PLC";
- alarm.Time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
- this.currentAlarmCachePlc.Add(alarm);
- ////鏈夋柊鎶ヨ
- if (this.preAlarmCachePlc.Find(alarm => alarm.AlarmCode == acode) == null)
- {
- this.isNewAlarm = true;
- this.SendLogMsg(alarm.ModuleName_CN + alarm.MAlarmText_CN);
- }
- }
+ Source = "PLC",
+ AlarmCode = alarm.AlarmCode,
+ ModuleName_CN = alarm.ModuleName_CN,
+ MAlarmText_CN = alarm.MAlarmText_CN,
+ Time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
+ AlarmInfo = $"{alarm.ModuleName_CN} {alarm.MAlarmText_CN}"
+ };
+ if (this.currentAlarmCachePlc
+ .Find(alarm => alarm.AlarmCode == newAlarm.AlarmCode) == null)
+ {
+ this.currentAlarmCachePlc.Add(newAlarm);
}
}
-
- ////鏈夋柊鎶ヨ鍜屾姤璀﹀噺灏戞椂鍒锋柊鎶ヨ琛�
- if (this.isNewAlarm || (this.currentAlarmCachePlc.Count != this.preAlarmCachePlc.Count))
- {
- this.currentAlarmCachePlcToMain = XmlHelper.DeepClone(this.currentAlarmCachePlc);
- this.RefershAlarm();
- }
-
- this.preAlarmCachePlc.Clear();
- this.preAlarmCachePlc = XmlHelper.DeepClone(this.currentAlarmCachePlc);
}
- else
+
+ foreach (var item in markAlarmSetting)
{
- if (this.preAlarmCachePlc.Count != 0 || this.currentAlarmCachePlcToMain.Count != 0 || this.currentAlarmCachePlc.Count != 0)
+ var name = $"{item.DBAddress}.{item.StartAddress}";
+ if (lTSCADAApi.DoFctReadSingle(name, out string alarmCode, out errMsg) && alarmCode != "0")
{
- this.preAlarmCachePlc.Clear();
- this.currentAlarmCachePlcToMain.Clear();
- this.currentAlarmCachePlc.Clear();
- this.RefershAlarm();
+ isHaveAlarm = true;
+ var newAlarm = new AlarmText
+ {
+ Source = "PLC",
+ AlarmCode = alarmCode,
+ Time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
+ AlarmInfo = item.Description
+ };
+ if (this.currentAlarmCachePlc
+ .Find(d => d.AlarmInfo == newAlarm.AlarmInfo) == null)
+ {
+ this.currentAlarmCachePlc.Add(newAlarm);
+ }
}
}
+ this.RefershAlarm();
+ this.isPcAlarmnumber = this.currentAlarmCachePc.Count;
+
+ if (!isHaveAlarm) currentAlarmCachePlc.Clear();
}
catch (Exception ex)
{
- log.Error("sdadsa", ex);
+ log.Error("Read OPCServer Data Error.", ex);
}
finally
{
- this.MonitorTimer.Enabled = true;
+ if(!isClosing) this.MonitorTimer.Enabled = true;
}
}
@@ -355,11 +683,13 @@
List<byte> bytes = new List<byte>();
foreach (var item in alarmSettings)
{
- byte[] itemalarmCodeBytes = this.plc.Simens_S7_ReadBytes_DB("DB", item.DBAddress, item.StartAddress, item.Length);
- bytes.AddRange(itemalarmCodeBytes.ToList());
+ //byte[] itemalarmCodeBytes = this.plc.Simens_S7_ReadBytes_DB("DB", item.DBAddress, item.StartAddress, item.Length);
+ //bytes.AddRange(itemalarmCodeBytes.ToList());
}
alarmCodeBytes = bytes.ToArray();
}
+
+
/// <summary>
/// 鍒锋柊鎶ヨ淇℃伅
@@ -370,20 +700,26 @@
foreach (AlarmText alarm in this.currentAlarmCachePlc)
{
- this.currentInfo = alarm.ModuleName_CN + alarm.MAlarmText_CN;
- Model.Datasource.Add(alarm);
- string sqladd = string.Format("INSERT INTO Alarm (source, alarmcode, alarminfo, time) VALUES( '{0}','{1}','{2}','{3}');",
- alarm.Source, alarm.AlarmCode, this.currentInfo, alarm.Time);
- sqliteHelper.ExecuteSql(sqladd);
+ var currentInfo = alarm.AlarmInfo;
+ string sqladd = string.Format("INSERT INTO Alarm (source, alarmcode, alarminfo, time) VALUES('{0}','{1}','{2}','{3}');",
+ alarm.Source, alarm.AlarmCode, currentInfo, alarm.Time);
+ if (AlarmShowHelper.ShowAlarm(currentInfo))
+ {
+ sqliteHelper.ExecuteSql(sqladd);
+ }
}
+ //this.currentAlarmCachePlc.Clear();
foreach (AlarmText alarm in this.currentAlarmCachePc)
{
-
- Model.Datasource.Add(alarm);
- string sqladd2 = string.Format("INSERT INTO Alarm (source, alarmcode, alarminfo, time) VALUES( '{0}','{1}','{2}','{3}');", alarm.Source, alarm.AlarmCode, this.currentInfo, alarm.Time);
- this.sqliteHelper.ExecuteSql(sqladd2);
+ string sqladd2 = string.Format("INSERT INTO Alarm (source, alarmcode, alarminfo, time) VALUES('{0}','{1}','{2}','{3}');", alarm.Source, alarm.AlarmCode, alarm.AlarmInfo, alarm.Time);
+ sqliteHelper.ExecuteSql(sqladd2);
+ //Dispatcher.BeginInvoke(new Action(() =>
+ //{
+ // Datasource.Add(alarm);
+ //}));
}
+ this.currentAlarmCachePc.Clear();
}
/// <summary>
@@ -394,14 +730,6 @@
{
string LogMsg = "{\"Type\":\"Alarm\",\"Source\":\"" + alarm.Source + "\",\"Msg\":\"" + Msg + "\",\"Time\":\"" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "\"}";
this.loggeralarm.Send("Log", LogMsg);
- }
-
- public override void SetBaseFolder(string folder)
- {
- base.SetBaseFolder(folder);
- blockPath = Path.Combine(BaseFolder, "BlockSetting.xml");
- markPath = Path.Combine(BaseFolder, "MarkSetting.xml");
- textSettingPath = Path.Combine(BaseFolder, "textSetting.xml");
}
}
}
diff --git a/HMI.AlermInfoManage/AlarmSettingList.xaml b/HMI.AlermInfoManage/AlarmSettingList.xaml
index 75fc864..573554d 100644
--- a/HMI.AlermInfoManage/AlarmSettingList.xaml
+++ b/HMI.AlermInfoManage/AlarmSettingList.xaml
@@ -10,15 +10,239 @@
xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
mc:Ignorable="d"
Title="{Binding SelectedValue,Mode=OneWay}"
- SizeToContent="Height"
pu:WindowXModalDialog.Buttons="OK"
pu:WindowXModalDialog.OKButtonContent="{DynamicResource App.Close}"
- Width="800"
+ Width="1000"
Height="600"
+ Loaded="WindowX_Loaded"
+ WindowStartupLocation="CenterOwner"
Style="{StaticResource ModalWindow}">
+ <pu:WindowX.Resources>
+ <ResourceDictionary>
+ <ResourceDictionary.MergedDictionaries>
+ <ResourceDictionary Source="/HMI.UI;component/Style/PanuonListView.xaml"/>
+ </ResourceDictionary.MergedDictionaries>
+
+ <Style x:Key="EditLink" TargetType="Button" BasedOn="{StaticResource RowLink}">
+ <Setter Property="Content" Value="{DynamicResource App.Edit}"/>
+ <Setter Property="Foreground" Value="{DynamicResource PrimaryColor}"/>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding Path=IsMouseOver,
+ RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ListViewItem,AncestorLevel=1}}"
+ Value="True">
+ <Setter Property="Foreground" Value="#FFF"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding Path=IsSelected,
+ RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ListViewItem,AncestorLevel=1}}"
+Value="True">
+ <Setter Property="Foreground" Value="#FFF"/>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </ResourceDictionary>
+ </pu:WindowX.Resources>
<Grid Margin="10">
- <Border BorderThickness="1" BorderBrush="Gray">
- <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition />
+ </Grid.RowDefinitions>
+
+ <StackPanel Grid.Row="0" Orientation="Horizontal" HorizontalAlignment="Right"
+ Margin="0,0,0,10"
+ dp:StackPanelHelper.ChildSpace="10">
+ <Button Style="{StaticResource AddBtn}" x:Name="addBtn" Click="Button_Click"/>
+ <Button Style="{StaticResource RfhBtn}" x:Name="refreshBtn" Click="Button_Click"/>
+ <Button Style="{StaticResource ExportBtn}" x:Name="exportBtn" Click="Button_Click"/>
+ <Button Style="{StaticResource ImportBtn}" x:Name="importBtn" Click="Button_Click"/>
+ <Button Style="{StaticResource DelBtn}" x:Name="delBatchBtn" Click="Button_Click"/>
+ </StackPanel>
+
+ <Border Grid.Row="1" BorderThickness="0" BorderBrush="Gray">
+
+ <TabControl Style="{StaticResource HeaderTabControl}" SelectedIndex="{Binding ItemIndex}" x:Name="tab">
+ <TabItem Header="DB鍧楁姤璀�">
+ <ListView Style="{StaticResource DefaultListTable}" ItemsSource="{Binding Datasource}">
+ <ListView.View>
+ <GridView AllowsColumnReorder="False">
+
+ <GridViewColumn Width="30">
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <CheckBox VerticalAlignment="Center"
+IsChecked="{Binding IsSelected,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+
+ <GridViewColumn Width="60" Header="#">
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <Border Style="{StaticResource CellBorder}">
+ <TextBlock Style="{StaticResource ListTableTextBlock}" Text="{Binding Converter={StaticResource lvRowNumber},
+RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ListViewItem,AncestorLevel=1}}"/>
+ </Border>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+
+ <GridViewColumn Width="300">
+ <GridViewColumn.Header>
+ <TextBlock Text="{DynamicResource Alm.DbAddress}"/>
+ </GridViewColumn.Header>
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <Border Style="{StaticResource CellBorder}">
+ <TextBlock Style="{StaticResource ListTableTextBlock}"
+ Text="{Binding DBAddress}"/>
+ </Border>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+ <GridViewColumn Width="200">
+ <GridViewColumn.Header>
+ <TextBlock Text="{DynamicResource Alm.StartAddress}"/>
+ </GridViewColumn.Header>
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <Border Style="{StaticResource CellBorder}">
+ <TextBlock Style="{StaticResource ListTableTextBlock}"
+ Text="{Binding StartAddress}"/>
+ </Border>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+ <GridViewColumn Width="200">
+ <GridViewColumn.Header>
+ <TextBlock Text="{DynamicResource Alm.DbLength}"/>
+ </GridViewColumn.Header>
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <Border Style="{StaticResource CellBorder}">
+ <TextBlock Style="{StaticResource ListTableTextBlock}"
+ Text="{Binding Length}"/>
+ </Border>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+ <GridViewColumn Width="120">
+ <GridViewColumn.Header>
+ <TextBlock Text="{DynamicResource App.Opt}"/>
+ </GridViewColumn.Header>
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <StackPanel Orientation="Horizontal" dp:StackPanelHelper.ChildSpace="10">
+ <Button x:Name="editBtn" Style="{StaticResource EditLink}"
+ Click="Button_Click" Tag="{Binding }"/>
+
+ <Button x:Name="delBtn" Style="{StaticResource DeleteLink}"
+ Click="Button_Click" Tag="{Binding }"/>
+ </StackPanel>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+ </GridView>
+ </ListView.View>
+ </ListView>
+ </TabItem>
+ <TabItem Header="鏍囧織浣嶆姤璀�">
+ <ListView Style="{StaticResource DefaultListTable}" ItemsSource="{Binding MarkDatasource}">
+ <ListView.View>
+ <GridView AllowsColumnReorder="False">
+
+ <GridViewColumn Width="30">
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <CheckBox VerticalAlignment="Center"
+IsChecked="{Binding IsSelected,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+
+ <GridViewColumn Width="60" Header="#">
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <Border Style="{StaticResource CellBorder}">
+ <TextBlock Style="{StaticResource ListTableTextBlock}" Text="{Binding Converter={StaticResource lvRowNumber},
+RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ListViewItem,AncestorLevel=1}}"/>
+ </Border>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+
+ <GridViewColumn Width="220">
+ <GridViewColumn.Header>
+ <TextBlock Text="{DynamicResource Alm.DbAddress}"/>
+ </GridViewColumn.Header>
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <Border Style="{StaticResource CellBorder}">
+ <TextBlock Style="{StaticResource ListTableTextBlock}"
+ Text="{Binding DBAddress}"/>
+ </Border>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+ <GridViewColumn Width="180">
+ <GridViewColumn.Header>
+ <TextBlock Text="{DynamicResource Alm.StartAddress}"/>
+ </GridViewColumn.Header>
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <Border Style="{StaticResource CellBorder}">
+ <TextBlock Style="{StaticResource ListTableTextBlock}"
+ Text="{Binding StartAddress}"/>
+ </Border>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+ <GridViewColumn Width="150">
+ <GridViewColumn.Header>
+ <TextBlock Text="{DynamicResource Alm.DbLength}"/>
+ </GridViewColumn.Header>
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <Border Style="{StaticResource CellBorder}">
+ <TextBlock Style="{StaticResource ListTableTextBlock}"
+ Text="{Binding Length}"/>
+ </Border>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+ <GridViewColumn Width="200">
+ <GridViewColumn.Header>
+ <TextBlock Text="{DynamicResource Alm.Description}"/>
+ </GridViewColumn.Header>
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <Border Style="{StaticResource CellBorder}">
+ <TextBlock Style="{StaticResource ListTableTextBlock}"
+ Text="{Binding Description}"/>
+ </Border>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+ <GridViewColumn Width="120">
+ <GridViewColumn.Header>
+ <TextBlock Text="{DynamicResource App.Opt}"/>
+ </GridViewColumn.Header>
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <StackPanel Orientation="Horizontal" dp:StackPanelHelper.ChildSpace="10">
+ <Button x:Name="editBtn" Style="{StaticResource EditLink}"
+ Click="Button_Click" Tag="{Binding }"/>
+
+ <Button x:Name="delBtn" Style="{StaticResource DeleteLink}"
+ Click="Button_Click" Tag="{Binding }"/>
+ </StackPanel>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+ </GridView>
+ </ListView.View>
+ </ListView>
+ </TabItem>
+ </TabControl>
+ <!--<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
@@ -40,7 +264,7 @@
<ControlTemplate TargetType="ListBoxItem">
<Border x:Name="border" Background="LightGray"
Padding="10" Margin="0" BorderThickness="0">
- <!-- 鍐呭鍛堢幇鍣� -->
+ --><!-- 鍐呭鍛堢幇鍣� --><!--
<StackPanel>
<ContentPresenter Content="{TemplateBinding Content}"
ContentStringFormat="{TemplateBinding ContentStringFormat}"
@@ -124,7 +348,7 @@
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
- </Grid>
+ </Grid>-->
</Border>
</Grid>
</pu:WindowX>
diff --git a/HMI.AlermInfoManage/AlarmSettingList.xaml.cs b/HMI.AlermInfoManage/AlarmSettingList.xaml.cs
index a641650..ba8ac96 100644
--- a/HMI.AlermInfoManage/AlarmSettingList.xaml.cs
+++ b/HMI.AlermInfoManage/AlarmSettingList.xaml.cs
@@ -1,7 +1,10 @@
锘縰sing HMI.AlarmInfoManage.Entity;
using HMI.Core.Util;
using HMI.UI.Util;
+using HMI.Util;
using log4net;
+using Microsoft.Win32;
+using NPOI.SS.Formula.Functions;
using Panuon.WPF.UI;
using System;
using System.Collections.ObjectModel;
@@ -18,10 +21,14 @@
public partial class AlarmSettingList : WindowX
{
private ILog log;
- public AlarmSettingList(string blockFile, string markFile, ILog log)
+ public AlarmSettingList(string blockFile, string markFile, ObservableCollection<AlarmSetting> datasource,
+ ObservableCollection<AlarmSetting> markDatasource,
+ ILog log)
{
this.blockFile = blockFile;
this.markFile = markFile;
+ Datasource = datasource;
+ MarkDatasource = markDatasource;
this.log = log;
DataContext = this;
InitializeComponent();
@@ -69,7 +76,7 @@
private void Button_Click(object sender, RoutedEventArgs e)
{
Button btn = sender as Button;
- DataGridRow row = btn?.Tag as DataGridRow;
+ AlarmSetting data = btn?.Tag as AlarmSetting;
switch (btn.Name)
{
case "refreshBtn":
@@ -82,36 +89,57 @@
DeleteBatchData();
break;
case "editBtn":
- EditData(row.GetIndex(), btn.DataContext as AlarmSetting);
+ EditData(ItemIndex == 0 ? Datasource.IndexOf(data) : MarkDatasource.IndexOf(data), data);
+ break;
+ case "exportBtn":
+ ExportData();
+ break;
+ case "importBtn":
+ ImportData();
break;
case "delBtn":
- DeleteData(row.GetIndex());
+ DeleteData(ItemIndex == 0 ? Datasource.IndexOf(data) : MarkDatasource.IndexOf(data));
break;
default:
break;
}
-
}
private void LoadData()
{
try
{
- ObservableCollection<AlarmSetting> datasource = new ObservableCollection<AlarmSetting>();
- if (ItemIndex == 0 && File.Exists(blockFile))
+ if (File.Exists(blockFile))
{
- datasource =
+ Datasource =
XmlHelper.DeserializeFromXml<ObservableCollection<AlarmSetting>>(blockFile);
}
- else if (ItemIndex == 1 && File.Exists(markFile))
+ else
{
- datasource =
- XmlHelper.DeserializeFromXml<ObservableCollection<AlarmSetting>>(markFile);
+ Datasource = new ObservableCollection<AlarmSetting>();
}
- Datasource = datasource;
}
catch (Exception ex)
{
+ Datasource = new ObservableCollection<AlarmSetting>();
+ ToastHelper.Error(this, $"{this.lang("App.LoadFailed")}: {ex.Message}");
+ }
+
+ try
+ {
+ if (File.Exists(markFile))
+ {
+ MarkDatasource =
+ XmlHelper.DeserializeFromXml<ObservableCollection<AlarmSetting>>(markFile);
+ }
+ else
+ {
+ MarkDatasource = new ObservableCollection<AlarmSetting>();
+ }
+ }
+ catch (Exception ex)
+ {
+ MarkDatasource = new ObservableCollection<AlarmSetting>();
ToastHelper.Error(this, $"{this.lang("App.LoadFailed")}: {ex.Message}");
}
}
@@ -127,7 +155,7 @@
Title = $"{this.lang("App.Add")}{temp}",
Owner = Window.GetWindow(this),
};
- if (modal.Open(-1, data, Datasource, file) == true)
+ if (modal.Open(-1, data, ItemIndex == 0 ? Datasource : MarkDatasource, file, ItemIndex != 0) == true)
{
LoadData();
}
@@ -150,7 +178,7 @@
Title = $"{this.lang("App.Edit")}{temp}",
Owner = Window.GetWindow(this),
};
- if (modal.Open(index, data, Datasource, file) == true)
+ if (modal.Open(index, data, ItemIndex == 0 ? Datasource : MarkDatasource, file, ItemIndex != 0) == true)
{
LoadData();
}
@@ -161,6 +189,61 @@
ToastHelper.Error(this, $"{this.lang("App.EditFailed")}: {ex.Message}");
}
}
+
+ private void ExportData()
+ {
+ try
+ {
+ SaveFileDialog sfd = new SaveFileDialog
+ {
+ FileName = ItemIndex == 0 ? "DB鍧楁姤璀�.xls" : "鏍囧織浣嶆姤璀�.xls",
+ Filter = "Excel|*.xls"
+ };
+ if (sfd.ShowDialog() == true)
+ {
+ ExcelHelper.ExportExcel(sfd.FileName, ItemIndex == 0 ? Datasource : MarkDatasource);
+ }
+ }
+ catch (Exception ex)
+ {
+ log.Error("Export Failed.", ex);
+ ToastHelper.Error(this, $"{this.lang("App.ExportFailed")}: {ex.Message}");
+ }
+ }
+
+ private void ImportData()
+ {
+ try
+ {
+ OpenFileDialog ofd = new OpenFileDialog
+ {
+ Filter = "Excel|*.xls"
+ };
+ if (ofd.ShowDialog() == true)
+ {
+ var datasource = new ObservableCollection<AlarmSetting>(
+ ExcelHelper.ReadFromExcel<AlarmSetting>(ofd.FileName));
+ if (ItemIndex == 0)
+ {
+ Datasource = datasource;
+ }
+ else
+ {
+ MarkDatasource = datasource;
+ }
+ var file = ItemIndex == 0 ? blockFile : markFile;
+ var temp = ItemIndex == 0 ? Datasource : MarkDatasource;
+ XmlHelper.SerializeToXml(file, temp);
+ LoadData();
+ }
+ }
+ catch (Exception ex)
+ {
+ log.Error("Import Failed.", ex);
+ ToastHelper.Error(this, $"{this.lang("App.ImportFailed")}: {ex.Message}");
+ }
+ }
+
private void DeleteData(int index)
{
try
@@ -168,7 +251,7 @@
if (MsgBoxHelper.WarnMessage(Window.GetWindow(this), this.lang("HMI.MakeSureDeleteThis")) == MessageBoxResult.OK)
{
var file = ItemIndex == 0 ? blockFile : markFile;
- var temp = XmlHelper.DeepClone(Datasource);
+ var temp = XmlHelper.DeepClone(ItemIndex == 0 ? Datasource : MarkDatasource);
temp.RemoveAt(index);
XmlHelper.SerializeToXml(file, temp);
@@ -185,7 +268,7 @@
{
try
{
- var temp = Datasource.Where(e => e.IsSelected).ToList();
+ var temp = (ItemIndex == 0 ? Datasource : MarkDatasource).Where(e => e.IsSelected).ToList();
if (temp == null || temp.Count <= 0)
{
ToastHelper.Warning(Window.GetWindow(this), this.lang("HMI.NoDeleteData"));
@@ -196,7 +279,7 @@
== MessageBoxResult.OK)
{
var file = ItemIndex == 0 ? blockFile : markFile;
- temp = Datasource.Where(e => !e.IsSelected).ToList();
+ temp = (ItemIndex == 0 ? Datasource : MarkDatasource).Where(e => !e.IsSelected).ToList();
XmlHelper.SerializeToXml(file, temp);
LoadData();
}
diff --git a/HMI.AlermInfoManage/Entity/AlarmSetting.cs b/HMI.AlermInfoManage/Entity/AlarmSetting.cs
index d612d6a..1ca7090 100644
--- a/HMI.AlermInfoManage/Entity/AlarmSetting.cs
+++ b/HMI.AlermInfoManage/Entity/AlarmSetting.cs
@@ -1,4 +1,5 @@
-锘縰sing HMI.Core.Entity;
+锘縰sing HMI.Core;
+using HMI.Core.Entity;
namespace HMI.AlarmInfoManage.Entity
{
@@ -9,16 +10,22 @@
/// <summary>
/// 寮�濮婦B鍦板潃
/// </summary>
- public int DBAddress { get; set; }
+ [ExcelColumn("DB鍦板潃")]
+ public string DBAddress { get; set; }
/// <summary>
/// 璧峰Byte浣�
/// </summary>
- public int StartAddress { get; set; }
+ [ExcelColumn("璧峰浣�")]
+ public string StartAddress { get; set; }
/// <summary>
/// 闀垮害
/// </summary>
+ [ExcelColumn("闀垮害")]
public int Length { get; set; }
+
+ [ExcelColumn("鎶ヨ鎻忚堪")]
+ public string Description { get; set; }
}
}
diff --git a/HMI.AlermInfoManage/Entity/AlarmText.cs b/HMI.AlermInfoManage/Entity/AlarmText.cs
index e431b70..ea746d4 100644
--- a/HMI.AlermInfoManage/Entity/AlarmText.cs
+++ b/HMI.AlermInfoManage/Entity/AlarmText.cs
@@ -1,4 +1,5 @@
-锘縰sing System.Xml.Serialization;
+锘縰sing HMI.Core;
+using System.Xml.Serialization;
namespace HMI.AlarmInfoManage.Entity
{
@@ -7,42 +8,50 @@
/// <summary>
/// 鎶ヨ浠g爜
/// </summary>
+ [ExcelColumn("缁勫悎鎶ヨ浠g爜")]
public string AlarmCode { get; set; }
/// <summary>
/// 宸ヤ綅缂栧彿
/// </summary>
+ [ExcelColumn("璁惧鍙�")]
public string OpNo { get; set; }
/// <summary>
/// 妯″潡缂栧彿
/// </summary>
+ [ExcelColumn("妯″潡鍙�")]
public string ModuleNo { get; set; }
/// <summary>
/// 妯″潡鍚嶇О(CN)
/// </summary>
+ [ExcelColumn("妯″潡鍚嶇О-CN")]
public string ModuleName_CN { get; set; }
/// <summary>
/// 妯″潡鍚嶇О(EN)
/// </summary>
+ [ExcelColumn("妯″潡鍚嶇О-US")]
public string ModuleName_EN { get; set; }
/// <summary>
/// 妯″潡鎶ヨ浠g爜
/// </summary>
+ [ExcelColumn("鎶ヨ浠g爜")]
public string MAlarmCode { get; set; }
/// <summary>
/// 妯″潡鎶ヨ鏂囨湰(CN)
/// </summary>
+ [ExcelColumn("鎶ヨ淇℃伅鏂囨湰-CN")]
public string MAlarmText_CN { get; set; }
/// <summary>
/// 妯″潡鎶ヨ鏂囨湰(EN)
/// </summary>
+ [ExcelColumn("鎶ヨ淇℃伅鏂囨湰-US")]
public string MAlarmText_EN { get; set; }
/// <summary>
@@ -50,6 +59,9 @@
/// </summary>
public string Time { get; set; }
+ [XmlIgnore]
+ public string AlarmInfo { get; set; }
+
/// <summary>
/// 鎶ヨ鏉ユ簮
/// </summary>
diff --git a/HMI.AlermInfoManage/HMI.AlarmInfoManage.csproj b/HMI.AlermInfoManage/HMI.AlarmInfoManage.csproj
index 452376a..c888b53 100644
--- a/HMI.AlermInfoManage/HMI.AlarmInfoManage.csproj
+++ b/HMI.AlermInfoManage/HMI.AlarmInfoManage.csproj
@@ -95,10 +95,17 @@
<Reference Include="PresentationFramework" />
</ItemGroup>
<ItemGroup>
+ <Page Include="SimpleAlarm.xaml">
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ </Page>
<Page Include="AlarmInfoManage.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
+ <Compile Include="SimpleAlarm.xaml.cs">
+ <DependentUpon>SimpleAlarm.xaml</DependentUpon>
+ </Compile>
<Compile Include="AlarmInfoManage.xaml.cs">
<DependentUpon>AlarmInfoManage.xaml</DependentUpon>
<SubType>Code</SubType>
@@ -155,6 +162,10 @@
</None>
</ItemGroup>
<ItemGroup>
+ <ProjectReference Include="..\..\ConnectionUtil\ConnectionUtil\ConnectionUtil.csproj">
+ <Project>{D0806FA6-3F6D-4304-81B8-EAD9DA7CB5B2}</Project>
+ <Name>ConnectionUtil</Name>
+ </ProjectReference>
<ProjectReference Include="..\HMI.Base\HMI.Base.csproj">
<Project>{2a6f9720-a890-4036-9d73-41a0dae28341}</Project>
<Name>HMI.Base</Name>
@@ -167,6 +178,14 @@
<Project>{f17de6b5-af1d-48c6-94a0-6b763a6546a6}</Project>
<Name>HMI.UI</Name>
</ProjectReference>
+ <ProjectReference Include="..\HMI.Util\HMI.Util.csproj">
+ <Project>{AFEA100A-9223-448D-AB10-3015D93DD98C}</Project>
+ <Name>HMI.Util</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\OPCClient\OPCClient.csproj">
+ <Project>{E5740BB5-9FC6-4A20-B7C2-CC90C281ED05}</Project>
+ <Name>OPCClient</Name>
+ </ProjectReference>
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
diff --git a/HMI.AlermInfoManage/Modal/AlarmSettingModal.xaml b/HMI.AlermInfoManage/Modal/AlarmSettingModal.xaml
index da381d3..6dca9df 100644
--- a/HMI.AlermInfoManage/Modal/AlarmSettingModal.xaml
+++ b/HMI.AlermInfoManage/Modal/AlarmSettingModal.xaml
@@ -24,19 +24,25 @@
dp:FormGroupHelper.IsRequired="True"
dp:FormGroupHelper.ValidateMethod="ValidateDBAddress"
GroupName="MyFormGroup">
- <pu:NumberInput Style="{StaticResource FormNumberInput}"
- x:Name="dbAddress" Interval="1"/>
+ <TextBox Style="{StaticResource EditorTextBoxStyle}"
+ x:Name="dbAddress"/>
</pu:FormGroup>
<pu:FormGroup Header="{DynamicResource Alm.StartAddress}" dp:FormGroupHelper.IsRequired="True"
GroupName="MyFormGroup">
- <pu:NumberInput Style="{StaticResource FormNumberInput}" x:Name="startAddress" Interval="1"/>
+ <TextBox Style="{StaticResource EditorTextBoxStyle}"
+ x:Name="startAddress"/>
</pu:FormGroup>
<pu:FormGroup Header="{DynamicResource Alm.DbLength}" dp:FormGroupHelper.IsRequired="True"
GroupName="MyFormGroup">
<pu:NumberInput Style="{StaticResource FormNumberInput}" x:Name="length" Interval="1"/>
</pu:FormGroup>
+
+ <pu:FormGroup x:Name="FgDesc" Header="{DynamicResource Alm.Description}" dp:FormGroupHelper.IsRequired="True"
+ GroupName="MyFormGroup">
+ <TextBox Style="{StaticResource EditorTextBoxStyle}" x:Name="TbDesc"/>
+ </pu:FormGroup>
</StackPanel>
</Grid>
</pu:WindowX>
diff --git a/HMI.AlermInfoManage/Modal/AlarmSettingModal.xaml.cs b/HMI.AlermInfoManage/Modal/AlarmSettingModal.xaml.cs
index a1ab9e5..08f0f70 100644
--- a/HMI.AlermInfoManage/Modal/AlarmSettingModal.xaml.cs
+++ b/HMI.AlermInfoManage/Modal/AlarmSettingModal.xaml.cs
@@ -8,6 +8,7 @@
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
+using System.Windows;
namespace HMI.AlarmInfoManage
{
@@ -72,8 +73,7 @@
public bool ValidateDBAddress(object value, out string err)
{
err = null;
- int dbAddress = Convert.ToInt32(value);
- if (Datasource.FirstOrDefault(e => e.DBAddress == dbAddress) != null)
+ if (Datasource?.FirstOrDefault(e => e.DBAddress == value) != null)
{
err = this.lang("App.MustBeUnique", this.lang("Alm.DbAddress"));
return false;
@@ -86,24 +86,27 @@
bool flag = FormGroupHelper.ValidateForm(formPanel);
if (flag)
{
- Data.DBAddress = Convert.ToInt32(dbAddress.Value);
- Data.StartAddress = Convert.ToInt32(startAddress.Value);
+ Data.DBAddress = dbAddress.Text;
+ Data.StartAddress = startAddress.Text;
Data.Length = Convert.ToInt32(length.Value);
+ Data.Description = TbDesc.Text;
}
return flag;
}
public bool? Open(int index, AlarmSetting data,
ObservableCollection<AlarmSetting> dataSource,
- string filePath)
+ string filePath, bool showDescription)
{
+ FgDesc.Visibility = showDescription ? Visibility.Visible : Visibility.Collapsed;
FilePath = filePath;
DataIndex = index;
Data = data;
Datasource = dataSource;
- dbAddress.Value = Data.DBAddress;
- startAddress.Value = Data.StartAddress;
+ dbAddress.Text = Data.DBAddress;
+ startAddress.Text = Data.StartAddress;
length.Value = Data.Length;
+ TbDesc.Text = Data.Description;
return this.ShowDialog();
}
diff --git a/HMI.AlermInfoManage/Model/XmlModel.cs b/HMI.AlermInfoManage/Model/XmlModel.cs
index f1eb4b1..eea1f87 100644
--- a/HMI.AlermInfoManage/Model/XmlModel.cs
+++ b/HMI.AlermInfoManage/Model/XmlModel.cs
@@ -1,14 +1,5 @@
-锘縰sing HMI.AlarmInfoManage.Entity;
-using HMI.Core.Entity;
-using HMI.Core.Util;
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Data;
+锘縰sing HMI.Core.Entity;
using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
namespace HMI.AlarmInfoManage.Model
{
@@ -18,13 +9,7 @@
public string AlermTextPath { get; private set; }
public string AlermSettingPath { get; private set; }
- private ObservableCollection<AlarmText> datasource = new ObservableCollection<AlarmText>();
-
- public ObservableCollection<AlarmText> Datasource
- {
- get { return datasource; }
- set { Set(ref datasource, value); }
- }
+
public XmlUIModel(string FileFolder)
{
diff --git a/HMI.AlermInfoManage/SimpleAlarm.xaml b/HMI.AlermInfoManage/SimpleAlarm.xaml
new file mode 100644
index 0000000..93b4d9e
--- /dev/null
+++ b/HMI.AlermInfoManage/SimpleAlarm.xaml
@@ -0,0 +1,96 @@
+锘�<hb:PluginControl x:Class="HMI.AlarmInfoManage.SimpleAlarm"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:hb="clr-namespace:HMI.Base;assembly=HMI.Base"
+ xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
+ xmlns:local="clr-namespace:HMI.AlarmInfoManage"
+ xmlns:uic="clr-namespace:HMI.UI.Converter;assembly=HMI.UI"
+ xmlns:pw="https://opensource.panuon.com/wpf"
+ xmlns:pu="https://opensource.panuon.com/wpf-ui"
+ mc:Ignorable="d"
+ Background="{StaticResource WorkspaceBackground}"
+ Loaded="UserControl_Loaded"
+ d:DesignHeight="450" d:DesignWidth="800">
+
+ <Border Style="{StaticResource CardBoarder}">
+ <DockPanel>
+ <DockPanel Margin="0,0,0,10" DockPanel.Dock="Top">
+ <StackPanel DockPanel.Dock="Right" Style="{StaticResource ButtonGroup}">
+ <Button Style="{StaticResource RfhBtn}" x:Name="refreshBtn" Click="Button_Click"/>
+ <Button Style="{StaticResource ExportBtn}" x:Name="exportBtn" Click="Button_Click"/>
+ </StackPanel>
+
+ <TextBlock DockPanel.Dock="Left" FontSize="{StaticResource TitleFontSize}"
+ VerticalAlignment="Center" HorizontalAlignment="Left" Text="{DynamicResource Alm.Title}"/>
+ </DockPanel>
+
+ <pu:Pagination DockPanel.Dock="Bottom" Margin="0,10,0,0" Height="30"
+ FontSize="14"
+HorizontalAlignment="Left"
+Foreground="Black"
+ItemsBackground="Transparent"
+ItemsCornerRadius="12"
+ItemsSelectedBackground="#36AAF7" CurrentPage="1" MaxPage="10"/>
+ <DataGrid x:Name="table" Style="{StaticResource DefaultDataGrid}" ItemsSource="{Binding Datasource}">
+ <DataGrid.Columns>
+ <DataGridTemplateColumn Header="" Width="Auto" CanUserResize="False">
+ <DataGridTemplateColumn.CellTemplate>
+ <DataTemplate>
+ <CheckBox VerticalAlignment="Center" IsChecked="{Binding Selected,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
+ </DataTemplate>
+ </DataGridTemplateColumn.CellTemplate>
+ </DataGridTemplateColumn>
+ <DataGridTemplateColumn Header="#" CanUserResize="False">
+ <DataGridTemplateColumn.CellTemplate>
+ <DataTemplate>
+ <TextBlock Text="{Binding Converter={StaticResource rowNumber},
+ RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGridRow},AncestorLevel=1}}"/>
+ </DataTemplate>
+ </DataGridTemplateColumn.CellTemplate>
+ </DataGridTemplateColumn>
+ <DataGridTextColumn Width="*" Binding="{Binding Source}">
+ <DataGridTextColumn.Header>
+ <TextBlock Text="{DynamicResource Alm.Source}"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>
+ <DataGridTextColumn Width="*" Binding="{Binding Code}">
+ <DataGridTextColumn.Header>
+ <TextBlock Text="{DynamicResource Alm.Code}"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>
+ <DataGridTextColumn Width="*" Binding="{Binding Info}">
+ <DataGridTextColumn.Header>
+ <TextBlock Text="{DynamicResource Alm.Info}"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>
+ <DataGridTextColumn Width="*" Binding="{Binding Time}">
+ <DataGridTextColumn.Header>
+ <TextBlock Text="{DynamicResource Alm.Time}"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>
+ <!--<DataGridTemplateColumn Width="100" IsReadOnly="True" CanUserResize="False">
+ <DataGridTemplateColumn.Header>
+ <TextBlock Text="{DynamicResource App.Opt}"/>
+ </DataGridTemplateColumn.Header>
+ <DataGridTemplateColumn.CellTemplate>
+ <DataTemplate>
+ <StackPanel Orientation="Horizontal">
+ <Button x:Name="editBtn" Style="{StaticResource EditLink}"
+ Margin="0,0,10,0"
+ Click="Button_Click"
+ DataContext="{Binding }"/>
+ <Button x:Name="delBtn" Style="{StaticResource DeleteLink}"
+ DataContext="{Binding }"
+ Click="Button_Click"/>
+ </StackPanel>
+ </DataTemplate>
+ </DataGridTemplateColumn.CellTemplate>
+ </DataGridTemplateColumn>-->
+ </DataGrid.Columns>
+ </DataGrid>
+
+ </DockPanel>
+ </Border>
+</hb:PluginControl>
diff --git a/HMI.AlermInfoManage/SimpleAlarm.xaml.cs b/HMI.AlermInfoManage/SimpleAlarm.xaml.cs
new file mode 100644
index 0000000..f323f1d
--- /dev/null
+++ b/HMI.AlermInfoManage/SimpleAlarm.xaml.cs
@@ -0,0 +1,100 @@
+锘縰sing HMI.Base;
+using HMI.Core.Util;
+using System;
+using System.IO;
+using System.Timers;
+using System.Windows;
+using System.Windows.Controls;
+
+namespace HMI.AlarmInfoManage
+{
+ /// <summary>
+ /// UserControl1.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ public partial class SimpleAlarm : PluginControl
+ {
+ private string dbPath;
+ private SqliteHelper sqliteHelper;
+ private Timer MonitorTimer;
+
+ public SimpleAlarm()
+ {
+ DataContext = this;
+ InitializeComponent();
+ }
+
+ public override void InitFinish()
+ {
+ dbPath = Path.Combine(BaseFolder, "alarm.db");
+ if (!File.Exists(dbPath))
+ {
+ SqliteHelper.CreateDatabase(dbPath);
+ sqliteHelper = new SqliteHelper(dbPath);
+ sqliteHelper.ExecuteSql(@"CREATE TABLE IF NOT EXISTS Alarm (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ source TEXT NOT NULL,
+ alarmcode TEXT,
+ alarminfo TEXT,
+ time DATETIME);");
+ }
+ }
+
+ private void Button_Click(object sender, RoutedEventArgs e)
+ {
+ Button btn = sender as Button;
+ switch (btn.Name)
+ {
+ case "refreshBtn":
+ //Model.
+ break;
+ case "exportBtn":
+ //ImportText();
+ break;
+ default:
+ break;
+ }
+ }
+
+ private void UserControl_Loaded(object sender, RoutedEventArgs e)
+ {
+ MonitorTimer = new Timer
+ {
+ Interval = 100,
+ };
+ MonitorTimer.Elapsed += MonitorTimer_Elapsed;
+
+ Loaded -= UserControl_Loaded;
+ }
+
+
+ private void MonitorTimer_Elapsed(object sender, ElapsedEventArgs e)
+ {
+ try
+ {
+ this.MonitorTimer.Enabled = false;
+ this.RefershAlarm();
+ }
+ catch (Exception ex)
+ {
+ log.Error("sdadsa", ex);
+ }
+ finally
+ {
+ this.MonitorTimer.Enabled = true;
+ }
+ }
+
+ /// <summary>
+ /// 鍒锋柊鎶ヨ淇℃伅
+ /// </summary>
+ private void RefershAlarm()
+ {
+
+ }
+
+ public override void SetBaseFolder(string folder)
+ {
+ base.SetBaseFolder(folder);
+ }
+ }
+}
diff --git a/HMI.Base/HMI.Base.csproj b/HMI.Base/HMI.Base.csproj
index 5203494..676e63f 100644
--- a/HMI.Base/HMI.Base.csproj
+++ b/HMI.Base/HMI.Base.csproj
@@ -72,6 +72,8 @@
</ItemGroup>
<ItemGroup>
<Compile Include="DtConverter.cs" />
+ <Compile Include="PluginMaskControl.cs" />
+ <Compile Include="SimpleControl.cs" />
<Compile Include="PluginControl.cs" />
<Compile Include="PluginInfo.cs" />
<Compile Include="PluginLoader.cs" />
@@ -88,6 +90,7 @@
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
+ <Compile Include="SimpleMaskControl.cs" />
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
@@ -103,6 +106,20 @@
<Project>{3e3bf44a-0b69-45c5-9512-528cb48a7106}</Project>
<Name>HMI.Core</Name>
</ProjectReference>
+ <ProjectReference Include="..\HMI.UI\HMI.UI.csproj">
+ <Project>{f17de6b5-af1d-48c6-94a0-6b763a6546a6}</Project>
+ <Name>HMI.UI</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <Page Include="MaskControl.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
+ <Page Include="Themes\Generic.xaml">
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ </Page>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
\ No newline at end of file
diff --git a/HMI.Base/MaskControl.xaml b/HMI.Base/MaskControl.xaml
new file mode 100644
index 0000000..7e58c72
--- /dev/null
+++ b/HMI.Base/MaskControl.xaml
@@ -0,0 +1,32 @@
+锘�<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:ui="clr-namespace:HMI.UI;assembly=HMI.UI"
+ xmlns:local="clr-namespace:HMI.Base">
+ <Style x:Key="simpleMaskControl" TargetType="local:SimpleMaskControl">
+ <Setter Property="Template">
+ <Setter.Value>
+ <ControlTemplate TargetType="local:SimpleMaskControl">
+ <Grid>
+ <ContentPresenter Content="{TemplateBinding Content}"/>
+
+ <ui:MaskControl x:Name="mask"/>
+ </Grid>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style>
+
+ <Style x:Key="pluginMaskControl" TargetType="local:PluginMaskControl">
+ <Setter Property="Template">
+ <Setter.Value>
+ <ControlTemplate TargetType="local:PluginMaskControl">
+ <Grid>
+ <ContentPresenter Content="{TemplateBinding Content}"/>
+
+ <ui:MaskControl x:Name="mask"/>
+ </Grid>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style>
+</ResourceDictionary>
\ No newline at end of file
diff --git a/HMI.Base/PluginLoader.cs b/HMI.Base/PluginLoader.cs
index e63503a..f295e9d 100644
--- a/HMI.Base/PluginLoader.cs
+++ b/HMI.Base/PluginLoader.cs
@@ -4,7 +4,6 @@
using log4net;
using System;
using System.Collections.Generic;
-using System.Data;
using System.IO;
using System.Reflection;
using System.Threading;
@@ -31,7 +30,6 @@
private static ILog log = LogManager.GetLogger("PluginLoader");
private static string PluginFolder = PathHelper.PluginFolder();
- public bool Completed { get; private set; } = false;
public SqliteHelper sqliteHelper;
public List<PluginInfo> Menus { get; private set; }
public List<PluginInfo> Plugins { get; private set; }
@@ -50,6 +48,7 @@
{
Instance = null;
}
+ GC.Collect();
}
public static PluginLoader GetLoader()
@@ -76,6 +75,12 @@
LoadMessageAppend?.Invoke(this, new LoadMsg { Type = LoadMsgType.FINISHED });
});
}
+ pluginContainer.DoCloseEvent += PluginContainer_DoCloseEvent;
+ }
+
+ private void PluginContainer_DoCloseEvent(object sender, EventArgs e)
+ {
+ Reset();
}
private void LoadChildrenMenu()
@@ -83,7 +88,7 @@
foreach (var menu in Plugins)
{
CountdownEvent c = new CountdownEvent(1);
- Thread.Sleep(80);
+ Thread.Sleep(50);
Application.Current.Dispatcher.Invoke(new Action(() =>
{
try
@@ -158,21 +163,39 @@
}
}
+ private PluginInfo ConvertPermission2PluginInfo(PermissionData data)
+ {
+ if (data.Type == "鏉冮檺") return null;
+ PluginInfo info = new PluginInfo
+ {
+ Code = data.Code,
+ Name = data.Name,
+ Type = data.Type,
+ ParentCode = data.ParentCode,
+ DllPath = data.DllPath,
+ ClassName = data.ClassName,
+ IconFont = data.IconFont
+ //Icon = new BitmapImage(new Uri(Path.Combine(PathHelper.IconFolder, dr["iconPath"].ToString())))
+ };
+ if (data.Children != null && data.Children.Count > 0)
+ {
+ foreach (var child in data.Children)
+ {
+ var childInfo = ConvertPermission2PluginInfo(child);
+ if (childInfo != null) info.Children.Add(childInfo);
+ }
+ }
+ return info;
+ }
+
public List<PluginInfo> LoadTreeMenu(Dispatcher dispatcher)
{
- //LoadMessageAppend?.Invoke(this, "寮�濮嬪姞杞借彍鍗�...");
- List<PluginInfo> data = new List<PluginInfo>();
+ List<PluginInfo> menus = new List<PluginInfo>();
Dictionary<string, PluginInfo> cache = new Dictionary<string, PluginInfo>();
try
{
- UserInfo user = UserInfo.User;
- string sql = $@"SELECT DISTINCT m.* FROM menu AS m INNER JOIN role_menu_rel AS rrel ON m.code = rrel.menuCode
-INNER JOIN role AS r ON rrel.roleCode = r.code
-INNER JOIN user_role_rel AS urel ON r.code = urel.roleCode
-AND urel.username = '{user.Username}' ORDER BY m.level,m.sort, m.id;";
-
- DataTable dt = sqliteHelper.GetDataTable(sql);
- if (dt != null)
+ List<PermissionData> allPermissions = UserInfo.User?.AllPermissions;
+ if (allPermissions != null)
{
Application.Current.Dispatcher.Invoke(() =>
{
@@ -180,28 +203,27 @@
new LoadMsg
{
Type = LoadMsgType.INIT,
- NumData = dt.Rows.Count,
- Message = this.lang("App.MenuCount", dt.Rows.Count),
+ NumData = allPermissions.Count,
+ Message = this.lang("App.MenuCount", allPermissions.Count),
});
- foreach (DataRow dr in dt.Rows)
+ foreach (PermissionData data in allPermissions)
{
- string path = Path.Combine(PathHelper.IconFolder, dr["iconPath"].ToString());
+ if (data.Type == "Permission") continue;
var menu = new PluginInfo
{
- Code = dr["code"].ToString(),
- Name = dr["name"].ToString(),
- Type = dr["type"].ToString(),
- ParentCode = dr["parentCode"].ToString(),
- DllPath = dr["dllPath"].ToString(),
- ClassName = dr["className"].ToString(),
- IconFont = dr["icon"].ToString()
- //Icon = new BitmapImage(new Uri(Path.Combine(PathHelper.IconFolder, dr["iconPath"].ToString())))
+ Code = data.Code,
+ Name = data.Name,
+ Type = data.Type,
+ ParentCode = data.ParentCode,
+ DllPath = data.DllPath,
+ ClassName = data.ClassName,
+ IconFont = data.IconFont
};
cache[menu.Code] = menu;
if (!cache.ContainsKey(menu.ParentCode))
{
- data.Add(menu);
+ menus.Add(menu);
}
else
{
@@ -217,7 +239,7 @@
{
//LoadMessageAppend?.Invoke(this, ex.Message);
}
- return data;
+ return menus;
}
}
}
diff --git a/HMI.Base/PluginMaskControl.cs b/HMI.Base/PluginMaskControl.cs
new file mode 100644
index 0000000..21be635
--- /dev/null
+++ b/HMI.Base/PluginMaskControl.cs
@@ -0,0 +1,89 @@
+锘縰sing System;
+using System.ComponentModel;
+using System.Runtime.CompilerServices;
+using System.Windows.Controls;
+using HMI.Core.Api;
+using HMI.UI;
+using log4net;
+
+namespace HMI.Base
+{
+ public class PluginMaskControl : UserControl, IPlugin, INotifyPropertyChanged
+ {
+ #region ...
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ protected void Set([CallerMemberName] string name = null)
+ {
+
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
+ }
+
+ protected void Set<T>(ref T old, T @new, [CallerMemberName] string propertyName = null)
+ {
+ old = @new;
+ if (propertyName != null)
+ {
+ Set(propertyName);
+ }
+ }
+ #endregion
+
+ protected ILog log;
+ protected string BaseFolder;
+
+ public virtual void Active()
+ {
+
+ }
+
+ public virtual void DeActive()
+ {
+
+ }
+
+ public virtual void Init()
+ {
+
+ }
+
+ public virtual void OnTabChange(object sender, object args)
+ {
+
+ }
+
+ public virtual void SetBaseFolder(string folder)
+ {
+ BaseFolder = folder;
+ }
+
+ public virtual void SetLogger(ILog logger)
+ {
+ log = logger;
+ }
+
+ public virtual void InitFinish()
+ {
+
+ }
+
+ public virtual void OnClose(object sender, CancelEventArgs e)
+ {
+
+ }
+
+ public virtual void DoClose(object sender, EventArgs e)
+ {
+
+ }
+
+ public void ShowMask(Action action, Action<Exception> reject = null, string title = null, string content = null)
+ {
+ MaskControl mask = this.Template.FindName("mask", this) as MaskControl;
+ if (mask != null)
+ {
+ mask.ShowMask(this, action, reject, title, content);
+ }
+ }
+ }
+}
diff --git a/HMI.Base/SimpleControl.cs b/HMI.Base/SimpleControl.cs
new file mode 100644
index 0000000..c5f5414
--- /dev/null
+++ b/HMI.Base/SimpleControl.cs
@@ -0,0 +1,59 @@
+锘縰sing System;
+using System.ComponentModel;
+using System.Windows.Controls;
+using HMI.Core.Api;
+using log4net;
+
+namespace HMI.Base
+{
+ public class SimpleControl : UserControl, IPlugin
+ {
+ protected ILog log;
+ protected string BaseFolder;
+
+ public virtual void Active()
+ {
+
+ }
+
+ public virtual void DeActive()
+ {
+
+ }
+
+ public virtual void Init()
+ {
+
+ }
+
+ public virtual void OnTabChange(object sender, object args)
+ {
+
+ }
+
+ public virtual void SetBaseFolder(string folder)
+ {
+ BaseFolder = folder;
+ }
+
+ public virtual void SetLogger(ILog logger)
+ {
+ log = logger;
+ }
+
+ public virtual void InitFinish()
+ {
+
+ }
+
+ public virtual void OnClose(object sender, CancelEventArgs e)
+ {
+
+ }
+
+ public virtual void DoClose(object sender, EventArgs e)
+ {
+
+ }
+ }
+}
diff --git a/HMI.Base/SimpleMaskControl.cs b/HMI.Base/SimpleMaskControl.cs
new file mode 100644
index 0000000..c0a3d3f
--- /dev/null
+++ b/HMI.Base/SimpleMaskControl.cs
@@ -0,0 +1,79 @@
+锘縰sing HMI.Core.Api;
+using HMI.UI;
+using log4net;
+using System;
+using System.ComponentModel;
+using System.Windows;
+using System.Windows.Controls;
+
+namespace HMI.Base
+{
+ /// <summary>
+ /// PluginMaskControl.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ public partial class SimpleMaskControl : UserControl, IPlugin
+ {
+ static SimpleMaskControl()
+ {
+ DefaultStyleKeyProperty.OverrideMetadata(typeof(SimpleMaskControl),
+ new FrameworkPropertyMetadata(typeof(SimpleMaskControl)));
+ }
+
+ protected ILog log;
+ protected string BaseFolder;
+
+ public virtual void Active()
+ {
+
+ }
+
+ public virtual void DeActive()
+ {
+
+ }
+
+ public virtual void Init()
+ {
+
+ }
+
+ public virtual void OnTabChange(object sender, object args)
+ {
+
+ }
+
+ public virtual void SetBaseFolder(string folder)
+ {
+ BaseFolder = folder;
+ }
+
+ public virtual void SetLogger(ILog logger)
+ {
+ log = logger;
+ }
+
+ public virtual void InitFinish()
+ {
+
+ }
+
+ public virtual void OnClose(object sender, CancelEventArgs e)
+ {
+
+ }
+
+ public virtual void DoClose(object sender, EventArgs e)
+ {
+
+ }
+
+ public void ShowMask(Action action, Action<Exception> reject = null, string title = null, string content = null)
+ {
+ MaskControl mask = this.Template.FindName("mask", this) as MaskControl;
+ if (mask != null)
+ {
+ mask.ShowMask(this, action, reject, title, content);
+ }
+ }
+ }
+}
diff --git a/HMI.Base/Themes/Generic.xaml b/HMI.Base/Themes/Generic.xaml
new file mode 100644
index 0000000..d220045
--- /dev/null
+++ b/HMI.Base/Themes/Generic.xaml
@@ -0,0 +1,32 @@
+锘�<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:local="clr-namespace:HMI.Base"
+ xmlns:ui="clr-namespace:HMI.UI;assembly=HMI.UI">
+ <Style TargetType="local:SimpleMaskControl">
+ <Setter Property="Template">
+ <Setter.Value>
+ <ControlTemplate TargetType="local:SimpleMaskControl">
+ <Grid Background="{TemplateBinding Background}">
+ <ContentPresenter Content="{TemplateBinding Content}"/>
+
+ <ui:MaskControl x:Name="mask"/>
+ </Grid>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style>
+
+ <Style TargetType="local:PluginMaskControl">
+ <Setter Property="Template">
+ <Setter.Value>
+ <ControlTemplate TargetType="local:PluginMaskControl">
+ <Grid>
+ <ContentPresenter Content="{TemplateBinding Content}"/>
+
+ <ui:MaskControl x:Name="mask"/>
+ </Grid>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style>
+</ResourceDictionary>
\ No newline at end of file
diff --git a/HMI.Core/Api/AlarmShowHelper.cs b/HMI.Core/Api/AlarmShowHelper.cs
new file mode 100644
index 0000000..172a9ef
--- /dev/null
+++ b/HMI.Core/Api/AlarmShowHelper.cs
@@ -0,0 +1,24 @@
+锘縩amespace HMI.Core.Api
+{
+ public class AlarmShowHelper
+ {
+ private static IAlarmShow shower;
+
+ public static void Register(IAlarmShow shower)
+ {
+ if (AlarmShowHelper.shower == null)
+ {
+ AlarmShowHelper.shower = shower;
+ }
+ }
+
+ public static bool ShowAlarm(string message)
+ {
+ if (shower != null)
+ {
+ return shower.ShowAlarm(message);
+ }
+ return false;
+ }
+ }
+}
diff --git a/HMI.Core/Api/IAlarmShow.cs b/HMI.Core/Api/IAlarmShow.cs
new file mode 100644
index 0000000..65c2243
--- /dev/null
+++ b/HMI.Core/Api/IAlarmShow.cs
@@ -0,0 +1,13 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HMI.Core.Api
+{
+ public interface IAlarmShow
+ {
+ bool ShowAlarm(string message);
+ }
+}
diff --git a/HMI.Core/DpUtil/PermissionHelper.cs b/HMI.Core/DpUtil/PermissionHelper.cs
new file mode 100644
index 0000000..cfcaec3
--- /dev/null
+++ b/HMI.Core/DpUtil/PermissionHelper.cs
@@ -0,0 +1,47 @@
+锘縰sing HMI.Core.Entity;
+using System.Linq;
+using System.Windows;
+
+namespace HMI.Core.DpUtil
+{
+ public class PermissionHelper
+ {
+ public static string GetRequiredPermission(UIElement element)
+ {
+ return (string)element.GetValue(RequiredPermissionProperty);
+ }
+
+ public static void SetRequiredPermission(UIElement element, string requiredPermission)
+ {
+ element.SetValue(RequiredPermissionProperty, requiredPermission);
+ }
+
+ public static readonly DependencyProperty RequiredPermissionProperty =
+ DependencyProperty.RegisterAttached("RequiredPermission", typeof(string), typeof(UIElement),
+ new PropertyMetadata(string.Empty, OnRequiredPermissionChanged));
+
+ private static void OnRequiredPermissionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ if (d is UIElement element)
+ {
+ if (e.Property == RequiredPermissionProperty)
+ {
+ var requiredPermission = (string)e.NewValue;
+ if (string.IsNullOrEmpty(requiredPermission)) return;
+ if (UserInfo.User == null)
+ {
+ element.Visibility = Visibility.Collapsed;
+ return;
+ }
+ if (UserInfo.User?.AllPermissions == null)
+ {
+ element.Visibility = Visibility.Collapsed;
+ return;
+ }
+ if (UserInfo.User.AllPermissions.FirstOrDefault(p => p.Code == requiredPermission) != null) return;
+ element.Visibility = Visibility.Collapsed;
+ }
+ }
+ }
+ }
+}
diff --git a/HMI.Core/Entity/PermissionData.cs b/HMI.Core/Entity/PermissionData.cs
new file mode 100644
index 0000000..905a8a7
--- /dev/null
+++ b/HMI.Core/Entity/PermissionData.cs
@@ -0,0 +1,24 @@
+锘縰sing System.Collections.Generic;
+
+namespace HMI.Core.Entity
+{
+ public class PermissionData
+ {
+ public string Id { get; set; }
+ public string Code { get; set; }
+ public string Name { get; set; }
+ public string IconPath { get; set; }
+ public string Icon { get; set; }
+ public string Level { get; set; }
+ public string Type { get; set; }
+ public string ParentCode { get; set; }
+ public string ParentName { get; set; }
+ public string DllPath { get; set; }
+ public string ClassName { get; set; }
+ public string IconFont { get; set; }
+
+ public double? Sort { get; set; }
+
+ public List<PermissionData> Children { get; set; } = new List<PermissionData>();
+ }
+}
diff --git a/HMI.Core/Entity/UserInfo.cs b/HMI.Core/Entity/UserInfo.cs
index c9b644d..49d8d31 100644
--- a/HMI.Core/Entity/UserInfo.cs
+++ b/HMI.Core/Entity/UserInfo.cs
@@ -1,15 +1,22 @@
-锘縩amespace HMI.Core.Entity
+锘縰sing System.Collections.Generic;
+
+namespace HMI.Core.Entity
{
public class UserInfo
{
public static UserInfo User { get; private set; }
- public UserInfo(string id, string code, string username, string name, string password = null)
+ public UserInfo(string id, string code, string username, string name,
+ List<PermissionData> permissions,
+ List<PermissionData> allPermissions,
+ string password = null)
{
Id = id;
Code = code;
Username = username;
Name = name;
Password = password;
+ Permissions = permissions;
+ AllPermissions = allPermissions;
}
public string Id { get; private set; }
@@ -17,6 +24,8 @@
public string Username { get; private set; }
public string Name { get; private set; }
public string Password { get; private set; }
+ public List<PermissionData> Permissions { get; private set; }
+ public List<PermissionData> AllPermissions { get; private set; }
public static void Login(UserInfo info)
{
diff --git a/HMI.Core/HMI.Core.csproj b/HMI.Core/HMI.Core.csproj
index 600e655..43134dc 100644
--- a/HMI.Core/HMI.Core.csproj
+++ b/HMI.Core/HMI.Core.csproj
@@ -87,6 +87,8 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Annotation\ExcelColumn.cs" />
+ <Compile Include="Api\AlarmShowHelper.cs" />
+ <Compile Include="Api\IAlarmShow.cs" />
<Compile Include="Api\IConfigManager.cs" />
<Compile Include="Api\IConfigRefresh.cs" />
<Compile Include="Api\IFolderOwner.cs" />
@@ -95,9 +97,11 @@
<Compile Include="Api\IPluginContainer.cs" />
<Compile Include="Annotation\InitAttribute.cs" />
<Compile Include="Api\PluginPackage.cs" />
+ <Compile Include="DpUtil\PermissionHelper.cs" />
<Compile Include="Entity\LangInfo.cs" />
<Compile Include="Entity\NotifyBase.cs" />
<Compile Include="Entity\ParameterData.cs" />
+ <Compile Include="Entity\PermissionData.cs" />
<Compile Include="Entity\ProductData.cs" />
<Compile Include="Entity\SelectBase.cs" />
<Compile Include="Entity\TestItemData.cs" />
@@ -125,7 +129,6 @@
<Compile Include="Util\XmlHelper.cs" />
</ItemGroup>
<ItemGroup>
- <None Include="app.config" />
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
diff --git a/HMI.Core/Util/MSMQHelper.cs b/HMI.Core/Util/MSMQHelper.cs
index 3e331c6..41dcf48 100644
--- a/HMI.Core/Util/MSMQHelper.cs
+++ b/HMI.Core/Util/MSMQHelper.cs
@@ -87,7 +87,7 @@
{
MessageID = string.Empty;
MsgString = string.Empty;
- TimeSpan Time = new TimeSpan(TimeOut*10000);
+ TimeSpan Time = new TimeSpan(TimeOut);
Message MsgReceived = null;
try
{
diff --git a/HMI.Core/app.config b/HMI.Core/app.config
deleted file mode 100644
index d93dea3..0000000
--- a/HMI.Core/app.config
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<configuration>
- <runtime>
- <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
- <dependentAssembly>
- <assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>
- <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0"/>
- </dependentAssembly>
- <dependentAssembly>
- <assemblyIdentity name="System.ComponentModel.Annotations" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>
- <bindingRedirect oldVersion="0.0.0.0-4.2.1.0" newVersion="4.2.1.0"/>
- </dependentAssembly>
- <dependentAssembly>
- <assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral"/>
- <bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0"/>
- </dependentAssembly>
- </assemblyBinding>
- </runtime>
-<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2"/></startup></configuration>
diff --git a/HMI.DataViewer/DataViewer.xaml b/HMI.DataViewer/DataViewer.xaml
index f5ef14b..ae17303 100644
--- a/HMI.DataViewer/DataViewer.xaml
+++ b/HMI.DataViewer/DataViewer.xaml
@@ -16,7 +16,6 @@
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
- <ResourceDictionary Source="/HMI.UI;component/Style/PanuonDataGrid.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
diff --git a/HMI.IOMonitor/HMI.IOMonitor.csproj b/HMI.IOMonitor/HMI.IOMonitor.csproj
index cc932b2..9600002 100644
--- a/HMI.IOMonitor/HMI.IOMonitor.csproj
+++ b/HMI.IOMonitor/HMI.IOMonitor.csproj
@@ -131,7 +131,6 @@
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
- <None Include="app.config" />
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
diff --git a/HMI.IOMonitor/app.config b/HMI.IOMonitor/app.config
deleted file mode 100644
index a0cefc2..0000000
--- a/HMI.IOMonitor/app.config
+++ /dev/null
@@ -1,11 +0,0 @@
-锘�<?xml version="1.0" encoding="utf-8"?>
-<configuration>
- <runtime>
- <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
- <dependentAssembly>
- <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
- <bindingRedirect oldVersion="0.0.0.0-13.0.0.0" newVersion="13.0.0.0" />
- </dependentAssembly>
- </assemblyBinding>
- </runtime>
-</configuration>
\ No newline at end of file
diff --git a/HMI.LogViewer/LogViewer.xaml b/HMI.LogViewer/LogViewer.xaml
index 86632eb..52a68ba 100644
--- a/HMI.LogViewer/LogViewer.xaml
+++ b/HMI.LogViewer/LogViewer.xaml
@@ -2,21 +2,20 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:hb="clr-namespace:HMI.Base;assembly=HMI.Base"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:HMI.LogViewer"
+ mc:Ignorable="d"
+ xmlns:hb="clr-namespace:HMI.Base;assembly=HMI.Base"
xmlns:uic="clr-namespace:HMI.UI.Converter;assembly=HMI.UI"
xmlns:pw="https://opensource.panuon.com/wpf"
xmlns:pu="https://opensource.panuon.com/wpf-ui"
xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
- mc:Ignorable="d"
Loaded="UserControl_Loaded"
Background="{StaticResource WorkspaceBackground}"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
- <ResourceDictionary Source="/HMI.UI;component/Style/PanuonDataGrid.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
diff --git a/HMI.LogViewer/LogViewer.xaml.cs b/HMI.LogViewer/LogViewer.xaml.cs
index bc54659..da25941 100644
--- a/HMI.LogViewer/LogViewer.xaml.cs
+++ b/HMI.LogViewer/LogViewer.xaml.cs
@@ -1,7 +1,6 @@
锘縰sing HMI.Base;
using HMI.Core.Util;
using HMI.UI.Util;
-using log4net.Core;
using System;
using System.Collections.Generic;
using System.Data;
@@ -10,7 +9,6 @@
using System.Timers;
using System.Windows;
using System.Windows.Controls;
-using static System.Net.Mime.MediaTypeNames;
namespace HMI.LogViewer
{
diff --git a/HMI.MenuManage/MenuManage.xaml b/HMI.MenuManage/MenuManage.xaml
index 269e70e..e5a5b7b 100644
--- a/HMI.MenuManage/MenuManage.xaml
+++ b/HMI.MenuManage/MenuManage.xaml
@@ -16,11 +16,7 @@
Background="{StaticResource WorkspaceBackground}"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
- <ResourceDictionary>
- <ResourceDictionary.MergedDictionaries>
- <ResourceDictionary Source="/HMI.UI;component/Style/PanuonDataGrid.xaml"/>
- </ResourceDictionary.MergedDictionaries>
- </ResourceDictionary>
+
</UserControl.Resources>
<Grid>
<Grid.ColumnDefinitions>
diff --git a/HMI.MenuManage/MenuManage.xaml.cs b/HMI.MenuManage/MenuManage.xaml.cs
index fa38a3a..b812ce4 100644
--- a/HMI.MenuManage/MenuManage.xaml.cs
+++ b/HMI.MenuManage/MenuManage.xaml.cs
@@ -3,9 +3,13 @@
using HMI.MenuManage.Entity;
using HMI.MenuManage.Model;
using HMI.UI.Util;
+using log4net;
using System;
using System.Collections.Generic;
+using System.Collections.ObjectModel;
using System.ComponentModel;
+using System.Data;
+using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
@@ -18,14 +22,120 @@
public partial class MenuManage : PluginControl
{
#region 灞炴��
- private MenuManageModel Model;
+ public SqliteHelper sqliteHelper;
+
+ public int DataSourceCount { get => DataSource?.Count ?? 0; }
+
+ private ObservableCollection<MenuData> _DataSource;
+
+ public ObservableCollection<MenuData> DataSource
+ {
+ get => _DataSource;
+ set
+ {
+ Set(ref _DataSource, value);
+ Set(nameof(DataSourceCount));
+ }
+ }
+
+ private ObservableCollection<MenuData> _TreeDataSource;
+
+ public ObservableCollection<MenuData> TreeDataSource
+ {
+ get => _TreeDataSource;
+ set { Set(ref _TreeDataSource, value); }
+ }
#endregion
+
+ public static ILog PluginLog { get; private set; }
public MenuManage()
{
- Model = new MenuManageModel();
- this.DataContext = Model;
+ this.DataContext = this;
InitializeComponent();
+ if (!File.Exists(PathHelper.DatabasePath))
+ {
+ SqliteHelper.CreateDatabase(PathHelper.DatabasePath);
+ }
+ sqliteHelper = new SqliteHelper(PathHelper.DatabasePath);
+ sqliteHelper.ExecuteSql(@"CREATE TABLE IF NOT EXISTS menu (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ code TEXT NOT NULL,
+ name TEXT NOT NULL,
+ icon TEXT,
+ iconPath TEXT,
+ level TEXT,
+ type TEXT,
+ parentCode TEXT,
+ dllPath TEXT,
+ className TEXT,
+ sort REAL,
+ UNIQUE(code)
+ );");
+ }
+
+ public override void SetLogger(ILog logger)
+ {
+ base.SetLogger(logger);
+ PluginLog = logger;
+ }
+
+ public void LoadData()
+ {
+ ObservableCollection<MenuData> data = new ObservableCollection<MenuData>();
+ ObservableCollection<MenuData> treeData = new ObservableCollection<MenuData>();
+ DataTable dt = sqliteHelper.GetDataTable("SELECT m1.*,m2.name AS parentName FROM menu AS m1 LEFT JOIN menu AS m2 ON m1.parentCode = m2.code Order By m1.sort,m1.id;");
+ Dictionary<string, MenuData> cache = new Dictionary<string, MenuData>();
+ if (dt != null)
+ {
+ foreach (DataRow dr in dt.Rows)
+ {
+ var menu = new MenuData
+ {
+ Id = dr["id"].ToString(),
+ Code = dr["code"].ToString(),
+ Name = dr["name"].ToString(),
+ Icon = dr["icon"].ToString(),
+ Level = dr["level"].ToString(),
+ Type = dr["type"].ToString(),
+ ParentCode = dr["parentCode"].ToString(),
+ ParentName = dr["parentName"].ToString(),
+ DllPath = dr["dllPath"].ToString(),
+ ClassName = dr["className"].ToString(),
+ Sort = dr["sort"] == DBNull.Value ? 0 : double.Parse(dr["sort"].ToString()),
+ };
+ data.Add(menu);
+ if (menu.Level == "1")
+ {
+ treeData.Add(menu);
+ }
+ cache.Add(menu.Code, menu);
+ }
+
+ foreach (var menu in data)
+ {
+ if (!string.IsNullOrEmpty(menu.ParentCode) && menu.ParentCode != menu.Code)
+ {
+ cache[menu.ParentCode].Children.Add(menu);
+ }
+ }
+ }
+
+ TreeDataSource = treeData;
+ DataSource = data;
+ }
+
+ public void DeleteMenuById(string id)
+ {
+ string sql = $"DELETE FROM menu WHERE id = {id};";
+ sqliteHelper.ExecuteSql(sql);
+ }
+
+ public void DeleteMenuByIds(IEnumerable<string> ids)
+ {
+ List<string> sqls = ids.Select(id => $"DELETE FROM menu WHERE id = {id};")
+ .ToList();
+ sqliteHelper.ExecuteBatchSql(sqls);
}
private void Button_Click(object sender, RoutedEventArgs e)
@@ -38,13 +148,13 @@
MenuModal window = new MenuModal
{
Title = $"{LangUtil.Get("HMI.Menu.Add")}",
- sqliteHelper = Model.sqliteHelper,
+ sqliteHelper = sqliteHelper,
Owner = Window.GetWindow(this)
};
if (true == window.Open(new MenuData()))
{
MenuData data = window.Data;
- Model.LoadData();
+ LoadData();
}
}
catch (Exception ex)
@@ -57,7 +167,7 @@
{
try
{
- Model.LoadData();
+ LoadData();
}
catch (Exception ex)
{
@@ -69,7 +179,7 @@
{
try
{
- List<string> ids = Model.DataSource.Where(x => x.Selected).Select(x => x.Id).ToList();
+ List<string> ids = DataSource.Where(x => x.Selected).Select(x => x.Id).ToList();
if (ids == null || ids.Count <= 0)
{
ToastHelper.Warning(Window.GetWindow(this), LangUtil.Get("HMI.NoDeleteData"));
@@ -80,8 +190,8 @@
string.Format(LangUtil.Get("HMI.MakeSureDeletes"), ids.Count));
if (res == MessageBoxResult.OK)
{
- Model.DeleteMenuByIds(ids);
- Model.LoadData();
+ DeleteMenuByIds(ids);
+ LoadData();
}
}
catch (Exception ex)
@@ -98,13 +208,13 @@
MenuModal window = new MenuModal
{
Title = $"{LangUtil.Get("HMI.Menu.Edit")}",
- sqliteHelper = Model.sqliteHelper,
+ sqliteHelper = sqliteHelper,
Owner = Window.GetWindow(this)
};
if (true == window.Open(data))
{
var newData = window.Data;
- Model.LoadData();
+ LoadData();
}
}
catch (Exception ex)
@@ -122,8 +232,8 @@
string.Format(LangUtil.Get("HMI.MakeSureDeleteSingle"), data.Name));
if (res == MessageBoxResult.OK)
{
- Model.DeleteMenuById(data.Id);
- Model.LoadData();
+ DeleteMenuById(data.Id);
+ LoadData();
}
}
catch (Exception ex)
@@ -138,7 +248,7 @@
{
try
{
- Model?.sqliteHelper?.Close();
+ sqliteHelper?.Close();
}
catch (Exception ex)
{
@@ -148,7 +258,7 @@
private void DataGrid_Loaded(object sender, RoutedEventArgs e)
{
- Model.LoadData();
+ LoadData();
Loaded -= DataGrid_Loaded;
}
diff --git a/HMI.MenuManage/Modal/MenuModal.xaml b/HMI.MenuManage/Modal/MenuModal.xaml
index ce33c4e..a919f39 100644
--- a/HMI.MenuManage/Modal/MenuModal.xaml
+++ b/HMI.MenuManage/Modal/MenuModal.xaml
@@ -55,8 +55,9 @@
</pu:FormGroup>
<pu:FormGroup x:Name="FgType"
- Style="{StaticResource InputFormGroupStyle}" Header="{DynamicResource HMI.Menu.Type}" GroupName="MyFormGroup">
+ Style="{StaticResource InputFormGroupStyle}" Header="{DynamicResource HMI.Menu.Type}" GroupName="MyFormGroup">
<ComboBox x:Name="TbType" Style="{StaticResource FormComboxStyle}">
+ <ComboBoxItem>Permission</ComboBoxItem>
<ComboBoxItem>WPF</ComboBoxItem>
<ComboBoxItem>WinForm</ComboBoxItem>
<ComboBoxItem>LV</ComboBoxItem>
diff --git a/HMI.MenuManage/Modal/MenuModal.xaml.cs b/HMI.MenuManage/Modal/MenuModal.xaml.cs
index ad3953c..35d2ffb 100644
--- a/HMI.MenuManage/Modal/MenuModal.xaml.cs
+++ b/HMI.MenuManage/Modal/MenuModal.xaml.cs
@@ -64,7 +64,8 @@
}
catch (Exception ex)
{
- ToastHelper.Error(this, "Error锛�");
+ MenuManage.PluginLog.Error("Modal Commit Error.", ex);
+ ToastHelper.Error(this, ex.Message);
e.Cancel = true;
return;
}
diff --git a/HMI.MenuManage/Modal/RoleModal.xaml.cs b/HMI.MenuManage/Modal/RoleModal.xaml.cs
index 91699e9..0b8f823 100644
--- a/HMI.MenuManage/Modal/RoleModal.xaml.cs
+++ b/HMI.MenuManage/Modal/RoleModal.xaml.cs
@@ -1,5 +1,4 @@
-锘縰sing HMI.Core.Exceptions;
-using HMI.Core.Util;
+锘縰sing HMI.Core.Util;
using HMI.MenuManage.Entity;
using HMI.MenuManage.Util;
using HMI.UI.DpUtil;
diff --git a/HMI.MenuManage/Model/MenuManageModel.cs b/HMI.MenuManage/Model/MenuManageModel.cs
index 95b9212..1baebfd 100644
--- a/HMI.MenuManage/Model/MenuManageModel.cs
+++ b/HMI.MenuManage/Model/MenuManageModel.cs
@@ -12,110 +12,5 @@
{
public class MenuManageModel : NotifyBase
{
- public SqliteHelper sqliteHelper;
-
- private ObservableCollection<MenuData> _DataSource;
-
- public ObservableCollection<MenuData> DataSource
- {
- get => _DataSource;
- set
- {
- Set(ref _DataSource, value);
- Set(nameof(DataSourceCount));
- }
- }
-
- public int DataSourceCount { get => DataSource?.Count ?? 0; }
-
-
- private ObservableCollection<MenuData> _TreeDataSource;
-
- public ObservableCollection<MenuData> TreeDataSource
- {
- get => _TreeDataSource;
- set { Set(ref _TreeDataSource, value); }
- }
-
- public MenuManageModel()
- {
- if (!File.Exists(PathHelper.DatabasePath))
- {
- SqliteHelper.CreateDatabase(PathHelper.DatabasePath);
- }
- sqliteHelper = new SqliteHelper(PathHelper.DatabasePath);
- sqliteHelper.ExecuteSql(@"CREATE TABLE IF NOT EXISTS menu (
- id INTEGER PRIMARY KEY AUTOINCREMENT,
- code TEXT NOT NULL,
- name TEXT NOT NULL,
- icon TEXT,
- iconPath TEXT,
- level TEXT,
- type TEXT,
- parentCode TEXT,
- dllPath TEXT,
- className TEXT,
- sort REAL,
- UNIQUE(code)
- );");
- }
-
- public void LoadData()
- {
- ObservableCollection<MenuData> data = new ObservableCollection<MenuData>();
- ObservableCollection<MenuData> treeData = new ObservableCollection<MenuData>();
- DataTable dt = sqliteHelper.GetDataTable("SELECT m1.*,m2.name AS parentName FROM menu AS m1 LEFT JOIN menu AS m2 ON m1.parentCode = m2.code Order By m1.sort,m1.id;");
- Dictionary<string, MenuData> cache = new Dictionary<string, MenuData>();
- if (dt != null)
- {
- foreach (DataRow dr in dt.Rows)
- {
- var menu = new MenuData
- {
- Id = dr["id"].ToString(),
- Code = dr["code"].ToString(),
- Name = dr["name"].ToString(),
- Icon = dr["icon"].ToString(),
- Level = dr["level"].ToString(),
- Type = dr["type"].ToString(),
- ParentCode = dr["parentCode"].ToString(),
- ParentName = dr["parentName"].ToString(),
- DllPath = dr["dllPath"].ToString(),
- ClassName = dr["className"].ToString(),
- Sort = dr["sort"] == DBNull.Value ? 0 : double.Parse(dr["sort"].ToString()),
- };
- data.Add(menu);
- if (menu.Level == "1")
- {
- treeData.Add(menu);
- }
- cache.Add(menu.Code, menu);
- }
-
- foreach (var menu in data)
- {
- if (!string.IsNullOrEmpty(menu.ParentCode) && menu.ParentCode != menu.Code)
- {
- cache[menu.ParentCode].Children.Add(menu);
- }
- }
- }
-
- TreeDataSource = treeData;
- DataSource = data;
- }
-
- public void DeleteMenuById(string id)
- {
- string sql = $"DELETE FROM menu WHERE id = {id};";
- sqliteHelper.ExecuteSql(sql);
- }
-
- public void DeleteMenuByIds(IEnumerable<string> ids)
- {
- List<string> sqls = ids.Select(id => $"DELETE FROM menu WHERE id = {id};")
- .ToList();
- sqliteHelper.ExecuteBatchSql(sqls);
- }
}
}
diff --git a/HMI.MenuManage/RoleManage.xaml b/HMI.MenuManage/RoleManage.xaml
index 0f033c1..4b2acbd 100644
--- a/HMI.MenuManage/RoleManage.xaml
+++ b/HMI.MenuManage/RoleManage.xaml
@@ -14,11 +14,6 @@
Background="#f0f2f5"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
- <ResourceDictionary>
- <ResourceDictionary.MergedDictionaries>
- <ResourceDictionary Source="/HMI.UI;component/Style/PanuonDataGrid.xaml"/>
- </ResourceDictionary.MergedDictionaries>
- </ResourceDictionary>
</UserControl.Resources>
<Grid>
<Grid.ColumnDefinitions>
diff --git a/HMI.MenuManage/UserManage.xaml b/HMI.MenuManage/UserManage.xaml
index d964dd7..c9059ee 100644
--- a/HMI.MenuManage/UserManage.xaml
+++ b/HMI.MenuManage/UserManage.xaml
@@ -13,11 +13,6 @@
Padding="10"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
- <ResourceDictionary>
- <ResourceDictionary.MergedDictionaries>
- <ResourceDictionary Source="/HMI.UI;component/Style/PanuonDataGrid.xaml"/>
- </ResourceDictionary.MergedDictionaries>
- </ResourceDictionary>
</UserControl.Resources>
<Grid>
<Grid.ColumnDefinitions>
diff --git a/HMI.ParameterManage/ParameterManage.xaml b/HMI.ParameterManage/ParameterManage.xaml
index 838287d..61be0e0 100644
--- a/HMI.ParameterManage/ParameterManage.xaml
+++ b/HMI.ParameterManage/ParameterManage.xaml
@@ -16,11 +16,11 @@
Background="{StaticResource WorkspaceBackground}"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
- <ResourceDictionary>
+ <!--<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/HMI.UI;component/Style/PanuonDataGrid.xaml"/>
</ResourceDictionary.MergedDictionaries>
- </ResourceDictionary>
+ </ResourceDictionary>-->
</UserControl.Resources>
<Grid>
<Grid.ColumnDefinitions>
diff --git a/HMI.ParameterManage/ParameterSetting.xaml b/HMI.ParameterManage/ParameterSetting.xaml
index cc093dc..96eeac9 100644
--- a/HMI.ParameterManage/ParameterSetting.xaml
+++ b/HMI.ParameterManage/ParameterSetting.xaml
@@ -15,11 +15,11 @@
Background="{StaticResource WorkspaceBackground}"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
- <ResourceDictionary>
+ <!--<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/HMI.UI;component/Style/PanuonDataGrid.xaml"/>
</ResourceDictionary.MergedDictionaries>
- </ResourceDictionary>
+ </ResourceDictionary>-->
</UserControl.Resources>
<Border Style="{StaticResource CardBoarder}">
<Grid dp:GridHelper.Space="10" Cursor="">
diff --git a/HMI.ParameterManage/TestItem.xaml b/HMI.ParameterManage/TestItem.xaml
index a26e373..00b9d03 100644
--- a/HMI.ParameterManage/TestItem.xaml
+++ b/HMI.ParameterManage/TestItem.xaml
@@ -14,11 +14,11 @@
Loaded="PluginControl_Loaded"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
- <ResourceDictionary>
+ <!--<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/HMI.UI;component/Style/PanuonDataGrid.xaml"/>
</ResourceDictionary.MergedDictionaries>
- </ResourceDictionary>
+ </ResourceDictionary>-->
</UserControl.Resources>
<Border Style="{StaticResource CardBoarder}">
<Grid dp:GridHelper.Space="10">
diff --git a/HMI.SettingControl/SettingControl.xaml b/HMI.SettingControl/SettingControl.xaml
index facee9b..ccf7602 100644
--- a/HMI.SettingControl/SettingControl.xaml
+++ b/HMI.SettingControl/SettingControl.xaml
@@ -17,7 +17,6 @@
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<pu:StyleDictionary Includes="TabControl" />
- <ResourceDictionary Source="/HMI.UI;component/Style/PanuonResource.xaml"/>
<ResourceDictionary Source="/HMI.UI;component/Resources/Font/Font.xaml"/>
</ResourceDictionary.MergedDictionaries>
diff --git a/HMI.SettingControl/SystemConfig.xaml b/HMI.SettingControl/SystemConfig.xaml
index 4ad1199..9027c4d 100644
--- a/HMI.SettingControl/SystemConfig.xaml
+++ b/HMI.SettingControl/SystemConfig.xaml
@@ -15,7 +15,6 @@
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<pu:StyleDictionary Includes="TabControl" />
- <ResourceDictionary Source="/HMI.UI;component/Style/PanuonResource.xaml"/>
<ResourceDictionary Source="/HMI.UI;component/Resources/Font/Font.xaml"/>
</ResourceDictionary.MergedDictionaries>
diff --git a/HMI.UI/Controls/LightBall.cs b/HMI.UI/Controls/LightBall.cs
new file mode 100644
index 0000000..d9ffd5c
--- /dev/null
+++ b/HMI.UI/Controls/LightBall.cs
@@ -0,0 +1,43 @@
+锘縰sing System.Windows;
+using System.Windows.Controls;
+
+namespace HMI.UI
+{
+ public class LightBall : ContentControl
+ {
+ static LightBall()
+ {
+ DefaultStyleKeyProperty.OverrideMetadata(typeof(LightBall), new FrameworkPropertyMetadata(typeof(LightBall)));
+ }
+
+ public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(
+ "Value",
+ typeof(bool),
+ typeof(LightBall),
+ new FrameworkPropertyMetadata(false));
+
+ public static readonly DependencyProperty SizeProperty = DependencyProperty.Register(
+ "Size",
+ typeof(double),
+ typeof(LightBall),
+ new FrameworkPropertyMetadata(12d));
+
+ public double Size
+ {
+ get => (double)GetValue(SizeProperty);
+ set
+ {
+ SetValue(SizeProperty, value);
+ }
+ }
+
+ public bool Value
+ {
+ get => (bool)GetValue(ValueProperty);
+ set
+ {
+ SetValue(ValueProperty, value);
+ }
+ }
+ }
+}
diff --git a/HMI.UI/Controls/NumberInput.cs b/HMI.UI/Controls/NumberInput.cs
index d91c656..01d4234 100644
--- a/HMI.UI/Controls/NumberInput.cs
+++ b/HMI.UI/Controls/NumberInput.cs
@@ -37,7 +37,8 @@
{
// 鍏佽杈撳叆鏁板瓧銆佽礋鍙峰拰灏忔暟鐐�
Regex regex = new Regex(@"^-?\d*\.?\d*$");
- string newText = this.Text.Insert(this.CaretIndex, e.Text);
+ string segment = e.Text == "." ? ".0" : e.Text;
+ string newText = this.Text.Insert(this.CaretIndex, segment);
// 妫�鏌ユ槸鍚﹀凡缁忔湁璐熷彿锛屽鏋滄湁鍒欎笉鍏佽鍐嶈緭鍏ヨ礋鍙�
if (e.Text == "-" && this.Text.Contains("-"))
@@ -52,7 +53,10 @@
e.Handled = true;
return;
}
-
+ //else if (e.Text == ".") {
+ // e.Text = ".0";
+ //}
+ //regex = new Regex(@"^-?\d*\.?\d*$|^-?\.\d*$|^-?\d+\.$");
// 楠岃瘉瀹屾暣鐨勬柊鏂囨湰鏄惁绗﹀悎鏁板瓧鏍煎紡
if (!regex.IsMatch(newText))
{
diff --git a/HMI.UI/Controls/VisualHost.cs b/HMI.UI/Controls/VisualHost.cs
new file mode 100644
index 0000000..92adf88
--- /dev/null
+++ b/HMI.UI/Controls/VisualHost.cs
@@ -0,0 +1,30 @@
+锘縰sing System;
+using System.Windows;
+using System.Windows.Media;
+
+namespace HMI.UI.Controls
+{
+ public class VisualHost : FrameworkElement
+ {
+ Visual child;
+
+ public VisualHost(Visual child)
+ {
+ if (child == null)
+ throw new ArgumentException("child");
+
+ this.child = child;
+ AddVisualChild(child);
+ }
+
+ protected override Visual GetVisualChild(int index)
+ {
+ return (index == 0) ? child : null;
+ }
+
+ protected override int VisualChildrenCount
+ {
+ get { return 1; }
+ }
+ }
+}
diff --git a/HMI.UI/Converter/DataGridRowNumberConverter.cs b/HMI.UI/Converter/DataGridRowNumberConverter.cs
index a9fca5c..5ebb98c 100644
--- a/HMI.UI/Converter/DataGridRowNumberConverter.cs
+++ b/HMI.UI/Converter/DataGridRowNumberConverter.cs
@@ -22,6 +22,37 @@
}
}
+ public class ListViewRowNumberConverter : IValueConverter
+ {
+ public object Convert(object value, Type TargetType, object parameter, CultureInfo culture)
+ {
+ ListViewItem item = (ListViewItem)value;
+ ListView listView = ItemsControl.ItemsControlFromItemContainer(item) as ListView;
+ return listView.ItemContainerGenerator.IndexFromContainer(item) + 1;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ return value;
+ }
+ }
+
+ public class ListViewRowHeightConverter : IValueConverter
+ {
+ public object Convert(object value, Type TargetType, object parameter, CultureInfo culture)
+ {
+ double num = double.Parse(parameter.ToString());
+ double? res = value as double?;
+ if (res == null) return value;
+ return res - num;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ return value;
+ }
+ }
+
//public class ListBoxItemIndexConverter : IValueConverter
//{
// public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
diff --git a/HMI.UI/Converter/ReverseBoolConverter.cs b/HMI.UI/Converter/ReverseBoolConverter.cs
new file mode 100644
index 0000000..48966c4
--- /dev/null
+++ b/HMI.UI/Converter/ReverseBoolConverter.cs
@@ -0,0 +1,27 @@
+锘縰sing System;
+using System.Globalization;
+using System.Windows.Data;
+
+namespace HMI.UI.Converter
+{
+ public class ReverseBoolConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if (value is bool flag)
+ {
+ return !flag;
+ }
+ return value;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if (value is bool flag)
+ {
+ return !flag;
+ }
+ return value;
+ }
+ }
+}
diff --git a/Plugin.TestBuilder/UI/CanvasHelper.cs b/HMI.UI/DpUtil/CanvasHelper.cs
similarity index 69%
rename from Plugin.TestBuilder/UI/CanvasHelper.cs
rename to HMI.UI/DpUtil/CanvasHelper.cs
index 1778663..8973ac7 100644
--- a/Plugin.TestBuilder/UI/CanvasHelper.cs
+++ b/HMI.UI/DpUtil/CanvasHelper.cs
@@ -1,9 +1,21 @@
-锘縰sing System;
+锘縰sing HMI.UI.MDI;
+using System;
using System.Windows;
using System.Windows.Media;
-namespace Plugin.TestBuilder.UI
+namespace HMI.UI.DpUtil
{
+ public class CanvasPosition
+ {
+ public double Top { get; set; }
+ public double Left { get; set; }
+ public double Width { get; set; }
+ public double Height { get; set; }
+
+ public double LimitWidth { get; set; }
+ public double LimitHeight { get; set; }
+ }
+
public class CanvasHelper
{
public static void SetTopZIndex(InnerWindow element, DependencyObject parent, Type targetClass)
diff --git a/HMI.UI/DpUtil/FormGroupHelper.cs b/HMI.UI/DpUtil/FormGroupHelper.cs
index 01f6223..bdfd5bd 100644
--- a/HMI.UI/DpUtil/FormGroupHelper.cs
+++ b/HMI.UI/DpUtil/FormGroupHelper.cs
@@ -57,6 +57,11 @@
{
if (child is FormGroup fg)
{
+ if (fg.Visibility != Visibility.Visible)
+ {
+ ClearValue(fg);
+ continue;
+ }
fg.ValidateResult = ValidateResult.None;
fg.Message = null;
object content = fg.Content;
@@ -96,5 +101,24 @@
if (content is PasswordBox passwordInput) return passwordInput.Password;
return null;
}
+
+ private static void ClearValue(object content)
+ {
+ if (content == null) return;
+ if (content is UIElementCollection elementCollection && elementCollection.Count > 0)
+ ClearValue(elementCollection[0]);
+ if (content is TextBox tb) tb.Text = null;
+ if (content is CheckBox cb) cb.IsChecked = null;
+ if (content is ComboBox cBox)
+ {
+ cBox.SelectedItem = null;
+ cBox.SelectedValue = null;
+ cBox.Text = null;
+ }
+
+ if (content is Panel panel) ClearValue(panel.Children);
+ if (content is Panuon.WPF.UI.NumberInput numberInput) numberInput.Value = null;
+ if (content is PasswordBox passwordInput) passwordInput.Password = null;
+ }
}
}
diff --git a/HMI.UI/DpUtil/Resize.cs b/HMI.UI/DpUtil/Resize.cs
new file mode 100644
index 0000000..d21fd4d
--- /dev/null
+++ b/HMI.UI/DpUtil/Resize.cs
@@ -0,0 +1,640 @@
+锘縰sing HMI.UI.MDI;
+using System;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Controls.Primitives;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Shapes;
+
+namespace HMI.UI.DpUtil
+{
+ public class Resize
+ {
+ private static readonly double MinWidth = 60;
+ private static readonly double MinHeight = 60;
+
+ public static double GetReMaxWidth(DependencyObject obj)
+ {
+ return (double)obj.GetValue(ReMaxWithProperty);
+ }
+ public static void SetReMaxWidth(DependencyObject obj, double value)
+ {
+ obj.SetValue(ReMaxWithProperty, value);
+ }
+ public static readonly DependencyProperty ReMaxWithProperty =
+ DependencyProperty.RegisterAttached("ReMaxWith", typeof(double), typeof(Resize), new PropertyMetadata(0.0));
+
+
+ // 鎷栨嫿妯℃澘
+ public static ControlTemplate GetResizeTemplate(DependencyObject obj)
+ {
+ return (ControlTemplate)obj.GetValue(ResizeTemplateProperty);
+ }
+
+ public static void SetResizeTemplate(DependencyObject obj, ControlTemplate value)
+ {
+ obj.SetValue(ResizeTemplateProperty, value);
+ }
+
+ public static readonly DependencyProperty ResizeTemplateProperty =
+ DependencyProperty.RegisterAttached("ResizeTemplate", typeof(ControlTemplate), typeof(Resize), new PropertyMetadata(null, (d, e) =>
+ {
+ FrameworkElement element = d as FrameworkElement;
+ if (element == null) return;
+ Resizeable resize = GetResizeable(element);
+ if (resize == null) return;
+ resize.Detach();
+ resize.Attach();
+ }));
+
+ // 鏄惁鍙互鎷栨嫿鏀瑰彉澶у皬
+ public static bool GetCanMove(DependencyObject obj)
+ {
+ return (bool)obj.GetValue(CanMoveProperty);
+ }
+ public static void SetCanMove(DependencyObject obj, bool value)
+ {
+ obj.SetValue(CanMoveProperty, value);
+ }
+ public static readonly DependencyProperty CanMoveProperty =
+ DependencyProperty.RegisterAttached("CanMove", typeof(bool), typeof(Resize),
+ new PropertyMetadata(true));
+
+ // 鏄惁鍙互鎷栨嫿鏀瑰彉澶у皬
+ public static bool GetIsResizeable(DependencyObject obj)
+ {
+ return (bool)obj.GetValue(IsResizeableProperty);
+ }
+ public static void SetIsResizeable(DependencyObject obj, bool value)
+ {
+ obj.SetValue(IsResizeableProperty, value);
+ }
+
+ public static readonly DependencyProperty IsResizeableProperty =
+ DependencyProperty.RegisterAttached("IsResizeable", typeof(bool), typeof(Resize), new PropertyMetadata(true, (d, e) =>
+ {
+ FrameworkElement element = d as FrameworkElement;
+ if (element == null) return;
+ // 鍏堝彇娑堜箣鍓嶇殑鎷栨嫿瑁呴グ
+ Resizeable resize = GetResizeable(element);
+ if (resize != null) resize.Detach();
+ // 瀹炵幇閫昏緫
+ // 鍒ゆ柇灞炴�ц缃殑鏄笉鏄痶rue
+ if (!(bool)e.NewValue)
+ {
+ SetResizeable(element, null);
+ return;
+ }
+
+ if (!element.IsLoaded)
+ {
+ RoutedEventHandler Loaded_Resize = null;
+ Loaded_Resize = (sender, e1) =>
+ {
+ FrameworkElement senderElement = sender as FrameworkElement;
+ Resizeable r = new Resizeable(senderElement);
+ r.Attach();
+ SetResizeable(senderElement, r);
+ senderElement.Loaded -= Loaded_Resize;
+ };
+ element.Loaded += Loaded_Resize;
+ }
+ else
+ {
+ resize = new Resizeable(element);
+ resize.Attach();
+ SetResizeable(element, resize);
+ }
+ }));
+
+ public static Resizeable GetResizeable(DependencyObject obj)
+ {
+ return (Resizeable)obj.GetValue(ResizeableProperty);
+ }
+
+ public static void SetResizeable(DependencyObject obj, Resizeable value)
+ {
+ obj.SetValue(ResizeableProperty, value);
+ }
+
+ // Using a DependencyProperty as the backing store for Resizeable. This enables animation, styling, binding, etc...
+ static readonly DependencyProperty ResizeableProperty =
+ DependencyProperty.RegisterAttached("Resizeable", typeof(Resizeable), typeof(Resize), new PropertyMetadata(null));
+
+ static int i = 0;
+ static SolidColorBrush[] colors = new SolidColorBrush[] {
+ new SolidColorBrush(Colors.White),
+ new SolidColorBrush(Colors.Red),
+ new SolidColorBrush(Colors.Blue),
+ new SolidColorBrush(Colors.Green),
+ new SolidColorBrush(Colors.LightBlue),
+ new SolidColorBrush(Colors.Orange),
+ new SolidColorBrush(Colors.Yellow),
+ new SolidColorBrush(Colors.Black),
+ };
+
+ public class Resizeable
+ {
+ ResizeType _resizeType;
+ enum ResizeType
+ {
+ None,
+ Grid,
+ Canvas,
+ Window,
+ Others,
+ }
+ FrameworkElement _resizeTarget;
+
+ FrameworkElement _thumbsParent = null;
+ public Resizeable(FrameworkElement resizeTarget)
+ {
+ _resizeTarget = resizeTarget;
+ }
+
+ public void Attach()
+ {
+ FrameworkElement thumbsRoot = null;
+ ControlTemplate template = GetResizeTemplate(_resizeTarget);
+ // 鐪嬩笉鎳備簡锛屽ぇ姒傛槸鎷栨嫿妯℃澘
+ if (template != null)
+ {
+ Control control = new Control();
+ control.Template = template;
+ control.ApplyTemplate();
+ thumbsRoot = control;
+ _thumbsParent = VisualTreeHelper.GetChild(thumbsRoot, 0) as FrameworkElement;
+ }
+
+ if (thumbsRoot != null)
+ {
+ UIElement element = _resizeTarget is Window _windowTarget ? _windowTarget.Content as UIElement : _resizeTarget;
+ if (element != null)
+ {
+ if (element is InnerWindow _inner)
+ {
+ AdornerLayer layer = _inner.ResizeAdornerDecorator.AdornerLayer;
+ if (layer == null)
+ throw new Exception("鑾峰彇鎺т欢瑁呴グ灞傚け璐ワ紝鎺т欢鍙兘娌℃湁瑁呴グ灞傦紒");
+ layer.Add(new ResizeAdorner(layer, thumbsRoot));
+ }
+ else
+ {
+ AdornerLayer layer = AdornerLayer.GetAdornerLayer(element);
+ if (layer == null)
+ throw new Exception("鑾峰彇鎺т欢瑁呴グ灞傚け璐ワ紝鎺т欢鍙兘娌℃湁瑁呴グ灞傦紒");
+ layer.Add(new ResizeAdorner(element, thumbsRoot));
+ }
+ }
+ }
+
+ // 浣跨敤缂虹渷鏍峰紡
+ if (thumbsRoot == null)
+ {
+ Thumb leftThumb = null, topThumb = null, rightThumb = null, bottomThumb = null,
+ lefTopThumb = null, rightTopThumb = null, rightBottomThumb = null, leftbottomThumb = null;
+ int thumnSize = 5;
+ // 鍒濆鍖杢humb
+ leftThumb = new Thumb();
+ leftThumb.Template = new ControlTemplate(typeof(Thumb))
+ {
+ VisualTree = GetFactory(new SolidColorBrush(Colors.Transparent))
+ };
+ leftThumb.HorizontalAlignment = HorizontalAlignment.Left;
+ leftThumb.VerticalAlignment = VerticalAlignment.Stretch;
+ leftThumb.Cursor = Cursors.SizeWE;
+ leftThumb.Width = thumnSize;
+ leftThumb.Height = double.NaN;
+ leftThumb.Margin = new Thickness(0, thumnSize, 0, thumnSize);
+
+ topThumb = new Thumb();
+ topThumb.Template = new ControlTemplate(typeof(Thumb))
+ {
+ VisualTree = GetFactory(new SolidColorBrush(Colors.Transparent))
+ };
+ topThumb.HorizontalAlignment = HorizontalAlignment.Stretch;
+ topThumb.VerticalAlignment = VerticalAlignment.Top;
+ topThumb.Cursor = Cursors.SizeNS;
+ topThumb.Width = double.NaN;
+ topThumb.Height = thumnSize;
+ topThumb.Margin = new Thickness(thumnSize, 0, thumnSize, 0);
+
+ rightThumb = new Thumb();
+ rightThumb.Template = new ControlTemplate(typeof(Thumb))
+ {
+ VisualTree = GetFactory(new SolidColorBrush(Colors.Transparent))
+ };
+ rightThumb.HorizontalAlignment = HorizontalAlignment.Right;
+ rightThumb.VerticalAlignment = VerticalAlignment.Stretch;
+ rightThumb.Cursor = Cursors.SizeWE;
+ rightThumb.Width = thumnSize;
+ rightThumb.Height = double.NaN;
+ rightThumb.Margin = new Thickness(0, thumnSize, 0, thumnSize);
+
+ bottomThumb = new Thumb();
+ bottomThumb.Template = new ControlTemplate(typeof(Thumb))
+ {
+ VisualTree = GetFactory(new SolidColorBrush(Colors.Transparent))
+ };
+ bottomThumb.HorizontalAlignment = HorizontalAlignment.Stretch;
+ bottomThumb.VerticalAlignment = VerticalAlignment.Bottom;
+ bottomThumb.Cursor = Cursors.SizeNS;
+ bottomThumb.Width = double.NaN;
+ bottomThumb.Height = thumnSize;
+ bottomThumb.Margin = new Thickness(thumnSize, 0, thumnSize, 0);
+
+ lefTopThumb = new Thumb();
+ lefTopThumb.Template = new ControlTemplate(typeof(Thumb))
+ {
+ VisualTree = GetFactory(new SolidColorBrush(Colors.Transparent))
+ };
+ lefTopThumb.HorizontalAlignment = HorizontalAlignment.Left;
+ lefTopThumb.VerticalAlignment = VerticalAlignment.Top;
+ lefTopThumb.Cursor = Cursors.SizeNWSE;
+ lefTopThumb.Width = thumnSize;
+ lefTopThumb.Height = thumnSize;
+
+ rightTopThumb = new Thumb();
+ rightTopThumb.Template = new ControlTemplate(typeof(Thumb))
+ {
+ VisualTree = GetFactory(new SolidColorBrush(Colors.Transparent))
+ };
+ rightTopThumb.HorizontalAlignment = HorizontalAlignment.Right;
+ rightTopThumb.VerticalAlignment = VerticalAlignment.Top;
+ rightTopThumb.Cursor = Cursors.SizeNESW;
+ rightTopThumb.Width = thumnSize;
+ rightTopThumb.Height = thumnSize;
+
+ rightBottomThumb = new Thumb();
+ rightBottomThumb.Template = new ControlTemplate(typeof(Thumb))
+ {
+ VisualTree = GetFactory(new SolidColorBrush(Colors.Transparent))
+ };
+ rightBottomThumb.HorizontalAlignment = HorizontalAlignment.Right;
+ rightBottomThumb.VerticalAlignment = VerticalAlignment.Bottom;
+ rightBottomThumb.Cursor = Cursors.SizeNWSE;
+ rightBottomThumb.Width = thumnSize;
+ rightBottomThumb.Height = thumnSize;
+
+ leftbottomThumb = new Thumb();
+ leftbottomThumb.Template = new ControlTemplate(typeof(Thumb))
+ {
+ VisualTree = GetFactory(new SolidColorBrush(Colors.Transparent))
+ };
+ leftbottomThumb.HorizontalAlignment = HorizontalAlignment.Left;
+ leftbottomThumb.VerticalAlignment = VerticalAlignment.Bottom;
+ leftbottomThumb.Cursor = Cursors.SizeNESW;
+ leftbottomThumb.Width = thumnSize;
+ leftbottomThumb.Height = thumnSize;
+
+
+ Grid grid = new Grid();
+ grid.Children.Add(leftThumb);
+ grid.Children.Add(topThumb);
+ grid.Children.Add(rightThumb);
+ grid.Children.Add(bottomThumb);
+ grid.Children.Add(lefTopThumb);
+ grid.Children.Add(rightTopThumb);
+ grid.Children.Add(rightBottomThumb);
+ grid.Children.Add(leftbottomThumb);
+ UIElement element;
+ if (_resizeTarget is Window _resizeTargetWindow)
+ {
+ element = _resizeTargetWindow.Content as UIElement;
+ }
+ else
+ {
+ element = _resizeTarget;
+ }
+ if (element != null)
+ {
+ if (element is InnerWindow _inner)
+ {
+ AdornerLayer layer = _inner.ResizeAdornerDecorator?.AdornerLayer;
+ if (layer == null)
+ throw new Exception("鑾峰彇鎺т欢瑁呴グ灞傚け璐ワ紝鎺т欢鍙兘娌℃湁瑁呴グ灞傦紒");
+ layer.Add(new ResizeAdorner(layer, grid));
+ }
+ else
+ {
+ AdornerLayer layer = AdornerLayer.GetAdornerLayer(element);
+ if (layer == null)
+ throw new Exception("鑾峰彇鎺т欢瑁呴グ灞傚け璐ワ紝鎺т欢鍙兘娌℃湁瑁呴グ灞傦紒");
+ layer.Add(new ResizeAdorner(element, grid));
+ }
+ }
+ thumbsRoot = grid;
+ _thumbsParent = thumbsRoot;
+ }
+
+ //娉ㄥ唽浜嬩欢
+ for (int i = 0; i < VisualTreeHelper.GetChildrenCount(_thumbsParent); i++)
+ {
+ Thumb thumb = VisualTreeHelper.GetChild(_thumbsParent, i) as Thumb;
+ if (thumb != null)
+ {
+ thumb.DragStarted += Thumb_DragStarted;
+ thumb.DragDelta += Thumb_DragDelta;
+ }
+ }
+ }
+ public void Detach()
+ {
+ for (int i = 0; i < VisualTreeHelper.GetChildrenCount(_thumbsParent); i++)
+ {
+ Thumb thumb = VisualTreeHelper.GetChild(_thumbsParent, i) as Thumb;
+ if (thumb != null)
+ {
+ thumb.DragStarted -= Thumb_DragStarted;
+ thumb.DragDelta -= Thumb_DragDelta;
+ }
+ thumb.Cursor = Cursors.Arrow;
+ }
+ _thumbsParent = null;
+ }
+
+ private void Thumb_DragStarted(object sender, DragStartedEventArgs e)
+ {
+ _resizeType = GetResizeType();
+ if (_resizeType == ResizeType.Canvas && _resizeTarget is InnerWindow _inner)
+ {
+ Canvas parent = GetCanvas(_inner);
+ // 濡傛灉鏄釜InnerWindow锛屽氨鎶奍nnerWindowZIndex缃《
+ // TODO 鍙互鏀规垚鎺ュ彛鎴栬�匘ependencyPrope鏉ュ仛
+ CanvasHelper.SetTopZIndex(_inner, parent, _inner.GetType());
+ }
+ }
+
+ private void Thumb_DragDelta(object sender, DragDeltaEventArgs e)
+ {
+ switch (_resizeType)
+ {
+ case ResizeType.None:
+ break;
+ case ResizeType.Grid:
+ {
+ FrameworkElement element = _resizeTarget;
+ FrameworkElement thumb = sender as FrameworkElement;
+ double left, top, right, bottom, width, height;
+ if (thumb.HorizontalAlignment == HorizontalAlignment.Left)
+ {
+ right = element.Margin.Right;
+ left = element.Margin.Left + e.HorizontalChange;
+ width = (double.IsNaN(element.Width) ? element.ActualWidth : element.Width) - e.HorizontalChange;
+ }
+ else
+ {
+ left = element.Margin.Left;
+ right = element.Margin.Right - e.HorizontalChange;
+ width = (double.IsNaN(element.Width) ? element.ActualWidth : element.Width) + e.HorizontalChange;
+ }
+
+ if (thumb.VerticalAlignment == VerticalAlignment.Top)
+ {
+ bottom = element.Margin.Bottom;
+ top = element.Margin.Top + e.VerticalChange;
+ height = (double.IsNaN(element.Height) ? element.ActualHeight : element.Height) - e.VerticalChange;
+ }
+ else
+ {
+ top = element.Margin.Top;
+ bottom = element.Margin.Bottom - e.VerticalChange;
+ height = (double.IsNaN(element.Height) ? element.ActualHeight : element.Height) + e.VerticalChange;
+ }
+ if (thumb.HorizontalAlignment != HorizontalAlignment.Center && thumb.HorizontalAlignment != HorizontalAlignment.Stretch)
+ {
+ if (width >= 0)
+ {
+ element.Margin = new Thickness(left, element.Margin.Top, right, element.Margin.Bottom);
+ element.Width = width;
+ }
+ }
+ if (thumb.VerticalAlignment != VerticalAlignment.Center && thumb.VerticalAlignment != VerticalAlignment.Stretch)
+ {
+ if (height >= 0)
+ {
+ element.Margin = new Thickness(element.Margin.Left, top, element.Margin.Right, bottom);
+ element.Height = height;
+ }
+ }
+ }
+ break;
+ case ResizeType.Canvas:
+ {
+ FrameworkElement target = _resizeTarget;
+ Canvas parent = GetCanvas(target);
+ FrameworkElement thumb = sender as FrameworkElement;
+ if (parent == null)
+ {
+ // 涓�鑸笉浼氬嚭鐜拌繖绉嶆儏鍐碉紝淇濋櫓鍒ゆ柇涓�涓�
+ return;
+ }
+
+ double oldLeft = double.IsNaN(Canvas.GetLeft(target)) ? 0 : Canvas.GetLeft(target),
+ oldTop = double.IsNaN(Canvas.GetTop(target)) ? 0 : Canvas.GetTop(target),
+ oldWidth = double.IsNaN(target.ActualWidth) ? 0 : target.ActualWidth,
+ oldHeight = double.IsNaN(target.ActualHeight) ? 0 : target.ActualHeight;
+
+ double left, top, width, height;
+ double x = e.HorizontalChange, y = e.VerticalChange;
+ bool toLeft = x < 0, toTop = y < 0;
+ bool isLeft = thumb.HorizontalAlignment == HorizontalAlignment.Left,
+ isTop = thumb.VerticalAlignment == VerticalAlignment.Top;
+ if (isLeft)
+ {
+ // 宸︿晶鐨勬嫋鎷�
+ left = oldLeft + x;
+ width = oldWidth - x;
+ if (left < 0) { left = 0; width = oldWidth - (left - oldLeft); }
+ width = width < MinWidth ? MinWidth : width;
+ }
+ else
+ {
+ // 鍙充晶鐨勬嫋鎷�
+ left = oldLeft >= 0 ? oldLeft : 0;
+ width = oldWidth + x;
+ width = width < MinWidth ? MinWidth : width;
+ if (left + width > parent.ActualWidth) width = parent.ActualWidth - left;
+ }
+
+ if (isTop)
+ {
+ // 涓婅竟鐨勬嫋鎷�
+ top = oldTop + y;
+ height = oldHeight - y;
+ if (top < 0) { top = 0; height = oldHeight - (top - oldTop); }
+ height = height < MinHeight ? MinHeight : height;
+ }
+ else
+ {
+ // 涓嬭竟鐨勬嫋鎷�
+ top = oldTop > 0 ? oldTop : 0;
+ height = oldHeight + y;
+ height = height < MinHeight ? MinHeight : height;
+ if (top + height > parent.ActualHeight) height = parent.ActualHeight - top;
+ }
+
+ if (thumb.HorizontalAlignment != HorizontalAlignment.Center &&
+ thumb.HorizontalAlignment != HorizontalAlignment.Stretch)
+ {
+ // 姘村钩鏂瑰悜鏈�缁堝垽鏂�
+ Canvas.SetLeft(target, left);
+ target.Width = width;
+ //if ((isLeft && toLeft && left >= 0) ||
+ // (isLeft && !toLeft && width >= MinWidth) ||
+ // (!isLeft && toLeft && width >= MinWidth) ||
+ // (!isLeft && !toLeft && (left + width) <= parent.ActualWidth))
+ //{
+ // Canvas.SetLeft(target, left);
+ // target.Width = width;
+ //}
+ }
+
+ if (thumb.VerticalAlignment != VerticalAlignment.Center &&
+ thumb.VerticalAlignment != VerticalAlignment.Stretch)
+ {
+ // 鍨傜洿鏂瑰悜鏈�缁堝垽鏂�
+ Canvas.SetTop(target, top);
+ target.Height = height;
+ //if ((isTop && toTop && top >= 0) ||
+ // (isTop && !toTop && height >= MinHeight) ||
+ // (!isTop && toTop && height >= MinHeight) ||
+ // (!isTop && !toTop && (top + height) <= parent.ActualHeight))
+ //{
+ // Canvas.SetTop(target, top);
+ // target.Height = height;
+ //}
+ }
+ }
+ break;
+ case ResizeType.Window:
+ {
+ var c = _resizeTarget as Window;
+ var thumb = sender as FrameworkElement;
+ double left, top, width, height;
+ if (thumb.HorizontalAlignment == HorizontalAlignment.Left)
+ {
+ left = c.Left + e.HorizontalChange;
+ width = c.Width - e.HorizontalChange;
+ }
+ else
+ {
+ left = c.Left;
+ width = c.Width + e.HorizontalChange;
+ }
+
+ if (thumb.VerticalAlignment == VerticalAlignment.Top)
+ {
+
+ top = c.Top + e.VerticalChange;
+ height = c.Height - e.VerticalChange;
+ }
+ else
+ {
+ top = c.Top;
+ height = c.Height + e.VerticalChange;
+ }
+
+ if (thumb.HorizontalAlignment != HorizontalAlignment.Center && thumb.HorizontalAlignment != HorizontalAlignment.Stretch)
+ {
+ if (width > 63)
+ {
+ c.Width = width;
+ c.Left = left;
+ }
+ }
+ if (thumb.VerticalAlignment != VerticalAlignment.Center && thumb.VerticalAlignment != VerticalAlignment.Stretch)
+ {
+ if (height > 63)
+ {
+ c.Top = top;
+ c.Height = height;
+ }
+ }
+ }
+ break;
+ case ResizeType.Others:
+
+ break;
+ }
+ }
+ ResizeType GetResizeType()
+ {
+ ResizeType rt;
+ DependencyObject parent = VisualTreeHelper.GetParent(_resizeTarget);
+ if (parent is Grid)
+ {
+ rt = ResizeType.Grid;
+ }
+ else if (parent is Canvas)
+ {
+ rt = ResizeType.Canvas;
+ }
+ else if (_resizeTarget is Window)
+ {
+ rt = ResizeType.Window;
+ }
+ else
+ {
+ rt = ResizeType.Grid;
+ }
+ return rt;
+ }
+
+ // 鏂瑰舰宸ュ巶
+ FrameworkElementFactory GetFactory(Brush back)
+ {
+ FrameworkElementFactory fac = new FrameworkElementFactory(typeof(Rectangle));
+ fac.SetValue(Rectangle.FillProperty, back);
+ return fac;
+ }
+
+ // 瑁呴グ鍣�
+ public class ResizeAdorner : Adorner
+ {
+ // 甯冨眬瀹瑰櫒锛屽鏋滀笉浣跨敤甯冨眬瀹瑰櫒锛屽垯闇�瑕佺粰涓婅堪8涓帶浠跺竷灞�锛屽疄鐜板拰Grid甯冨眬瀹氫綅鏄竴鏍风殑锛屼細姣旇緝绻佺悙涓旀剰涔変笉澶с��
+ UIElement _child;
+ public ResizeAdorner(UIElement adornedElement, UIElement child) : base(adornedElement)
+ {
+ _child = child;
+ AddVisualChild(child);
+ }
+
+ protected override Visual GetVisualChild(int index)
+ {
+ return _child;
+ }
+ protected override int VisualChildrenCount { get; } = 1;
+ protected override Size ArrangeOverride(Size finalSize)
+ {
+ // 鐩存帴缁檊rid甯冨眬锛実rid鍐呴儴鐨則humb浼氳嚜鍔ㄥ竷灞�銆�
+ _child.Arrange(new Rect(new Point(0, 0), finalSize));
+ return finalSize;
+ }
+ public void ttt(int index)
+ {
+ for (int i = 0; i < VisualTreeHelper.GetChildrenCount(_child); i++)
+ {
+ DependencyObject child = VisualTreeHelper.GetChild(_child, i);
+ Canvas.SetZIndex(child as UIElement, index);
+
+ }
+
+ }
+
+ }
+ }
+
+ static Canvas GetCanvas(DependencyObject element)
+ {
+ DependencyObject e = element;
+ while (e != null && !(e is Canvas))
+ {
+ e = VisualTreeHelper.GetParent(e);
+ }
+ return e == null ? null : e as Canvas;
+ }
+ }
+}
diff --git a/HMI.UI/EditBox.cs b/HMI.UI/EditBox.cs
new file mode 100644
index 0000000..9d7b8bd
--- /dev/null
+++ b/HMI.UI/EditBox.cs
@@ -0,0 +1,194 @@
+锘縰sing System;
+using System.ComponentModel;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Input;
+using System.Windows.Media;
+
+namespace HMI.UI
+{
+ public class EditBox : Control
+ {
+ static EditBox()
+ {
+ DefaultStyleKeyProperty.OverrideMetadata(typeof(EditBox), new FrameworkPropertyMetadata(typeof(EditBox)));
+ }
+
+ public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(
+ "Value",
+ typeof(object),
+ typeof(EditBox),
+ new FrameworkPropertyMetadata());
+
+ public static readonly DependencyProperty CanEditProperty = DependencyProperty.Register(
+ "CanEdit",
+ typeof(bool),
+ typeof(EditBox),
+ new FrameworkPropertyMetadata(false, new PropertyChangedCallback(OnCanEditPropertyChanged)));
+
+ public static DependencyProperty IsEditingProperty = DependencyProperty.Register(
+ "IsEditing",
+ typeof(bool),
+ typeof(EditBox),
+ new FrameworkPropertyMetadata(false, new PropertyChangedCallback(OnIsEditingPropertyChanged)));
+
+ public static DependencyProperty PreEditingProperty = DependencyProperty.Register(
+ "PreEditing",
+ typeof(Func<bool?>),
+ typeof(EditBox),
+ new FrameworkPropertyMetadata());
+
+ public static DependencyProperty ShowEmptyProperty = DependencyProperty.Register(
+ "ShowEmpty",
+ typeof(bool),
+ typeof(EditBox),
+ new FrameworkPropertyMetadata(false));
+
+ private static void OnCanEditPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
+ {
+ if (obj is EditBox eb && e.Property == CanEditProperty)
+ {
+ bool value = (bool)e.NewValue;
+ if (value)
+ {
+ eb.MouseDoubleClick += eb.EditBox_MouseDoubleClick;
+ }
+ else
+ {
+ eb.MouseDoubleClick -= eb.EditBox_MouseDoubleClick;
+ }
+ }
+ }
+
+ private static void OnIsEditingPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
+ {
+ if (obj is EditBox eb && e.Property == IsEditingProperty)
+ {
+ bool value = (bool)e.NewValue;
+ eb.editing.Visibility = value ? Visibility.Visible : Visibility.Collapsed;
+ if (value)
+ {
+ eb.editing.Focus();
+ }
+ }
+ }
+
+ private TextBox editing;
+ public EditBox()
+ {
+ this.Loaded += EditBox_Loaded;
+ }
+
+ private void EditBox_Loaded(object sender, RoutedEventArgs e)
+ {
+ editing = this.Template.FindName("PART_TextBoxPart", this) as TextBox;
+ }
+
+ private void EditBox_MouseDoubleClick(object sender, MouseButtonEventArgs e)
+ {
+ if (IsEditing)
+ {
+ return;
+ }
+
+ Func<bool?> pre = GetValue(PreEditingProperty) as Func<bool?>;
+ if (pre != null && pre.Invoke() != true)
+ {
+ return;
+ }
+ var win = Window.GetWindow(this);
+
+ win.MouseDown += EditBox_LostFocus;
+ editing.LostFocus += EditBox_LostFocus;
+ IsEditing = true;
+ e.Handled = true;
+ }
+
+ public static bool GetElementUnderMouse(UIElement relativeTo, UIElement target)
+ {
+ Point mousePosition = Mouse.GetPosition(relativeTo);
+ bool res = false;
+ HitTestResultCallback resultCallback = (result) =>
+ {
+ // 鑾峰彇鐩镐氦鐨刄I鍏冪礌
+ var element = result.VisualHit as FrameworkElement;
+
+ if (element != null && element == target)
+ {
+ res = true;
+ return HitTestResultBehavior.Stop; // 鎵惧埌鍚庡仠姝㈤亶鍘�
+ }
+ return HitTestResultBehavior.Continue;
+ };
+
+ VisualTreeHelper.HitTest(relativeTo, null,
+ resultCallback, new PointHitTestParameters(mousePosition));
+ return res;
+ }
+
+ private void EditBox_LostFocus(object sender, RoutedEventArgs e)
+ {
+ if (sender == editing)
+ {
+ IsEditing = false;
+ editing.LostFocus -= EditBox_LostFocus;
+ Window.GetWindow(this).MouseDown -= EditBox_LostFocus;
+ }
+ else
+ {
+ var win = sender as Window;
+ if (!GetElementUnderMouse(win, this))
+ {
+ //editing.Focu
+ IsEditing = false;
+ win.MouseDown -= EditBox_LostFocus;
+ Window.GetWindow(this).MouseDown -= EditBox_LostFocus;
+ }
+ }
+ }
+
+ [Bindable(true)]
+ [Category("Appearance")]
+ public object Value
+ {
+ get { return GetValue(ValueProperty); }
+ set { SetValue(ValueProperty, value); }
+ }
+
+ public bool CanEdit
+ {
+ get => (bool)GetValue(CanEditProperty);
+ set
+ {
+ SetValue(CanEditProperty, value);
+ }
+ }
+
+ public bool IsEditing
+ {
+ get => (bool)GetValue(IsEditingProperty);
+ set
+ {
+ SetValue(IsEditingProperty, value);
+ }
+ }
+
+ public Func<bool?> PreEditing
+ {
+ get => (Func<bool?>)GetValue(PreEditingProperty);
+ set
+ {
+ SetValue(PreEditingProperty, value);
+ }
+ }
+
+ public bool ShowEmpty
+ {
+ get => (bool)GetValue(ShowEmptyProperty);
+ set
+ {
+ SetValue(ShowEmptyProperty, value);
+ }
+ }
+ }
+}
diff --git a/HMI.UI/HMI.UI.csproj b/HMI.UI/HMI.UI.csproj
index a36b6f6..8415c58 100644
--- a/HMI.UI/HMI.UI.csproj
+++ b/HMI.UI/HMI.UI.csproj
@@ -83,6 +83,7 @@
<Compile Include="Controls\KeyboradWindow.xaml.cs">
<DependentUpon>KeyboradWindow.xaml</DependentUpon>
</Compile>
+ <Compile Include="Controls\LightBall.cs" />
<Compile Include="Controls\MultiCombox.xaml.cs">
<DependentUpon>MultiCombox.xaml</DependentUpon>
</Compile>
@@ -96,22 +97,45 @@
<Compile Include="Controls\treegrid\Controls\TreeListView.cs" />
<Compile Include="Controls\treegrid\TreeItemConverter.cs" />
<Compile Include="Controls\treegrid\TreeNodeExtend.cs" />
+ <Compile Include="Controls\VisualHost.cs" />
+ <Compile Include="Converter\ReverseBoolConverter.cs" />
<Compile Include="Converter\IndentConverter.cs" />
<Compile Include="Converter\VisibilityBoolConverter.cs" />
<Compile Include="Converter\DataGridRowFlagConverter.cs" />
<Compile Include="Converter\DataGridRowNumberConverter.cs" />
<Compile Include="Converter\PathImageConverter.cs" />
<Compile Include="Controls\NumberInput.cs" />
+ <Compile Include="DpUtil\CanvasHelper.cs" />
<Compile Include="DpUtil\DataGridHelper.cs" />
<Compile Include="DpUtil\DataGridTextColumnHelper.cs" />
<Compile Include="DpUtil\FormGroupHelper.cs" />
<Compile Include="DpUtil\GridHelper.cs" />
+ <Compile Include="DpUtil\Resize.cs" />
<Compile Include="DpUtil\StackPanelHelper.cs" />
<Compile Include="DpUtil\TreeViewHelper.cs" />
<Compile Include="DpUtil\UniformGridHelper.cs" />
+ <Compile Include="EditBox.cs" />
<Compile Include="Entity\ScannerConfig.cs" />
+ <Compile Include="MaskControl.xaml.cs">
+ <DependentUpon>MaskControl.xaml</DependentUpon>
+ </Compile>
<Compile Include="MaskWindow.xaml.cs">
<DependentUpon>MaskWindow.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="MDI\BottomBar.xaml.cs">
+ <DependentUpon>BottomBar.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="MDI\InnerWindow.xaml.cs">
+ <DependentUpon>InnerWindow.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="MDI\MinInnerWindow.xaml.cs">
+ <DependentUpon>MinInnerWindow.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="MDI\Workspace.xaml.cs">
+ <DependentUpon>Workspace.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="RequirePasswordWindow.xaml.cs">
+ <DependentUpon>RequirePasswordWindow.xaml</DependentUpon>
</Compile>
<Compile Include="ScannerSetting.xaml.cs">
<DependentUpon>ScannerSetting.xaml</DependentUpon>
@@ -120,11 +144,28 @@
<DependentUpon>BaseWindow.xaml</DependentUpon>
</Compile>
<Compile Include="DpUtil\DpPlugin.cs" />
+ <Compile Include="TableComboBox.cs" />
<Compile Include="Util\IValueValidator.cs" />
<Compile Include="Util\MaskHolder.cs" />
<Compile Include="Util\MsgBoxHelper.cs" />
<Compile Include="Util\MsgBoxHelper2.cs" />
<Compile Include="Util\ToastHelper.cs" />
+ <Page Include="RequirePasswordWindow.xaml">
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ </Page>
+ <Page Include="Style\PanuonListView.xaml">
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ </Page>
+ <Page Include="Style\ScrollBarResource.xaml">
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ </Page>
+ <Page Include="Themes\Generic.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
<Resource Include="Resources\Font\Font.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
@@ -153,7 +194,27 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
+ <Page Include="MaskControl.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
<Page Include="MaskWindow.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
+ <Page Include="MDI\BottomBar.xaml">
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ </Page>
+ <Page Include="MDI\InnerWindow.xaml">
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ </Page>
+ <Page Include="MDI\MinInnerWindow.xaml">
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ </Page>
+ <Page Include="MDI\Workspace.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
@@ -172,7 +233,6 @@
<Page Include="Style\PanuonResource.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
- <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Page>
<Page Include="Style\BaseWindow.xaml">
<SubType>Designer</SubType>
@@ -181,17 +241,14 @@
<Page Include="Style\Colors.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
- <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Page>
<Page Include="Style\FormStyle.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
- <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Page>
<Page Include="Style\WindowResources.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
- <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Page>
</ItemGroup>
<ItemGroup>
@@ -233,6 +290,14 @@
<Name>HMI.Util</Name>
</ProjectReference>
</ItemGroup>
- <ItemGroup />
+ <ItemGroup>
+ <Resource Include="Resources\Icon\dot.svg" />
+ </ItemGroup>
+ <ItemGroup>
+ <Resource Include="Resources\Icon\dot.png" />
+ </ItemGroup>
+ <ItemGroup>
+ <Resource Include="Resources\Icon\dot2.png" />
+ </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
\ No newline at end of file
diff --git a/HMI.UI/MDI/BottomBar.xaml b/HMI.UI/MDI/BottomBar.xaml
new file mode 100644
index 0000000..5928ee7
--- /dev/null
+++ b/HMI.UI/MDI/BottomBar.xaml
@@ -0,0 +1,15 @@
+锘�<UserControl x:Class="HMI.UI.MDI.BottomBar"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:local="clr-namespace:HMI.UI.MDI"
+ mc:Ignorable="d"
+ d:DesignHeight="30" d:DesignWidth="800">
+ <ScrollViewer HorizontalScrollBarVisibility="Auto" Background="Transparent" VerticalScrollBarVisibility="Hidden">
+ <StackPanel x:Name="stackPanel" Orientation="Horizontal" HorizontalAlignment="Stretch">
+
+ </StackPanel>
+ </ScrollViewer>
+
+</UserControl>
diff --git a/HMI.UI/MDI/BottomBar.xaml.cs b/HMI.UI/MDI/BottomBar.xaml.cs
new file mode 100644
index 0000000..2808597
--- /dev/null
+++ b/HMI.UI/MDI/BottomBar.xaml.cs
@@ -0,0 +1,29 @@
+锘縰sing System.Windows;
+using System.Windows.Controls;
+
+namespace HMI.UI.MDI
+{
+ /// <summary>
+ /// BottomBar.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ public partial class BottomBar : UserControl
+ {
+ public BottomBar()
+ {
+ Visibility = Visibility.Collapsed;
+ InitializeComponent();
+ }
+
+ public void AddMinWindow(MinInnerWindow min)
+ {
+ stackPanel.Children.Add(min);
+ Visibility = Visibility.Visible;
+ }
+
+ public void RemoveMinWindow(MinInnerWindow min)
+ {
+ stackPanel.Children.Remove(min);
+ Visibility = stackPanel.Children.Count > 0 ? Visibility.Visible : Visibility.Collapsed;
+ }
+ }
+}
diff --git a/HMI.UI/MDI/InnerWindow.xaml b/HMI.UI/MDI/InnerWindow.xaml
new file mode 100644
index 0000000..856e1e7
--- /dev/null
+++ b/HMI.UI/MDI/InnerWindow.xaml
@@ -0,0 +1,67 @@
+锘�<UserControl x:Class="HMI.UI.MDI.InnerWindow"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:local="clr-namespace:HMI.UI.MDI"
+ mc:Ignorable="d"
+ HorizontalAlignment="Stretch"
+ HorizontalContentAlignment="Stretch"
+ MouseLeftButtonDown="Grid_MouseLeftButtonDown"
+ SizeChanged="UserControl_SizeChanged"
+ Background="#FFF"
+ Focusable="True">
+ <UserControl.Resources>
+ <ResourceDictionary>
+ <ResourceDictionary.MergedDictionaries>
+ <ResourceDictionary Source="/HMI.UI;component/Style/colors.xaml"/>
+ <ResourceDictionary Source="/HMI.UI;component/Style/WindowResources.xaml"/>
+ </ResourceDictionary.MergedDictionaries>
+
+ <Style x:Key="SliderThumbStyle" TargetType="{x:Type Thumb}">
+ <Setter Property="Template">
+ <Setter.Value>
+ <ControlTemplate>
+ <Label VerticalContentAlignment="Center"
+ Foreground="{Binding HeaderFontColor}" Content="{Binding Title}"/>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style>
+ </ResourceDictionary>
+ </UserControl.Resources>
+
+ <UserControl.Template>
+ <ControlTemplate TargetType="local:InnerWindow">
+ <AdornerDecorator x:Name="PART_Adorner" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" >
+ <Grid GotFocus="Grid_GotFocus">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="30"/>
+ <RowDefinition Height="*"/>
+ </Grid.RowDefinitions>
+
+ <Grid Background="{StaticResource ReVerBar}">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="*"/>
+ <ColumnDefinition Width="Auto"/>
+ </Grid.ColumnDefinitions>
+
+ <Thumb Style="{StaticResource SliderThumbStyle}" Grid.Column="0" x:Name="thumb1" DragDelta="DragDelta"
+ DragStarted="DragStarted" DragCompleted="DragCompleted"/>
+
+ <StackPanel Grid.Column="1" Orientation="Horizontal">
+ <Button Style="{StaticResource ChildWindowButton}" Background="Transparent" Click="Lock_Click"></Button>
+ <Button Style="{StaticResource ChildWindowButton}" Background="Transparent" Click="Min_Click"></Button>
+ <Button Style="{StaticResource ChildWindowButton}" Background="Transparent" Click="Max_Click" ></Button>
+ <!--<Button Style="{StaticResource ChildWindowCloseButton}" Background="Transparent" Click="CLose_Click"></Button>-->
+ </StackPanel>
+ </Grid>
+
+ <Border Grid.Row="1" Background="LightGray" VerticalAlignment="Stretch" BorderThickness="2,0,2,2" BorderBrush="{Binding HeaderBackground}">
+ <ContentPresenter HorizontalAlignment="Stretch" VerticalAlignment="Stretch"></ContentPresenter>
+ </Border>
+ </Grid>
+ </AdornerDecorator>
+ </ControlTemplate>
+ </UserControl.Template>
+</UserControl>
\ No newline at end of file
diff --git a/HMI.UI/MDI/InnerWindow.xaml.cs b/HMI.UI/MDI/InnerWindow.xaml.cs
new file mode 100644
index 0000000..ad0a0f4
--- /dev/null
+++ b/HMI.UI/MDI/InnerWindow.xaml.cs
@@ -0,0 +1,267 @@
+锘縰sing HMI.UI.DpUtil;
+using System;
+using System.ComponentModel;
+using System.Runtime.CompilerServices;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+
+namespace HMI.UI.MDI
+{
+ /// <summary>
+ /// InnerWindow.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ public partial class InnerWindow : UserControl, INotifyPropertyChanged
+ {
+ #region INotifyPropertyChanged
+ public virtual event PropertyChangedEventHandler PropertyChanged;
+
+ protected virtual void RaisePropertyChanged(string name)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
+ }
+
+ protected void RaiseAndSetIfChanged<T>(ref T old, T @new, [CallerMemberName] string propertyName = null)
+ {
+ old = @new;
+ if (propertyName != null)
+ {
+ RaisePropertyChanged(propertyName);
+ }
+ }
+ #endregion
+
+ #region 灞炴��
+
+ #region Common
+ public DragType DragType { get; set; } = DragType.Canvas;
+ public CanvasPosition canvasPosition;
+ private Canvas canvas;
+ public WindowState WindowState { get; set; } = WindowState.Normal;
+ public AdornerDecorator ResizeAdornerDecorator
+ {
+ get
+ {
+ return this.Template.FindName("PART_Adorner", this) as AdornerDecorator;
+ }
+ }
+
+ private string _Title;
+ public string Title
+ {
+ get { return _Title; }
+ set => RaiseAndSetIfChanged(ref _Title, value);
+ }
+
+ public int Zindex
+ {
+ get
+ {
+ return Canvas.GetZIndex(this);
+ }
+ set
+ {
+ Canvas.SetZIndex(this, value);
+ }
+ }
+ #endregion
+
+ #region 浜嬩欢
+ public event EventHandler MinEvent;
+ public event EventHandler MaxEvent;
+ public event EventHandler LockEvent;
+ public event EventHandler CloseEvent;
+ public event EventHandler ZIndexEvent;
+ #endregion
+
+ #region DependencyProperty
+ public Brush HeaderBackground
+ {
+ get { return (Brush)GetValue(HeaderBackgroundProperty); }
+ set { SetValue(HeaderBackgroundProperty, value); }
+ }
+
+ public static readonly DependencyProperty HeaderBackgroundProperty =
+ DependencyProperty.Register("HeaderBackground", typeof(Brush), typeof(InnerWindow),
+ new PropertyMetadata(new SolidColorBrush(Color.FromRgb(54, 146, 225))));
+
+ public Brush HeaderFontColor
+ {
+ get { return (Brush)GetValue(HeaderFontColorProperty); }
+ set { SetValue(HeaderFontColorProperty, value); }
+ }
+
+ public static readonly DependencyProperty HeaderFontColorProperty =
+ DependencyProperty.Register("HeaderFontColor", typeof(Brush), typeof(InnerWindow),
+ new PropertyMetadata(new SolidColorBrush(Color.FromRgb(255, 255, 225))));
+ #endregion
+
+ #endregion
+
+ public InnerWindow()
+ {
+ DataContext = this;
+ InitializeComponent();
+ Loaded += InnerWindow_Loaded;
+ }
+
+ public static readonly DependencyProperty CanResizeProperty = DependencyProperty.Register(
+ "CanResize",
+ typeof(bool),
+ typeof(InnerWindow),
+ new FrameworkPropertyMetadata(true, new PropertyChangedCallback(OnCanResizeChanged)));
+
+ private static void OnCanResizeChanged(DependencyObject dp, DependencyPropertyChangedEventArgs e)
+ {
+ bool val = (bool)e.NewValue;
+ Resize.SetIsResizeable(dp, val);
+ Resize.SetCanMove(dp, val);
+ }
+
+ public bool CanResize
+ {
+ get => (bool)GetValue(CanResizeProperty);
+ set => SetValue(CanResizeProperty, value);
+ }
+
+ private void InnerWindow_Loaded(object sender, RoutedEventArgs e)
+ {
+ Loaded -= InnerWindow_Loaded;
+ }
+
+ #region 鎷栨嫿绉诲姩鐩稿叧
+ private void DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
+ {
+ if (!Resize.GetCanMove(this)) return;
+ switch (DragType)
+ {
+ case DragType.Canvas:
+ {
+ double offsetX = e.HorizontalChange;
+ double offsetY = e.VerticalChange;
+
+ Width = ActualWidth > canvas.ActualWidth ? canvas.ActualWidth : Width;
+ Height = ActualHeight > canvas.ActualHeight ? canvas.ActualHeight : Height;
+
+ double newLeft = Canvas.GetLeft(this) + e.HorizontalChange;
+ newLeft = newLeft < 0 ? 0 : newLeft;
+
+
+ double newTop = Canvas.GetTop(this) + e.VerticalChange;
+ newTop = newTop < 0 ? 0 : newTop;
+
+ double fixLeft = canvasPosition == null || canvasPosition.LimitWidth <= 0 ? ActualWidth : canvasPosition.LimitWidth;
+ double fixTop = canvasPosition == null || canvasPosition.LimitHeight <= 0 ? ActualHeight : canvasPosition.LimitHeight;
+
+ if (canvas != null)
+ {
+ newLeft = offsetX > 0 && newLeft > canvas.ActualWidth - fixLeft ? canvas.ActualWidth - fixLeft : newLeft;
+ newTop = offsetY > 0 && newTop > canvas.ActualHeight - fixTop ? canvas.ActualHeight - fixTop : newTop;
+ }
+
+ Canvas.SetLeft(this, newLeft);
+ Canvas.SetTop(this, newTop);
+ break;
+ }
+ }
+ }
+
+ private void DragStarted(object sender, System.Windows.Controls.Primitives.DragStartedEventArgs e)
+ {
+ ZIndexEvent?.Invoke(this, null);
+ // thumb1.Background = Brushes.White;
+ }
+
+ private void DragCompleted(object sender, System.Windows.Controls.Primitives.DragCompletedEventArgs e)
+ {
+ canvasPosition.Top = Canvas.GetTop(this);
+ canvasPosition.Left = Canvas.GetLeft(this);
+ }
+ #endregion
+
+ /// <summary>
+ /// 娣诲姞鍒扮敾甯冧笂
+ /// </summary>
+ /// <param name="canvas"></param>
+ public void AttachToCanvas(Canvas canvas)
+ {
+ canvas.Children.Add(this);
+ this.canvas = canvas;
+ if (ActualWidth < MinWidth)
+ {
+ Width = MinWidth;
+ }
+ if (ActualHeight < MinHeight)
+ {
+ Height = MinHeight;
+ }
+ Canvas.SetLeft(this, canvasPosition == null ? 0 : canvasPosition.Left);
+ Canvas.SetTop(this, canvasPosition == null ? 0 : canvasPosition.Top);
+ canvas.SizeChanged += Canvas_SizeChanged;
+ }
+
+ private void Canvas_SizeChanged(object sender, SizeChangedEventArgs e)
+ {
+ Size newSize = e.NewSize;
+ Size previousSize = e.PreviousSize;
+
+ double xRate = newSize.Width / previousSize.Width;
+ double yRate = newSize.Height / previousSize.Height;
+
+ Canvas.SetLeft(this, Canvas.GetLeft(this) * xRate);
+ Canvas.SetTop(this, Canvas.GetTop(this) * yRate);
+ this.Width = this.Width * xRate;
+ this.Height = this.Height * yRate;
+ }
+
+ private void Lock_Click(object sender, RoutedEventArgs e)
+ {
+ LockEvent?.Invoke(this, null);
+ }
+
+ private void Min_Click(object sender, RoutedEventArgs e)
+ {
+ MinEvent?.Invoke(this, null);
+ }
+
+ private void Max_Click(object sender, RoutedEventArgs e)
+ {
+ MaxEvent?.Invoke(this, null);
+ }
+
+ private void CLose_Click(object sender, RoutedEventArgs e)
+ {
+
+ }
+
+ private void Grid_GotFocus(object sender, RoutedEventArgs e)
+ {
+
+ }
+
+ private void Grid_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
+ {
+ this.Focus();
+ }
+
+ private void UserControl_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
+ {
+
+ }
+
+ private void UserControl_SizeChanged(object sender, SizeChangedEventArgs e)
+ {
+
+ }
+ }
+
+ public enum DragType
+ {
+ Canvas = 0,
+ Dock = 1
+ }
+
+}
+
diff --git a/HMI.UI/MDI/MinInnerWindow.xaml b/HMI.UI/MDI/MinInnerWindow.xaml
new file mode 100644
index 0000000..c0804f0
--- /dev/null
+++ b/HMI.UI/MDI/MinInnerWindow.xaml
@@ -0,0 +1,24 @@
+锘�<UserControl x:Class="HMI.UI.MDI.MinInnerWindow"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:local="clr-namespace:HMI.UI.MDI"
+ mc:Ignorable="d"
+ Height="30"
+ d:DesignHeight="450" d:DesignWidth="800">
+ <UserControl.Resources>
+ <ResourceDictionary>
+ <ResourceDictionary.MergedDictionaries>
+ <ResourceDictionary Source="/HMI.UI;component/Style/colors.xaml"/>
+ <ResourceDictionary Source="/HMI.UI;component/Style/WindowResources.xaml"/>
+ </ResourceDictionary.MergedDictionaries>
+ </ResourceDictionary>
+ </UserControl.Resources>
+
+ <StackPanel Background="{StaticResource VerBar}" Orientation="Horizontal">
+ <Label BorderBrush="{StaticResource PrimaryColor}" Foreground="#FFF" BorderThickness="2,0,0,0" VerticalContentAlignment="Center" ToolTip="{Binding Title}" Content="{Binding Title}"/>
+ <Button Style="{StaticResource ChildWindowButton}" Background="Transparent" Click="Max_Click" ></Button>
+ <!--<Button Style="{StaticResource ChildWindowCloseButton}" Click="CLose_Click"></Button>-->
+ </StackPanel>
+</UserControl>
diff --git a/HMI.UI/MDI/MinInnerWindow.xaml.cs b/HMI.UI/MDI/MinInnerWindow.xaml.cs
new file mode 100644
index 0000000..91a94c8
--- /dev/null
+++ b/HMI.UI/MDI/MinInnerWindow.xaml.cs
@@ -0,0 +1,42 @@
+锘縰sing System;
+using System.Windows.Controls;
+
+namespace HMI.UI.MDI
+{
+ /// <summary>
+ /// MinInnerWindow.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ public partial class MinInnerWindow : UserControl
+ {
+ public event EventHandler MaxEvent;
+ public event EventHandler CloseEvent;
+ public InnerWindow Inner { get; set; }
+
+ public string Title
+ {
+ get => Inner == null ? null : Inner.Title;
+ }
+
+ public MinInnerWindow() : this(null)
+ {
+
+ }
+
+ public MinInnerWindow(InnerWindow inner)
+ {
+ DataContext = this;
+ Inner = inner;
+ InitializeComponent();
+ }
+
+ private void Max_Click(object sender, System.Windows.RoutedEventArgs e)
+ {
+ MaxEvent?.Invoke(this, null);
+ }
+
+ private void CLose_Click(object sender, System.Windows.RoutedEventArgs e)
+ {
+ CloseEvent?.Invoke(this, null);
+ }
+ }
+}
diff --git a/HMI.UI/MDI/Workspace.xaml b/HMI.UI/MDI/Workspace.xaml
new file mode 100644
index 0000000..d926fbe
--- /dev/null
+++ b/HMI.UI/MDI/Workspace.xaml
@@ -0,0 +1,34 @@
+锘�<UserControl x:Class="HMI.UI.MDI.Workspace"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:local="clr-namespace:HMI.UI.MDI"
+ mc:Ignorable="d"
+ x:Name="workspace"
+ xmlns:hcu="clr-namespace:HMI.Core.Util;assembly=HMI.Core"
+ d:DesignHeight="450" d:DesignWidth="800">
+ <UserControl.Resources>
+ <hcu:BindingProxy x:Key="BindingProxy" Data="{Binding ElementName=workspace}"/>
+ </UserControl.Resources>
+ <Grid>
+ <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
+ <Canvas x:Name="WorkArea" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" >
+ <Canvas.ContextMenu>
+ <ContextMenu DataContext="{Binding Data,Source={StaticResource BindingProxy}}">
+ <MenuItem Header="淇濆瓨甯冨眬" Click="MenuItem_Click"></MenuItem>
+ <MenuItem Header="閿佸畾甯冨眬"
+ IsCheckable="True"
+ IsChecked="{Binding IsLocked,Mode=OneWay}"
+ Click="MenuItem_Checked"></MenuItem>
+ </ContextMenu>
+ </Canvas.ContextMenu>
+ <Image Canvas.Left="0" Canvas.Top="0" Canvas.Right="0" Canvas.Bottom="0"
+Stretch="None" Panel.ZIndex="-999" Source="/HMI.UI;component/Resources/Icon/dot2.png">
+
+ </Image>
+ <local:BottomBar x:Name="BottomBar" Canvas.Bottom="0" Panel.ZIndex="9999999"/>
+ </Canvas>
+ </ScrollViewer>
+ </Grid>
+</UserControl>
diff --git a/HMI.UI/MDI/Workspace.xaml.cs b/HMI.UI/MDI/Workspace.xaml.cs
new file mode 100644
index 0000000..01ae0a9
--- /dev/null
+++ b/HMI.UI/MDI/Workspace.xaml.cs
@@ -0,0 +1,366 @@
+锘縰sing HMI.Core.Util;
+using HMI.UI.Converter;
+using HMI.UI.DpUtil;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+
+namespace HMI.UI.MDI
+{
+ public class WorkspaceSetting
+ {
+ public bool IsLocked { get; set; }
+ public List<Position> positions { get; set; } = new List<Position>();
+ }
+ public class Position
+ {
+ public string Key { get; set; }
+ public double Left { get; set; }
+ public double Top { get; set; }
+ public double Width { get; set; }
+ public double Height { get; set; }
+ }
+ /// <summary>
+ /// Workspace.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ public partial class Workspace : UserControl
+ {
+
+ public Workspace()
+ {
+ InitializeComponent();
+ }
+
+ private WorkspaceSetting setting;
+
+ private Dictionary<string, InnerWindow> nameMap
+ = new Dictionary<string, InnerWindow>();
+
+ private Dictionary<string, Position> positionMap
+ = new Dictionary<string, Position>();
+
+ public static readonly DependencyProperty SettingPathProperty = DependencyProperty.Register(
+ "SettingPath",
+ typeof(string),
+ typeof(Workspace),
+ new FrameworkPropertyMetadata(null, new PropertyChangedCallback(OnSettingChanged)));
+
+ private static void OnSettingChanged(DependencyObject dp, DependencyPropertyChangedEventArgs e)
+ {
+ if (dp is Workspace ws && e.Property == SettingPathProperty)
+ {
+ try
+ {
+ if (!File.Exists(e.NewValue.ToString()))
+ {
+ throw new Exception("Empty Workspace Setting.");
+ }
+ ws.setting = XmlHelper.DeserializeFromXml<WorkspaceSetting>(e.NewValue.ToString());
+ if (ws?.setting != null)
+ {
+ ws.IsLocked = ws.setting.IsLocked;
+ ws.positionMap = ws.setting.positions.ToDictionary(p => p.Key, p => p);
+ }
+ else
+ {
+ ws.positionMap.Clear();
+ }
+ }
+ catch
+ {
+ ws.setting = new WorkspaceSetting();
+ ws.positionMap.Clear();
+ }
+ }
+ }
+
+ private CanvasPosition GetPositionByIndex(int index)
+ {
+ double step = 15;
+ return new CanvasPosition
+ {
+ Left = (index + 1) * step,
+ Top = (index + 1) * step,
+ Width = 0.75 * ActualWidth,
+ Height = 0.75 * ActualHeight
+ };
+ }
+
+ public string SettingPath
+ {
+ get => (string)GetValue(SettingPathProperty);
+ set => SetValue(SettingPathProperty, value);
+ }
+
+ private int InnerWindowCount = 0;
+
+ public void AddInnerWindow(InnerWindow innerWindow)
+ {
+ AddInnerWindow(innerWindow, GetPositionByIndex(WorkArea.Children.Count));
+ }
+
+ public void AddInnerWindow(InnerWindow innerWindow, CanvasPosition canvasPosition)
+ {
+ HandleInnerWindow(innerWindow);
+ UpdatePosition(innerWindow, canvasPosition);
+ }
+
+ public void AddInnerWindow(string key, InnerWindow innerWindow)
+ {
+ if (nameMap.ContainsKey(key))
+ {
+ throw new Exception("Key Exists");
+ }
+ if (positionMap.ContainsKey(key))
+ {
+ var position = positionMap[key];
+ AddInnerWindow(innerWindow, new CanvasPosition
+ {
+ Left = position.Left * WorkArea.ActualWidth,
+ Top = position.Top * WorkArea.ActualHeight,
+ Width = position.Width * WorkArea.ActualWidth,
+ Height = position.Height * WorkArea.ActualHeight
+ });
+ }
+ else
+ {
+ AddInnerWindow(innerWindow);
+ }
+ nameMap.Add(key, innerWindow);
+ }
+
+ public void UpdatePosition(InnerWindow inner, CanvasPosition position)
+ {
+ inner.canvasPosition = position;
+ inner.Width = position.Width;
+ inner.Height = position.Height;
+ Canvas.SetLeft(inner, position.Left);
+ Canvas.SetTop(inner, position.Top);
+ }
+
+ /// <summary>
+ /// 璁剧疆InnerWindow
+ /// </summary>
+ /// <param name="inner"></param>
+ private void HandleInnerWindow(InnerWindow inner)
+ {
+ inner.MinEvent += InnerWindowMin;
+ inner.MaxEvent += InnerWindowMax;
+ inner.LockEvent += Inner_LockEvent;
+ inner.ZIndexEvent += Inner_ZIndexEvent;
+ inner.GotFocus += Inner_GotFocus;
+ inner.AttachToCanvas(WorkArea);
+ inner.CanResize = !IsLoaded;
+ Binding binding = new Binding("IsLocked")
+ {
+ Source = this,
+ Mode = BindingMode.OneWay,
+ Converter = new ReverseBoolConverter(),
+ UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
+ };
+ inner.SetBinding(InnerWindow.CanResizeProperty, binding);
+ inner.Zindex = InnerWindowCount++;
+ }
+
+ private void Inner_LockEvent(object sender, EventArgs e)
+ {
+ var inner = sender as InnerWindow;
+ var left = Canvas.GetLeft(inner) / WorkArea.ActualWidth;
+ var top = Canvas.GetTop(inner) / WorkArea.ActualHeight;
+ var width = inner.ActualWidth / WorkArea.ActualWidth;
+ var height = inner.ActualHeight / WorkArea.ActualHeight;
+
+ positionMap[inner.Title] = new Position
+ {
+ Left = left,
+ Top = top,
+ Width = width,
+ Height = height
+ };
+
+ List<Position> ps = new List<Position>();
+ foreach (var key in positionMap.Keys)
+ {
+ positionMap[key].Key = key;
+ ps.Add(positionMap[key]);
+ }
+
+ XmlHelper.SerializeToXml(SettingPath, ps);
+ }
+
+ /// <summary>
+ /// 搴曢儴MinInnerWindow澶勭悊
+ /// </summary>
+ /// <param name="inner"></param>
+ private void HandleMinInnerWindow(InnerWindow inner)
+ {
+ MinInnerWindow min = new MinInnerWindow(inner);
+ min.MaxEvent += MinInnerWindowMax;
+ min.CloseEvent += MinInnerWindowClose;
+ BottomBar.AddMinWindow(min);
+ }
+
+ /// <summary>
+ /// InnerWindow鐒︾偣浜嬩欢
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e"></param>
+ private void Inner_GotFocus(object sender, RoutedEventArgs e)
+ {
+ CanvasHelper.SetTopZIndex(sender as InnerWindow, WorkArea, typeof(InnerWindow));
+ }
+
+ /// <summary>
+ /// InnerWindow ZIndex鍒囨崲浜嬩欢
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e"></param>
+ private void Inner_ZIndexEvent(object sender, EventArgs e)
+ {
+ CanvasHelper.SetTopZIndex(sender as InnerWindow, WorkArea, typeof(InnerWindow));
+ }
+
+ /// <summary>
+ /// InnerWindow鏈�灏忓寲浜嬩欢
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e"></param>
+ private void InnerWindowMin(object sender, System.EventArgs e)
+ {
+ InnerWindow inner = sender as InnerWindow;
+ inner.Visibility = Visibility.Collapsed;
+ HandleMinInnerWindow(inner);
+ }
+
+ /// <summary>
+ /// InnerWindow鏈�澶у寲浜嬩欢
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e"></param>
+ private void InnerWindowMax(object sender, System.EventArgs e)
+ {
+ InnerWindow inner = sender as InnerWindow;
+ if (inner.WindowState == WindowState.Maximized)
+ {
+ Canvas.SetLeft(inner, inner.canvasPosition.Left);
+ Canvas.SetTop(inner, inner.canvasPosition.Top);
+
+ inner.Width = inner.canvasPosition.Width;
+ inner.Height = inner.canvasPosition.Height;
+ inner.WindowState = WindowState.Normal;
+ }
+ else
+ {
+ inner.canvasPosition.Left = Canvas.GetLeft(inner);
+ inner.canvasPosition.Top = Canvas.GetTop(inner);
+ inner.canvasPosition.Width = inner.ActualWidth;
+ inner.canvasPosition.Height = inner.ActualHeight;
+ Canvas.SetLeft(inner, 0);
+ Canvas.SetTop(inner, 0);
+ inner.Width = WorkArea.ActualWidth;
+ inner.Height = WorkArea.ActualHeight;
+ inner.WindowState = WindowState.Maximized;
+ }
+ }
+
+ /// <summary>
+ /// 搴曢儴MinInnerWindow灞曞紑
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e"></param>
+ private void MinInnerWindowMax(object sender, System.EventArgs e)
+ {
+ MinInnerWindow min = sender as MinInnerWindow;
+ min.Inner.Visibility = Visibility.Visible;
+ CanvasHelper.SetTopZIndex(min.Inner, WorkArea, typeof(InnerWindow));
+ BottomBar.RemoveMinWindow(min);
+ }
+
+ /// <summary>
+ /// 搴曢儴MinInnerWin鍏抽棴
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e"></param>
+ private void MinInnerWindowClose(object sender, System.EventArgs e)
+ {
+ MinInnerWindow min = sender as MinInnerWindow;
+ BottomBar.RemoveMinWindow(min);
+ }
+
+ private void MenuItem_Click(object sender, RoutedEventArgs e)
+ {
+ foreach (var inner in nameMap.Values)
+ {
+ var left = Canvas.GetLeft(inner) / WorkArea.ActualWidth;
+ var top = Canvas.GetTop(inner) / WorkArea.ActualHeight;
+ var width = inner.ActualWidth / WorkArea.ActualWidth;
+ var height = inner.ActualHeight / WorkArea.ActualHeight;
+ positionMap[inner.Title] = new Position
+ {
+ Left = left,
+ Top = top,
+ Width = width,
+ Height = height
+ };
+ }
+ List<Position> ps = new List<Position>();
+ foreach (var key in positionMap.Keys)
+ {
+ positionMap[key].Key = key;
+ ps.Add(positionMap[key]);
+ }
+ setting.positions = ps;
+ XmlHelper.SerializeToXml(SettingPath, setting);
+ }
+
+ public static readonly DependencyProperty IsLockedProperty = DependencyProperty.Register(
+ "IsLocked",
+ typeof(bool),
+ typeof(Workspace),
+ new FrameworkPropertyMetadata(false));
+
+ public bool IsLocked
+ {
+ get => (bool)GetValue(IsLockedProperty);
+ private set
+ {
+ if (setting != null)
+ {
+ setting.IsLocked = value;
+ }
+ SetValue(IsLockedProperty, value);
+ }
+ }
+
+ private void MenuItem_Checked(object sender, RoutedEventArgs e)
+ {
+ IsLocked = !IsLocked;
+ foreach (var inner in nameMap.Values)
+ {
+ var left = Canvas.GetLeft(inner) / WorkArea.ActualWidth;
+ var top = Canvas.GetTop(inner) / WorkArea.ActualHeight;
+ var width = inner.ActualWidth / WorkArea.ActualWidth;
+ var height = inner.ActualHeight / WorkArea.ActualHeight;
+ positionMap[inner.Title] = new Position
+ {
+ Left = left,
+ Top = top,
+ Width = width,
+ Height = height
+ };
+ }
+ List<Position> ps = new List<Position>();
+ foreach (var key in positionMap.Keys)
+ {
+ positionMap[key].Key = key;
+ ps.Add(positionMap[key]);
+ }
+ setting.positions = ps;
+ XmlHelper.SerializeToXml(SettingPath, setting);
+ }
+ }
+}
diff --git a/HMI.UI/MaskControl.xaml b/HMI.UI/MaskControl.xaml
new file mode 100644
index 0000000..4c7fb02
--- /dev/null
+++ b/HMI.UI/MaskControl.xaml
@@ -0,0 +1,58 @@
+锘�<UserControl x:Class="HMI.UI.MaskControl"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:local="clr-namespace:HMI.UI"
+ FontSize="14"
+ mc:Ignorable="d">
+ <Grid>
+ <Canvas Grid.Row="0" Grid.RowSpan="5" Visibility="Collapsed" Background="#AAFFFFFF" x:Name="pausePanel"
+ SizeChanged="pausePanel_Loaded">
+ <Border MinWidth="220" MaxWidth="300" BorderBrush="#000" Background="#FFF" BorderThickness="0.5" CornerRadius="5" x:Name="visualModal">
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="Auto"/>
+ </Grid.RowDefinitions>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition />
+ </Grid.ColumnDefinitions>
+ <Border Padding="10,5,0,5" Background="{StaticResource PrimaryColor}"
+ CornerRadius="5,5,0,0">
+ <Label Padding="2" Margin="0" Foreground="#FFF" x:Name="titleLabel" Content="璇风◢鍚�"/>
+ </Border>
+ <StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ Margin="20">
+
+ <TextBlock FontSize="45"
+ FontFamily="{StaticResource iconfont}" Foreground="{StaticResource PrimaryColor}"
+ RenderTransformOrigin="0.5,0.5"
+ VerticalAlignment="Center" Text="">
+ <TextBlock.RenderTransform>
+ <RotateTransform x:Name="MyAnimatedTransform" Angle="0" />
+ </TextBlock.RenderTransform>
+ <TextBlock.Triggers>
+ <EventTrigger RoutedEvent="TextBlock.Loaded">
+ <BeginStoryboard>
+ <Storyboard>
+ <DoubleAnimation
+ Storyboard.TargetName="MyAnimatedTransform"
+ Storyboard.TargetProperty="(RotateTransform.Angle)"
+ From="0" To="360" Duration="0:0:3"
+ RepeatBehavior="Forever"/>
+ </Storyboard>
+ </BeginStoryboard>
+ </EventTrigger>
+ </TextBlock.Triggers>
+ </TextBlock>
+ <TextBlock Grid.Row="1" Margin="20,0,0,0" Grid.Column="1" x:Name="contentLabel"
+ VerticalAlignment="Center" TextWrapping="Wrap"/>
+ </StackPanel>
+ </Grid>
+ </Border>
+ </Canvas>
+ </Grid>
+</UserControl>
diff --git a/HMI.UI/MaskControl.xaml.cs b/HMI.UI/MaskControl.xaml.cs
new file mode 100644
index 0000000..25e649c
--- /dev/null
+++ b/HMI.UI/MaskControl.xaml.cs
@@ -0,0 +1,63 @@
+锘縰sing System;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+
+namespace HMI.UI
+{
+ /// <summary>
+ /// MaskControl.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ public partial class MaskControl : UserControl
+ {
+ public static MaskControl Instance;
+
+ public static MaskControl GetInstance()
+ {
+ if (Instance == null)
+ {
+ Instance = new MaskControl();
+ }
+ return Instance;
+ }
+
+ public MaskControl()
+ {
+ InitializeComponent();
+ }
+
+ private void pausePanel_Loaded(object sender, RoutedEventArgs e)
+ {
+ var can = pausePanel;
+ var modal = visualModal;
+ Canvas.SetLeft(modal, (pausePanel.ActualWidth - visualModal.ActualWidth) / 2);
+ Canvas.SetTop(modal, (pausePanel.ActualHeight - visualModal.ActualHeight) / 2.5);
+ }
+
+ public void ShowMask(UserControl control, Action action, Action<Exception> reject = null, string title = null, string content = null)
+ {
+ this.titleLabel.Content = title;
+ this.contentLabel.Text = content;
+ pausePanel.Visibility = Visibility.Visible;
+ Task.Run(() =>
+ {
+ try
+ {
+ action();
+ }
+ catch (Exception ex)
+ {
+ if (reject != null) reject(ex);
+ }
+ finally
+ {
+ Dispatcher.BeginInvoke(new Action(() =>
+ {
+ pausePanel.Visibility = Visibility.Collapsed;
+ }));
+ }
+ });
+ }
+
+ }
+}
diff --git a/HMI.UI/RequirePasswordWindow.xaml b/HMI.UI/RequirePasswordWindow.xaml
new file mode 100644
index 0000000..92c0bce
--- /dev/null
+++ b/HMI.UI/RequirePasswordWindow.xaml
@@ -0,0 +1,33 @@
+锘�<pu:WindowX x:Class="HMI.Base.RequirePasswordWindow"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:local="clr-namespace:HMI.Base"
+ mc:Ignorable="d"
+ Style="{StaticResource ModalWindow}"
+ WindowStartupLocation="CenterOwner"
+ xmlns:pu="https://opensource.panuon.com/wpf-ui"
+ xmlns:dp="clr-namespace:HMI.UI.DpUtil"
+ Loaded="WindowX_Loaded"
+ SizeToContent="Height"
+ FontSize="14"
+ pu:WindowXModalDialog.OKButtonContent="纭畾"
+ Title="璇疯緭鍏ュ瘑鐮�" Width="500">
+ <Grid dp:GridHelper.Space="10">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="Auto"/>
+ </Grid.RowDefinitions>
+ <pu:FormGroup Header="褰撳墠鐢ㄦ埛" Orientation="Horizontal" Style="{StaticResource InputFormGroupStyle}">
+ <TextBlock Text="{Binding Username}"/>
+ </pu:FormGroup>
+ <pu:FormGroup Grid.Row="1" Header="瀵嗙爜" Orientation="Horizontal"
+ Style="{StaticResource RequiredInputFormGroupStyle}">
+ <PasswordBox x:Name="PwdPassword" VerticalContentAlignment="Center"
+ Style="{StaticResource SignInPasswordBoxStyle}"
+ pu:PasswordBoxHelper.Watermark="{DynamicResource App.Password}"/>
+ </pu:FormGroup>
+ </Grid>
+</pu:WindowX>
diff --git a/HMI.UI/RequirePasswordWindow.xaml.cs b/HMI.UI/RequirePasswordWindow.xaml.cs
new file mode 100644
index 0000000..b3472d6
--- /dev/null
+++ b/HMI.UI/RequirePasswordWindow.xaml.cs
@@ -0,0 +1,49 @@
+锘縰sing HMI.Core.Entity;
+using HMI.UI.Util;
+using Panuon.WPF.UI;
+using System.ComponentModel;
+
+namespace HMI.Base
+{
+ /// <summary>
+ /// RequirePasswordWindow.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ public partial class RequirePasswordWindow : WindowX
+ {
+ public RequirePasswordWindow()
+ {
+ this.DataContext = this;
+ InitializeComponent();
+ }
+
+ private string username;
+ public string Username
+ {
+ get => username;
+ set
+ {
+ Set(ref username, value);
+ }
+ }
+
+ protected override void OnClosing(CancelEventArgs e)
+ {
+ //Press Continue Button
+ if (DialogResult == true)
+ {
+ if (!string.Equals(PwdPassword.Password, UserInfo.User.Password))
+ {
+ ToastHelper.Error(this, "瀵嗙爜閿欒");
+ e.Cancel = true;
+ }
+ }
+ base.OnClosing(e);
+ }
+
+ private void WindowX_Loaded(object sender, System.Windows.RoutedEventArgs e)
+ {
+ Username = UserInfo.User.Username;
+ PwdPassword.Password = string.Empty;
+ }
+ }
+}
diff --git a/HMI.UI/Resources/Font/iconfont.ttf b/HMI.UI/Resources/Font/iconfont.ttf
index e7b61af..5ab6b13 100644
--- a/HMI.UI/Resources/Font/iconfont.ttf
+++ b/HMI.UI/Resources/Font/iconfont.ttf
Binary files differ
diff --git a/HMI.UI/Resources/Icon/dot.png b/HMI.UI/Resources/Icon/dot.png
new file mode 100644
index 0000000..21021e6
--- /dev/null
+++ b/HMI.UI/Resources/Icon/dot.png
Binary files differ
diff --git a/HMI.UI/Resources/Icon/dot.svg b/HMI.UI/Resources/Icon/dot.svg
new file mode 100644
index 0000000..7864800
--- /dev/null
+++ b/HMI.UI/Resources/Icon/dot.svg
@@ -0,0 +1,12 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="1920mm" height="1080mm" viewBox="0 0 1920 1080">
+ <defs>
+ <!-- 鍒涘缓鐐归樀鍥炬 -->
+ <pattern id="dotPattern" patternUnits="userSpaceOnUse" width="5" height="5">
+ <!-- 姣忎釜鍗曞厓涓績缁樺埗鐩村緞0.5mm鐨勯粦鐐� -->
+ <circle cx="2.5" cy="2.5" r="0.25" fill="black"/>
+ </pattern>
+ </defs>
+
+ <!-- 鐢ㄧ偣闃靛浘妗堝~鍏呮暣涓尯鍩� -->
+ <rect width="100%" height="100%" fill="url(#dotPattern)" fill-opacity="1"/>
+</svg>
\ No newline at end of file
diff --git a/HMI.UI/Resources/Icon/dot2.png b/HMI.UI/Resources/Icon/dot2.png
new file mode 100644
index 0000000..e2d568e
--- /dev/null
+++ b/HMI.UI/Resources/Icon/dot2.png
Binary files differ
diff --git a/HMI.UI/Style/FormStyle.xaml b/HMI.UI/Style/FormStyle.xaml
index b9a908f..24958cc 100644
--- a/HMI.UI/Style/FormStyle.xaml
+++ b/HMI.UI/Style/FormStyle.xaml
@@ -175,4 +175,14 @@
<Setter Property="SelectedDateTime" Value="{x:Null}"/>
</Style>
+ <Style x:Key="SignInPasswordBoxStyle" TargetType="PasswordBox" BasedOn="{StaticResource {x:Type PasswordBox}}">
+ <Setter Property="pu:PasswordBoxHelper.FocusedBorderBrush" Value="#6CBCEA" />
+ <Setter Property="pu:PasswordBoxHelper.FocusedShadowColor" Value="#6CBCEA" />
+ <Setter Property="pu:PasswordBoxHelper.CornerRadius" Value="2" />
+ <Setter Property="pu:PasswordBoxHelper.WatermarkForeground" Value="#4A4A4A" />
+ <Setter Property="pu:PasswordBoxHelper.FocusedWatermarkForeground" Value="#AAAAAA" />
+ <Setter Property="pu:PasswordBoxHelper.ClearButtonVisibility" Value="VisibleOnHoverAndNonnull" />
+ <Setter Property="Height" Value="35" />
+ <Setter Property="Padding" Value="10,0" />
+ </Style>
</ResourceDictionary>
\ No newline at end of file
diff --git a/HMI.UI/Style/MsgBoxStyle.xaml b/HMI.UI/Style/MsgBoxStyle.xaml
index 1858f41..984e2cc 100644
--- a/HMI.UI/Style/MsgBoxStyle.xaml
+++ b/HMI.UI/Style/MsgBoxStyle.xaml
@@ -124,6 +124,7 @@
<pu:ToastSetting x:Key="toastSuccess" Spacing="25">
<pu:ToastSetting.LabelStyle>
<Style TargetType="Label" BasedOn="{StaticResource {x:Static pu:Toast.LabelStyleKey}}">
+ <Setter Property="FontSize" Value="18" />
<Setter Property="Background" Value="{StaticResource SuccessColor}" />
<Setter Property="Foreground" Value="{StaticResource SuccessColorContrast}" />
</Style>
@@ -133,6 +134,7 @@
<pu:ToastSetting x:Key="toastWarning" Spacing="25">
<pu:ToastSetting.LabelStyle>
<Style TargetType="Label" BasedOn="{StaticResource {x:Static pu:Toast.LabelStyleKey}}">
+ <Setter Property="FontSize" Value="18" />
<Setter Property="Background" Value="{StaticResource WarningColor}" />
<Setter Property="Foreground" Value="{StaticResource SuccessColorContrast}" />
</Style>
@@ -142,6 +144,7 @@
<pu:ToastSetting x:Key="toastError" Spacing="25">
<pu:ToastSetting.LabelStyle>
<Style TargetType="Label" BasedOn="{StaticResource {x:Static pu:Toast.LabelStyleKey}}">
+ <Setter Property="FontSize" Value="18" />
<Setter Property="Background" Value="{StaticResource DangerColor}" />
<Setter Property="Foreground" Value="{StaticResource DangerColorContrast}" />
</Style>
diff --git a/HMI.UI/Style/PanuonDataGrid.xaml b/HMI.UI/Style/PanuonDataGrid.xaml
index 4260135..c2d9930 100644
--- a/HMI.UI/Style/PanuonDataGrid.xaml
+++ b/HMI.UI/Style/PanuonDataGrid.xaml
@@ -18,7 +18,15 @@
<Style x:Key="DefaultDataGridRow" TargetType="DataGridRow" BasedOn="{StaticResource {x:Static pu:StyleKeys.DataGridRowStyle}}">
<Setter Property="Background" Value="White"/>
- <Setter Property="DetailsVisibility" Value="Collapsed"/>
+ <Setter Property="HeaderStyle">
+ <Setter.Value>
+ <Style TargetType="DataGridColumnHeader"
+ BasedOn="{StaticResource {x:Static pu:StyleKeys.DataGridColumnHeaderStyle}}">
+ <Setter Property="Padding" Value="10"/>
+ <Setter Property="BorderThickness" Value="0"/>
+ </Style>
+ </Setter.Value>
+ </Setter>
<Style.Triggers>
<Trigger Property="AlternationIndex" Value="1">
<Setter Property="Background" Value="#eeeeee"/>
@@ -26,22 +34,15 @@
</Style.Triggers>
</Style>
-
- <Style TargetType="DataGridCell"
- BasedOn="{StaticResource {x:Static pu:StyleKeys.DataGridCellStyle}}">
- <Setter Property="Background" Value="Transparent"/>
- <Setter Property="Padding" Value="5"/>
- <Setter Property="Margin" Value="0"/>
- <Setter Property="BorderThickness" Value="0"/>
- <Setter Property="VerticalAlignment" Value="Stretch"/>
- </Style>
-
<Style x:Key="DefaultDataGrid" TargetType="DataGrid" BasedOn="{StaticResource {x:Static pu:StyleKeys.DataGridStyle}}">
<Style.Resources>
- <Style TargetType="DataGridColumnHeader"
- BasedOn="{StaticResource {x:Static pu:StyleKeys.DataGridColumnHeaderStyle}}">
- <Setter Property="Padding" Value="10"/>
+ <Style TargetType="DataGridCell"
+ BasedOn="{StaticResource {x:Static pu:StyleKeys.DataGridCellStyle}}">
+ <Setter Property="Background" Value="Transparent"/>
+ <Setter Property="Padding" Value="5"/>
+ <Setter Property="Margin" Value="0"/>
<Setter Property="BorderThickness" Value="0"/>
+ <Setter Property="VerticalAlignment" Value="Stretch"/>
</Style>
</Style.Resources>
@@ -51,7 +52,7 @@
<Setter Property="pu:DataGridHelper.ColumnHeaderPadding" Value="0"/>
<Setter Property="ForceCursor" Value="True"/>
<Setter Property="SelectionMode" Value="Single"/>
- <Setter Property="RowStyle" Value="{StaticResource DefaultDataGridRow}"/>
+ <!--<Setter Property="RowStyle" Value="{StaticResource DefaultDataGridRow}"/>-->
<Setter Property="AlternationCount" Value="2"></Setter>
<Setter Property="Foreground" Value="#3a3a3a"/>
<Setter Property="HorizontalGridLinesBrush" Value="{StaticResource TableBoarder}"/>
diff --git a/HMI.UI/Style/PanuonListView.xaml b/HMI.UI/Style/PanuonListView.xaml
new file mode 100644
index 0000000..23eff26
--- /dev/null
+++ b/HMI.UI/Style/PanuonListView.xaml
@@ -0,0 +1,77 @@
+锘�<ResourceDictionary
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ mc:Ignorable="d"
+ xmlns:ui="clr-namespace:HMI.UI"
+ xmlns:sys="clr-namespace:System;assembly=mscorlib"
+ xmlns:pw="https://opensource.panuon.com/wpf"
+ xmlns:pu="https://opensource.panuon.com/wpf-ui"
+ xmlns:uic="clr-namespace:HMI.UI.Converter"
+ xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI">
+ <ResourceDictionary.MergedDictionaries>
+ <pu:StyleDictionary Includes="ListView" />
+ <ResourceDictionary Source="/HMI.UI;component/Style/Colors.xaml"/>
+ <ResourceDictionary Source="/HMI.UI;component/Resources/Font/Font.xaml"/>
+ <ResourceDictionary Source="/HMI.UI;component/Style/ScrollBarResource.xaml"/>
+ </ResourceDictionary.MergedDictionaries>
+
+ <uic:ListViewRowNumberConverter x:Key="lvRowNumber"/>
+
+ <uic:ListViewRowHeightConverter x:Key="sbC"/>
+
+ <Style x:Key="CellBorder" TargetType="Border">
+ <Setter Property="BorderBrush" Value="{DynamicResource CommonBoarder}"/>
+ <Setter Property="BorderThickness" Value="1,0,0,0"/>
+ <Setter Property="Margin" Value="-5,0"/>
+ <Setter Property="Padding" Value="5,0,0,0"/>
+ <Setter Property="Height" Value="{Binding ActualHeight,
+ Mode=OneWay,
+ RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=GridViewRowPresenter,AncestorLevel=1}}"/>
+ <!--<Setter Property="Width" Value="{Binding ActualWidth,
+ Converter={StaticResource sbC},ConverterParameter=2.0,
+ RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ContentPresenter,AncestorLevel=1}}"/>-->
+ </Style>
+
+ <Style x:Key="ListTableTextBlock" TargetType="TextBlock">
+ <Setter Property="Padding" Value="0,5"/>
+ <Setter Property="Margin" Value="0"/>
+ <Setter Property="VerticalAlignment" Value="Center"/>
+ <Setter Property="TextWrapping" Value="Wrap"/>
+ </Style>
+
+ <Style x:Key="DefaultListTableItemStyle" TargetType="ListViewItem" BasedOn="{StaticResource {x:Static pu:StyleKeys.ListViewItemStyle}}">
+ <Setter Property="Background" Value="#FFF"/>
+ <Style.Triggers>
+ <Trigger Property="ItemsControl.AlternationIndex" Value="1">
+ <Setter Property="Background" Value="#eeeeee"/>
+ </Trigger>
+ </Style.Triggers>
+ </Style>
+
+ <Style x:Key="DefaultListTable" TargetType="ListView" BasedOn="{StaticResource {x:Static pu:StyleKeys.ListViewStyle}}">
+ <Style.Resources>
+ <Style TargetType="ScrollBar" BasedOn="{StaticResource ScrollStyle_Mobile}"/>
+ </Style.Resources>
+
+ <Setter Property="BorderThickness" Value="0"/>
+ <Setter Property="VirtualizingPanel.IsVirtualizing" Value="True"/>
+ <Setter Property="AlternationCount" Value="2"/>
+ <Setter Property="pu:ListViewHelper.ColumnHeaderHeight" Value="36"/>
+ <Setter Property="pu:ListViewHelper.ColumnHeaderBackground" Value="{DynamicResource VerBar}"/>
+ <Setter Property="pu:ListViewHelper.ColumnHeaderHoverBackground" Value="{DynamicResource VerBar}"/>
+ <Setter Property="pu:ListViewHelper.ColumnHeaderForeground" Value="#FFF"/>
+ <Setter Property="pu:ListViewHelper.ItemsHoverBackground" Value="{DynamicResource SecondPrimaryColor}"/>
+ <Setter Property="pu:ListViewHelper.ItemsHoverForeground" Value="{DynamicResource SecondPrimaryColorContract}"/>
+ <Setter Property="pu:ListViewHelper.ItemsSelectedBackground" Value="{DynamicResource PrimaryColor}"/>
+ <Setter Property="pu:ListViewHelper.ItemsSelectedForeground" Value="{DynamicResource PrimaryColorContract}"/>
+ <Setter Property="pu:ListViewHelper.ItemsSeparatorBrush" Value="{DynamicResource CommonBoarder}"/>
+ <Setter Property="pu:ListViewHelper.ItemsSeparatorThickness" Value="1"/>
+ <Setter Property="pu:ListViewHelper.ItemsPadding" Value="0"/>
+ <Setter Property="pu:ListViewHelper.ItemsHeight" Value="30"/>
+ <Setter Property="pu:ListViewHelper.ItemsSeparatorVisibility" Value="Visible"/>
+ <Setter Property="ItemContainerStyle" Value="{StaticResource DefaultListTableItemStyle}"/>
+ </Style>
+
+</ResourceDictionary>
\ No newline at end of file
diff --git a/HMI.UI/Style/PanuonResource.xaml b/HMI.UI/Style/PanuonResource.xaml
index 01cd250..23a2dcb 100644
--- a/HMI.UI/Style/PanuonResource.xaml
+++ b/HMI.UI/Style/PanuonResource.xaml
@@ -11,8 +11,10 @@
xmlns:uic="clr-namespace:HMI.UI.Converter;assembly=HMI.UI"
xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI">
<ResourceDictionary.MergedDictionaries>
- <pu:StyleDictionary Includes="PasswordBox,TextBox,ComboBox,Button,TreeView,Menu,ListBox,ContextMenu" />
+ <pu:StyleDictionary Includes="PasswordBox,TextBox,ComboBox,Button,TreeView,Menu,ListBox,ContextMenu,TabControl" />
<ResourceDictionary Source="/HMI.UI;component/Style/Colors.xaml"/>
+ <ResourceDictionary Source="/HMI.UI;component/Style/PanuonDataGrid.xaml"/>
+ <ResourceDictionary Source="/HMI.UI;component/Style/ScrollBarResource.xaml"/>
<ResourceDictionary Source="/HMI.UI;component/Resources/Font/Font.xaml"/>
</ResourceDictionary.MergedDictionaries>
<sys:Double x:Key="TitleFontSize">20</sys:Double>
@@ -234,4 +236,45 @@
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0"/>
</Style>
+
+ <Style x:Key="HeaderTabControl" TargetType="TabControl">
+ <Setter Property="pu:TabControlHelper.HeaderPanelAlignment" Value="Stretch"/>
+ <Setter Property="pu:TabControlHelper.ItemsBackground" Value="{DynamicResource VerBar}"/>
+ <Setter Property="pu:TabControlHelper.ItemsForeground" Value="#FFF"/>
+ <Setter Property="pu:TabControlHelper.ItemsSelectedForeground" Value="{DynamicResource PrimaryColor}"/>
+ <Setter Property="pu:TabControlHelper.ItemsFontSize" Value="14"/>
+ <Setter Property="pu:TabControlHelper.ItemsHeight" Value="30"/>
+ <Setter Property="pu:TabControlHelper.ItemsHorizontalHeaderAlignment" Value="Left"/>
+ <Setter Property="pu:TabControlHelper.ItemsHoverBackground" Value="{DynamicResource SecondPrimaryColor}"/>
+ <Setter Property="pu:TabControlHelper.ItemsHoverForeground" Value="#FFF"/>
+ <Setter Property="pu:TabControlHelper.ItemsPadding" Value="20,5,0,0"/>
+ <Setter Property="pu:TabControlHelper.ItemsRibbonLineCornerRadius" Value="4"/>
+ <Setter Property="pu:TabControlHelper.ItemsRibbonLineMargin" Value="0,5,0,5"/>
+ <Setter Property="pu:TabControlHelper.ItemsRibbonLineThickness" Value="4"/>
+ <Setter Property="pu:TabControlHelper.ItemsRibbonLineVisibility" Value="Visible"/>
+ <Setter Property="pu:TabControlHelper.ItemsSelectedBackground" Value="#FFF"/>
+ <Setter Property="pu:TabControlHelper.ItemsSelectedRibbonLineBrush" Value="#FFF"/>
+ <Setter Property="pu:TabControlHelper.ItemsSelectedRibbonLineThickness" Value="2"/>
+ <Setter Property="pu:TabControlHelper.ItemsWidth" Value="100"/>
+ <Setter Property="Template">
+ <Setter.Value>
+ <ControlTemplate TargetType="{x:Type TabControl}">
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="*"/>
+ </Grid.RowDefinitions>
+ <Border BorderThickness="1,1,1,0" BorderBrush="#acacac" Background="{DynamicResource VerBar}" Padding="2,2,10,0">
+ <TabPanel x:Name="HeaderPanel" Grid.Row="0" Panel.ZIndex="1" IsItemsHost="True"/>
+ </Border>
+
+ <Border Grid.Row="1" BorderBrush="{TemplateBinding BorderBrush}"
+ BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
+ <ContentPresenter x:Name="PART_SelectedContentHost" ContentSource="SelectedContent"/>
+ </Border>
+ </Grid>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style>
</ResourceDictionary>
\ No newline at end of file
diff --git a/HMI.UI/Style/ScrollBarResource.xaml b/HMI.UI/Style/ScrollBarResource.xaml
new file mode 100644
index 0000000..c7d7f6e
--- /dev/null
+++ b/HMI.UI/Style/ScrollBarResource.xaml
@@ -0,0 +1,106 @@
+锘�<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:ui="clr-namespace:HMI.UI"
+ xmlns:sys="clr-namespace:System;assembly=mscorlib">
+
+ <ControlTemplate x:Key="VerticalScrollBar" TargetType="RangeBase">
+ <Border Width="{TemplateBinding Width}" CornerRadius="2"
+ Background="{DynamicResource CommonBoarder}">
+ <Track Name="PART_Track" IsDirectionReversed="true">
+ <Track.DecreaseRepeatButton>
+ <RepeatButton Command="ScrollBar.PageUpCommand" Focusable="False">
+ <RepeatButton.Template>
+ <ControlTemplate>
+ <Border Background="Transparent"></Border>
+ </ControlTemplate>
+ </RepeatButton.Template>
+ </RepeatButton>
+ </Track.DecreaseRepeatButton>
+ <Track.Thumb>
+ <Thumb Width="{TemplateBinding Width}" Focusable="False">
+ <Thumb.Template>
+ <ControlTemplate>
+ <Border Background="Gray"
+ CornerRadius="2" />
+ </ControlTemplate>
+ </Thumb.Template>
+ </Thumb>
+ </Track.Thumb>
+ <Track.IncreaseRepeatButton>
+ <RepeatButton Command="ScrollBar.PageDownCommand" Focusable="False">
+ <RepeatButton.Template>
+ <ControlTemplate>
+ <Border Background="Transparent"></Border>
+ </ControlTemplate>
+ </RepeatButton.Template>
+ </RepeatButton>
+ </Track.IncreaseRepeatButton>
+ </Track>
+ </Border>
+ </ControlTemplate>
+
+ <ControlTemplate x:Key="HorizontalScrollBar" TargetType="{x:Type ScrollBar}">
+ <Grid Background="{DynamicResource CommonBoarder}">
+ <Track
+ Name="PART_Track"
+ Grid.Column="1"
+ IsDirectionReversed="False">
+ <Track.DecreaseRepeatButton>
+ <RepeatButton Command="ScrollBar.PageLeftCommand" Focusable="False">
+ <RepeatButton.Template>
+ <ControlTemplate>
+ <Border Background="Transparent"></Border>
+ </ControlTemplate>
+ </RepeatButton.Template>
+ </RepeatButton>
+ </Track.DecreaseRepeatButton>
+ <Track.Thumb>
+ <Thumb Height="{TemplateBinding Height}" >
+ <Thumb.Template>
+ <ControlTemplate>
+ <Border Background="Gray"
+ CornerRadius="2" />
+ </ControlTemplate>
+ </Thumb.Template>
+ </Thumb>
+ </Track.Thumb>
+ <Track.IncreaseRepeatButton>
+ <RepeatButton Command="ScrollBar.PageRightCommand" Focusable="False">
+ <RepeatButton.Template>
+ <ControlTemplate>
+ <Border Background="Transparent"></Border>
+ </ControlTemplate>
+ </RepeatButton.Template>
+ </RepeatButton>
+ </Track.IncreaseRepeatButton>
+ </Track>
+ </Grid>
+ </ControlTemplate>
+
+ <Style x:Key="ScrollStyle_Mobile" TargetType="ScrollBar">
+ <Style.Resources>
+ <sys:Double x:Key="{x:Static SystemParameters.VerticalScrollBarWidthKey}">6</sys:Double>
+ <sys:Double x:Key="{x:Static SystemParameters.HorizontalScrollBarHeightKey}">6</sys:Double>
+ </Style.Resources>
+
+ <Style.Triggers>
+ <Trigger Property="Orientation" Value="Vertical">
+ <Setter Property="Width" Value="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}" />
+ <Setter Property="Height" Value="Auto" />
+ <Setter Property="Template" Value="{DynamicResource VerticalScrollBar}" />
+ </Trigger>
+ <Trigger Property="Orientation" Value="Horizontal">
+ <Setter Property="Width" Value="Auto" />
+ <Setter Property="Height" Value="{DynamicResource {x:Static SystemParameters.HorizontalScrollBarHeightKey}}" />
+ <Setter Property="Template" Value="{DynamicResource HorizontalScrollBar}" />
+ </Trigger>
+ </Style.Triggers>
+ </Style>
+
+ <Style x:Key="DefaultScrollViewer" TargetType="ScrollViewer">
+ <Style.Resources>
+ <Style TargetType="ScrollBar" BasedOn="{StaticResource ScrollStyle_Mobile}"/>
+ </Style.Resources>
+ </Style>
+
+</ResourceDictionary>
\ No newline at end of file
diff --git a/HMI.UI/Style/WindowResources.xaml b/HMI.UI/Style/WindowResources.xaml
index 2cf9e7a..d12c27e 100644
--- a/HMI.UI/Style/WindowResources.xaml
+++ b/HMI.UI/Style/WindowResources.xaml
@@ -1,6 +1,7 @@
锘�<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ui="clr-namespace:HMI.UI"
+ xmlns:sys="clr-namespace:System;assembly=mscorlib"
>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/HMI.UI;component/Style/Colors.xaml"/>
diff --git a/HMI.UI/TableComboBox.cs b/HMI.UI/TableComboBox.cs
new file mode 100644
index 0000000..f76d7b5
--- /dev/null
+++ b/HMI.UI/TableComboBox.cs
@@ -0,0 +1,249 @@
+锘縰sing HMI.UI.Converter;
+using HMI.UI.MDI;
+using System;
+using System.ComponentModel;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Input;
+using System.Windows.Media;
+
+namespace HMI.UI
+{
+ public class TableComboBox : ItemsControl
+ {
+ static TableComboBox()
+ {
+ DefaultStyleKeyProperty.OverrideMetadata(typeof(TableComboBox), new FrameworkPropertyMetadata(typeof(TableComboBox)));
+ }
+
+ public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(
+ "Value",
+ typeof(object),
+ typeof(TableComboBox),
+ new FrameworkPropertyMetadata());
+
+ public static readonly DependencyProperty CanEditProperty = DependencyProperty.Register(
+ "CanEdit",
+ typeof(bool),
+ typeof(TableComboBox),
+ new FrameworkPropertyMetadata(false, new PropertyChangedCallback(OnCanEditPropertyChanged)));
+
+ public static DependencyProperty IsEditingProperty = DependencyProperty.Register(
+ "IsEditing",
+ typeof(bool),
+ typeof(TableComboBox),
+ new FrameworkPropertyMetadata(false, new PropertyChangedCallback(OnIsEditingPropertyChanged)));
+
+ public static DependencyProperty PreEditingProperty = DependencyProperty.Register(
+ "PreEditing",
+ typeof(Func<bool?>),
+ typeof(TableComboBox),
+ new FrameworkPropertyMetadata());
+
+ public static DependencyProperty ShowEmptyProperty = DependencyProperty.Register(
+ "ShowEmpty",
+ typeof(bool),
+ typeof(TableComboBox),
+ new FrameworkPropertyMetadata(false));
+
+ public static DependencyProperty IsDropDownOpenProperty = DependencyProperty.Register(
+ "IsDropDownOpen",
+ typeof(bool),
+ typeof(TableComboBox),
+ new FrameworkPropertyMetadata(false));
+
+
+ private static void OnCanEditPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
+ {
+ if (obj is TableComboBox eb && e.Property == CanEditProperty)
+ {
+ bool value = (bool)e.NewValue;
+ if (value)
+ {
+ eb.MouseDoubleClick += eb.EditBox_MouseDoubleClick;
+ }
+ else
+ {
+ eb.MouseDoubleClick -= eb.EditBox_MouseDoubleClick;
+ }
+ }
+ }
+
+ private static void OnIsEditingPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
+ {
+ if (obj is TableComboBox eb && e.Property == IsEditingProperty)
+ {
+ bool value = (bool)e.NewValue;
+ eb.editor.Visibility = value ? Visibility.Visible : Visibility.Collapsed;
+ if (value)
+ {
+ eb.editor.Focus();
+ }
+ }
+ }
+
+ private ComboBox editor;
+ public TableComboBox()
+ {
+ this.Loaded += EditBox_Loaded;
+ }
+
+ public bool IsDropDownOpen
+ {
+ get => (bool)GetValue(IsDropDownOpenProperty);
+ set
+ {
+ SetValue(IsDropDownOpenProperty, value);
+ }
+ }
+
+
+ private void EditBox_Loaded(object sender, RoutedEventArgs e)
+ {
+ editor = this.Template.FindName("PART_ComboBoxPart", this) as ComboBox;
+ editor.DisplayMemberPath = this.DisplayMemberPath;
+ editor.SelectedValuePath = this.SelectedValuePath;
+ editor.ItemsSource = this.ItemsSource;
+ editor.SelectedValue = Value;
+ editor.SelectionChanged += Editor_SelectionChanged;
+
+ Binding binding = new Binding("IsDropDownOpen")
+ {
+ Source = this,
+ Mode = BindingMode.TwoWay,
+ UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
+ };
+ editor.SetBinding(ComboBox.IsDropDownOpenProperty, binding);
+ }
+
+ private void Editor_SelectionChanged(object sender, SelectionChangedEventArgs e)
+ {
+ ComboBox box = sender as ComboBox;
+ if (IsEditing)
+ {
+ box.Focus();
+ }
+ }
+
+ private void EditBox_MouseDoubleClick(object sender, MouseButtonEventArgs e)
+ {
+ if (IsEditing)
+ {
+ return;
+ }
+
+ Func<bool?> pre = GetValue(PreEditingProperty) as Func<bool?>;
+ if (pre != null && pre.Invoke() != true)
+ {
+ return;
+ }
+ //var win = Window.GetWindow(this);
+
+ //win.MouseDown += EditBox_LostFocus;
+ editor.LostFocus += EditBox_LostFocus;
+ IsEditing = true;
+ e.Handled = true;
+ }
+
+ public static bool GetElementUnderMouse(UIElement relativeTo, UIElement target)
+ {
+ Point mousePosition = Mouse.GetPosition(relativeTo);
+ bool res = false;
+ HitTestResultCallback resultCallback = (result) =>
+ {
+ // 鑾峰彇鐩镐氦鐨刄I鍏冪礌
+ var element = result.VisualHit as FrameworkElement;
+
+ if (element != null && element == target)
+ {
+ res = true;
+ return HitTestResultBehavior.Stop; // 鎵惧埌鍚庡仠姝㈤亶鍘�
+ }
+ return HitTestResultBehavior.Continue;
+ };
+
+ VisualTreeHelper.HitTest(relativeTo, null,
+ resultCallback, new PointHitTestParameters(mousePosition));
+ return res;
+ }
+
+ private void EditBox_LostFocus(object sender, RoutedEventArgs e)
+ {
+ if (IsDropDownOpen)
+ {
+ return;
+ }
+ if (sender == editor)
+ {
+ IsEditing = false;
+ editor.LostFocus -= EditBox_LostFocus;
+ Window.GetWindow(this).MouseDown -= EditBox_LostFocus;
+ }
+ else
+ {
+ var win = sender as Window;
+ if (!GetElementUnderMouse(win, this))
+ {
+ //editing.Focu
+ IsEditing = false;
+ win.MouseDown -= EditBox_LostFocus;
+ Window.GetWindow(this).MouseDown -= EditBox_LostFocus;
+ }
+ }
+ }
+
+ public object Value
+ {
+ get
+ {
+ return GetValue(ValueProperty);
+ }
+ set
+ {
+ SetValue(ValueProperty, value);
+ }
+ }
+
+ public bool CanEdit
+ {
+ get => (bool)GetValue(CanEditProperty);
+ set
+ {
+ SetValue(CanEditProperty, value);
+ }
+ }
+
+ public string SelectedValuePath
+ {
+ get; set;
+ }
+
+ public bool IsEditing
+ {
+ get => (bool)GetValue(IsEditingProperty);
+ set
+ {
+ SetValue(IsEditingProperty, value);
+ }
+ }
+
+ public Func<bool?> PreEditing
+ {
+ get => (Func<bool?>)GetValue(PreEditingProperty);
+ set
+ {
+ SetValue(PreEditingProperty, value);
+ }
+ }
+
+ public bool ShowEmpty
+ {
+ get => (bool)GetValue(ShowEmptyProperty);
+ set
+ {
+ SetValue(ShowEmptyProperty, value);
+ }
+ }
+ }
+}
diff --git a/HMI.UI/Themes/Generic.xaml b/HMI.UI/Themes/Generic.xaml
new file mode 100644
index 0000000..e77a351
--- /dev/null
+++ b/HMI.UI/Themes/Generic.xaml
@@ -0,0 +1,145 @@
+锘�<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:local="clr-namespace:HMI.UI">
+ <RadialGradientBrush x:Key="RedLight" GradientOrigin="0.3,0.3"
+ RadiusX="0.7"
+ RadiusY="0.7">
+ <RadialGradientBrush.GradientStops>
+ <GradientStop Color="#fd583e" Offset="0"/>
+ <GradientStop Color="#d5341f" Offset="0.5"/>
+ <GradientStop Color="#aa0e00" Offset="1"/>
+ </RadialGradientBrush.GradientStops>
+ </RadialGradientBrush>
+
+ <RadialGradientBrush x:Key="GreenLight" GradientOrigin="0.3,0.3"
+ RadiusX="0.7"
+ RadiusY="0.7">
+ <RadialGradientBrush.GradientStops>
+ <GradientStop Color="#1b9e14" Offset="1"/>
+ <GradientStop Color="#21c418" Offset="0.5"/>
+ <GradientStop Color="#28ea1d" Offset="0"/>
+ </RadialGradientBrush.GradientStops>
+ </RadialGradientBrush>
+
+ <Style TargetType="{x:Type local:LightBall}">
+ <Setter Property="Template">
+ <Setter.Value>
+ <ControlTemplate TargetType="{x:Type local:LightBall}">
+ <StackPanel Orientation="Horizontal" VerticalAlignment="Center">
+ <Ellipse Height="{TemplateBinding Size}" Width="{TemplateBinding Size}" VerticalAlignment="Center">
+ <Ellipse.Style>
+ <Style TargetType="Ellipse">
+ <Setter Property="Fill" Value="{StaticResource RedLight}"/>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding Value,RelativeSource={RelativeSource Mode=TemplatedParent}}" Value="True">
+ <Setter Property="Fill" Value="{StaticResource GreenLight}"/>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Ellipse.Style>
+ </Ellipse>
+ <ContentPresenter Margin="5,0,0,0" VerticalAlignment="Center"/>
+ </StackPanel>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style>
+
+ <Style TargetType="{x:Type local:EditBox}">
+ <Setter Property="HorizontalAlignment" Value="Stretch" />
+ <Setter Property="Template">
+ <Setter.Value>
+ <ControlTemplate TargetType="{x:Type local:EditBox}">
+ <Grid Cursor="Hand" MinWidth="{TemplateBinding MinWidth}" Background="{TemplateBinding Background}">
+ <Border x:Name="sb" VerticalAlignment="Center" Padding="0" Margin="0">
+ <Border.Style>
+ <Style TargetType="Border">
+ <Setter Property="BorderThickness" Value="0"/>
+ <Setter Property="BorderBrush" Value="Transparent"/>
+ <Style.Triggers>
+ <MultiDataTrigger>
+ <MultiDataTrigger.Conditions>
+ <Condition Binding="{Binding Path=Value, RelativeSource={RelativeSource TemplatedParent}}" Value=""/>
+ <Condition Binding="{Binding Path=ShowEmpty, RelativeSource={RelativeSource TemplatedParent}}" Value="True"/>
+ </MultiDataTrigger.Conditions>
+ <MultiDataTrigger.Setters>
+ <Setter Property="BorderBrush" Value="Black"/>
+ <Setter Property="BorderThickness" Value="0,0,0,0.6"/>
+ </MultiDataTrigger.Setters>
+ </MultiDataTrigger>
+ <MultiDataTrigger>
+ <MultiDataTrigger.Conditions>
+ <Condition Binding="{Binding Path=Value, RelativeSource={RelativeSource TemplatedParent}}" Value="{x:Null}"/>
+ <Condition Binding="{Binding Path=ShowEmpty, RelativeSource={RelativeSource TemplatedParent}}" Value="True"/>
+ </MultiDataTrigger.Conditions>
+ <MultiDataTrigger.Setters>
+ <Setter Property="BorderBrush" Value="Black"/>
+ <Setter Property="BorderThickness" Value="0,0,0,0.6"/>
+ </MultiDataTrigger.Setters>
+ </MultiDataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Border.Style>
+ <TextBlock x:Name="PART_TextBlockPart"
+ FontSize="{TemplateBinding FontSize}"
+ TextWrapping="NoWrap" Padding="0" VerticalAlignment="Center"
+ Text="{Binding Path=Value, RelativeSource={RelativeSource TemplatedParent}}"/>
+ </Border>
+ <TextBox x:Name="PART_TextBoxPart" BorderThickness="0" Padding="0"
+ FontSize="{TemplateBinding FontSize}" Visibility="Collapsed"
+ Text="{Binding Path=Value, RelativeSource={RelativeSource TemplatedParent}}"/>
+ </Grid>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style>
+
+ <Style TargetType="{x:Type local:TableComboBox}">
+ <Setter Property="HorizontalAlignment" Value="Stretch" />
+ <Setter Property="Template">
+ <Setter.Value>
+ <ControlTemplate TargetType="{x:Type local:TableComboBox}">
+ <Grid Cursor="Hand" MinWidth="{TemplateBinding MinWidth}" Background="{TemplateBinding Background}">
+ <Border x:Name="sb" VerticalAlignment="Center" Padding="0" Margin="0">
+ <Border.Style>
+ <Style TargetType="Border">
+ <Setter Property="BorderThickness" Value="0"/>
+ <Setter Property="BorderBrush" Value="Transparent"/>
+ <Style.Triggers>
+ <MultiDataTrigger>
+ <MultiDataTrigger.Conditions>
+ <Condition Binding="{Binding Path=Value, RelativeSource={RelativeSource TemplatedParent}}" Value=""/>
+ <Condition Binding="{Binding Path=ShowEmpty, RelativeSource={RelativeSource TemplatedParent}}" Value="True"/>
+ </MultiDataTrigger.Conditions>
+ <MultiDataTrigger.Setters>
+ <Setter Property="BorderBrush" Value="Black"/>
+ <Setter Property="BorderThickness" Value="0,0,0,0.6"/>
+ </MultiDataTrigger.Setters>
+ </MultiDataTrigger>
+ <MultiDataTrigger>
+ <MultiDataTrigger.Conditions>
+ <Condition Binding="{Binding Path=Value, RelativeSource={RelativeSource TemplatedParent}}" Value="{x:Null}"/>
+ <Condition Binding="{Binding Path=ShowEmpty, RelativeSource={RelativeSource TemplatedParent}}" Value="True"/>
+ </MultiDataTrigger.Conditions>
+ <MultiDataTrigger.Setters>
+ <Setter Property="BorderBrush" Value="Black"/>
+ <Setter Property="BorderThickness" Value="0,0,0,0.6"/>
+ </MultiDataTrigger.Setters>
+ </MultiDataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Border.Style>
+ <TextBlock x:Name="PART_TextBlockPart"
+ FontSize="{TemplateBinding FontSize}"
+ TextWrapping="NoWrap" Padding="0" VerticalAlignment="Center"
+ Text="{Binding Path=Value, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}"/>
+ </Border>
+ <ComboBox x:Name="PART_ComboBoxPart" BorderThickness="0" Padding="0"
+ FontSize="{TemplateBinding FontSize}" Visibility="Collapsed"
+ Text="{Binding Path=Value, RelativeSource={RelativeSource TemplatedParent}}"/>
+ </Grid>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style>
+</ResourceDictionary>
\ No newline at end of file
diff --git a/HMI.UI/Util/MsgBoxHelper.cs b/HMI.UI/Util/MsgBoxHelper.cs
index 18f2a30..2c81478 100644
--- a/HMI.UI/Util/MsgBoxHelper.cs
+++ b/HMI.UI/Util/MsgBoxHelper.cs
@@ -2,6 +2,7 @@
using System.Windows;
using Panuon.WPF.UI.Configurations;
using HMI.Core.Util;
+using System;
namespace HMI.UI.Util
{
diff --git a/HMI.UI/Util/ToastHelper.cs b/HMI.UI/Util/ToastHelper.cs
index 90a409b..b578a76 100644
--- a/HMI.UI/Util/ToastHelper.cs
+++ b/HMI.UI/Util/ToastHelper.cs
@@ -1,6 +1,6 @@
锘縰sing HMI.Core.Util;
using Panuon.WPF.UI;
-using System.Runtime.CompilerServices;
+using System;
using System.Windows;
using System.Windows.Controls;
@@ -47,15 +47,18 @@
ToastPosition position = ToastPosition.Top, double offset = 0, int durationMs = 3000,
ToastWindow targetWindow = ToastWindow.ActiveWindow)
{
- var window = Application.Current.MainWindow;
- if (window is WindowX)
+ Application.Current.Dispatcher.BeginInvoke(new Action(() =>
{
- Instance.Success(window, message, icon, position, offset, durationMs, targetWindow);
- }
- else
- {
- MessageBox.Show(message, LangUtil.Get("App.Success"));
- }
+ var window = Application.Current.MainWindow;
+ if (window is WindowX)
+ {
+ Instance.Success(window, message, icon, position, offset, durationMs, targetWindow);
+ }
+ else
+ {
+ MessageBox.Show(message, LangUtil.Get("App.Success"));
+ }
+ }));
}
public static void Warning(string message,
@@ -63,15 +66,18 @@
ToastPosition position = ToastPosition.Top, double offset = 0, int durationMs = 3000,
ToastWindow targetWindow = ToastWindow.ActiveWindow)
{
- var window = Application.Current.MainWindow;
- if (window is WindowX)
+ Application.Current.Dispatcher.BeginInvoke(new Action(() =>
{
- Instance.Warning(window, message, icon, position, offset, durationMs, targetWindow);
- }
- else
- {
- MessageBox.Show(message, LangUtil.Get("App.Warn"));
- }
+ var window = Application.Current.MainWindow;
+ if (window is WindowX)
+ {
+ Instance.Warning(window, message, icon, position, offset, durationMs, targetWindow);
+ }
+ else
+ {
+ MessageBox.Show(message, LangUtil.Get("App.Warn"));
+ }
+ }));
}
public static void Error(string message,
@@ -79,16 +85,19 @@
ToastPosition position = ToastPosition.Top, double offset = 0, int durationMs = 3000,
ToastWindow targetWindow = ToastWindow.ActiveWindow)
{
- var window = Application.Current.MainWindow;
- if (window is WindowX)
+ Application.Current.Dispatcher.BeginInvoke(new Action(() =>
{
+ var window = Application.Current.MainWindow;
+ if (window is WindowX)
+ {
- Instance.Error(window, message, icon, position, offset, durationMs, targetWindow);
- }
- else
- {
- MessageBox.Show(message, LangUtil.Get("App.Error"));
- }
+ Instance.Error(window, message, icon, position, offset, durationMs, targetWindow);
+ }
+ else
+ {
+ MessageBox.Show(message, LangUtil.Get("App.Error"));
+ }
+ }));
}
public static void Info(string message,
@@ -96,16 +105,19 @@
ToastPosition position = ToastPosition.Top, double offset = 0, int durationMs = 3000,
ToastWindow targetWindow = ToastWindow.ActiveWindow)
{
- var window = Application.Current.MainWindow;
- if (window is WindowX)
+ Application.Current.Dispatcher.BeginInvoke(new Action(() =>
{
+ var window = Application.Current.MainWindow;
+ if (window is WindowX)
+ {
- Instance.Info(window, message, icon, position, offset, durationMs, targetWindow);
- }
- else
- {
- MessageBox.Show(message, LangUtil.Get("App.Info"));
- }
+ Instance.Info(window, message, icon, position, offset, durationMs, targetWindow);
+ }
+ else
+ {
+ MessageBox.Show(message, LangUtil.Get("App.Info"));
+ }
+ }));
}
diff --git a/HMI.UnitTest/HMI.UnitTest.csproj b/HMI.UnitTest/HMI.UnitTest.csproj
index ba07951..73dc3ae 100644
--- a/HMI.UnitTest/HMI.UnitTest.csproj
+++ b/HMI.UnitTest/HMI.UnitTest.csproj
@@ -155,10 +155,6 @@
<Project>{be42ab26-3270-43e1-84b8-6929d862ff8d}</Project>
<Name>Plugin.DataBoard</Name>
</ProjectReference>
- <ProjectReference Include="..\Plugin.TestBuilder\Plugin.TestBuilder.csproj">
- <Project>{30201ec1-9a82-48db-94b9-bd5c1190228b}</Project>
- <Name>Plugin.TestBuilder</Name>
- </ProjectReference>
<ProjectReference Include="..\Plugin.TestResult\Plugin.TestResult.csproj">
<Project>{7375b74c-b6bf-4814-9838-e1caacad1897}</Project>
<Name>Plugin.TestResult</Name>
@@ -167,6 +163,10 @@
<Project>{202d9a7b-96b3-4ad4-9977-fc4263207a02}</Project>
<Name>Plugin.TsExecution</Name>
</ProjectReference>
+ <ProjectReference Include="..\SimpleUtil\HMI.Simple.Util\HMI.Simple.Util.csproj">
+ <Project>{cf5bebe9-2803-49c3-b773-73d082e0984a}</Project>
+ <Name>HMI.Simple.Util</Name>
+ </ProjectReference>
</ItemGroup>
<ItemGroup>
<Folder Include="Entity\" />
diff --git a/HMI.UnitTest/MainWindow.xaml.cs b/HMI.UnitTest/MainWindow.xaml.cs
index d367685..a267a28 100644
--- a/HMI.UnitTest/MainWindow.xaml.cs
+++ b/HMI.UnitTest/MainWindow.xaml.cs
@@ -1,10 +1,10 @@
锘縰sing ConnectionUtil;
using HMI.Core.Api;
using HMI.Core.Util;
+using HMI.Simple.Util;
using log4net;
using Panuon.WPF.UI;
using Plugin.DataBoard;
-using Plugin.TestBuilder;
using Plugin.TestResult_WPF;
using Plugin.TsExecution;
using System;
@@ -22,6 +22,7 @@
private ILog log = LogManager.GetLogger("UnitTest");
public MainWindow()
{
+ ProductModelHelper.GetModelBySNR("cc123", out string model, out string msg);
LangUtil.Load();
InitializeComponent();
//page.Children.Add(new UserControl1());
@@ -33,13 +34,58 @@
private void Button_Click(object sender, RoutedEventArgs e)
{
+ Task.Run(() =>
+ {
+ for (int j = 0; j < 1000; j++)
+ {
+ string status = (j % 2 == 0) ? "Passed" : "Failed";
+ string d = (j % 2 == 0) ? "9" : "9999999999999999999999999999999999999999999999999999999999999999995";
+ tsExecution.AddTestData(0, $"ConnectivityCANRec,2,3,4,{d},6,{status}");
+ Thread.Sleep(5);
+ }
+ });
+
+ Task.Run(() =>
+ {
+ for (int j = 0; j < 1000; j++)
+ {
+ string status = (j % 2 == 0) ? "Passed" : "Failed";
+ string d = (j % 2 == 0) ? "9" : "9999999999999999999999999999999999999999999999999999999999999999995";
+ tsExecution.AddTestData(1, $"ConnectivityCANRec,2,3,4,{d},6,{status}");
+ Thread.Sleep(5);
+ }
+ });
+
+ Task.Run(() =>
+ {
+ for (int j = 0; j < 1000; j++)
+ {
+ string status = (j % 2 == 0) ? "Passed" : "Failed";
+ string d = (j % 2 == 0) ? "9" : "9999999999999999999999999999999999999999999999999999999999999999995";
+ tsExecution.AddTestData(2, $"ConnectivityCANRec,2,3,4,{d},6,{status}");
+ Thread.Sleep(5);
+ }
+ });
+
//Task.Run(() =>
//{
// for (int j = 0; j < 1000; j++)
// {
// string status = (j % 2 == 0) ? "Passed" : "Failed";
// string d = (j % 2 == 0) ? "9" : "9999999999999999999999999999999999999999999999999999999999999999995";
- // tsExecution.AddTestData(0, $"ConnectivityCANRec,2,3,4,{d},6,{status}");
+ // tsExecution.AddTestData(3, $"ConnectivityCANRec,2,3,4,{d},6,{status}");
+ // Thread.Sleep(5);
+ // }
+ //});
+
+ //Task.Run(() =>
+ //{
+ // for (int j = 0; j < 1000; j++)
+ // {
+ // string status = (j % 2 == 0) ? "Passed" : "Failed";
+ // string d = (j % 2 == 0) ? "9" : "9999999999999999999999999999999999999999999999999999999999999999995";
+ // tsExecution.AddTestData(1, $"ConnectivityCANRec,2,3,4,{d},6,{status}");
+ // Thread.Sleep(5);
// }
//});
@@ -160,7 +206,6 @@
private TsExecution tsExecution;
- private TestBuilder testBuilder;
private DataBoard dataBoard;
private void Window_Loaded(object sender, RoutedEventArgs e)
diff --git a/HMI.Util/ExcelHelper.cs b/HMI.Util/ExcelHelper.cs
index ee8f3fc..9e795dc 100644
--- a/HMI.Util/ExcelHelper.cs
+++ b/HMI.Util/ExcelHelper.cs
@@ -45,7 +45,7 @@
{
var attr = attrs[j];
var value = attr.IgnoreExport ? "" : properties[j].GetValue(datas[i]);
- rowTemp.CreateCell(j).SetCellValue(value.ToString());
+ rowTemp.CreateCell(j).SetCellValue(value?.ToString());
}
}
@@ -72,74 +72,86 @@
using (FileStream fileStream1 = new FileStream(sourcePath, FileMode.Open, FileAccess.Read))
{
IWorkbook workbook = null;
- if (sourcePath.EndsWith(".xlsx"))
- {
- workbook = new XSSFWorkbook(fileStream1);
- }
- else if (sourcePath.EndsWith(".xls"))
+ if (sourcePath.EndsWith(".xls"))
{
workbook = new HSSFWorkbook(fileStream1);
}
-
- ISheet sheet = workbook.GetSheetAt(0);
- IRow titleRow = sheet.GetRow(0);
-
- List<T> result = new List<T>();
- IRow row;
- for (int i = 1; i < (sheet.LastRowNum + 1); i++)
+ else
{
- row = sheet.GetRow(i);
- if (row != null)
- {
- T obj = (T)Activator.CreateInstance(type);
- bool isEmpty = true;
- for (int j = 0; j < row.Count(); j++)
- {
- string title = titleRow.GetCell(j).StringCellValue;
- if (dict.ContainsKey(title))
- {
- var cell = row.GetCell(j);
- if (cell == null || cell.CellType == CellType.Blank)
- continue;
- CellType ct = cell.CellType;
- object value = null;
- if (ct == CellType.String)
- value = row.GetCell(j).StringCellValue;
- else if (ct == CellType.Numeric)
- value = row.GetCell(j).NumericCellValue;
- else if (ct == CellType.Boolean)
- value = row.GetCell(j).BooleanCellValue;
-
- var prop = dict[title];
- if (prop.PropertyType == typeof(string))
- {
- value = Convert.ToString(value);
- }
- else if (prop.PropertyType == typeof(double) || prop.PropertyType == typeof(double?))
- {
- value = Convert.ToDouble(value);
- }
- else if (prop.PropertyType == typeof(int) || prop.PropertyType == typeof(int?))
- {
- value = Convert.ToInt16(value);
- }
- else if (prop.PropertyType == typeof(bool) || prop.PropertyType == typeof(bool?))
- {
- value = Convert.ToBoolean(value);
- }
- else if (prop.PropertyType.IsEnum)
- {
- value = Enum.Parse(prop.PropertyType, value.ToString());
- }
- prop.SetValue(obj, value);
- isEmpty = false;
- }
- }
- if (!isEmpty) result.Add(obj);
- }
+ workbook = new XSSFWorkbook(fileStream1);
}
- workbook.Close();
- return result;
+ int currentRow = 1;
+ try
+ {
+ ISheet sheet = workbook.GetSheetAt(0);
+ IRow titleRow = sheet.GetRow(0);
+
+ List<T> result = new List<T>();
+ IRow row;
+ for (currentRow = 1; currentRow < (sheet.LastRowNum + 1); currentRow++)
+ {
+ row = sheet.GetRow(currentRow);
+ if (row != null)
+ {
+ T obj = (T)Activator.CreateInstance(type);
+ bool isEmpty = true;
+ for (int j = 0; j < row.Count(); j++)
+ {
+ string title = titleRow.Cells[j].StringCellValue;
+ if (dict.ContainsKey(title))
+ {
+ var cell = row.GetCell(j);
+ if (cell == null || cell.CellType == CellType.Blank)
+ continue;
+ CellType ct = cell.CellType;
+ object value = null;
+ if (ct == CellType.String)
+ value = row.GetCell(j).StringCellValue;
+ else if (ct == CellType.Numeric)
+ value = row.GetCell(j).NumericCellValue;
+ else if (ct == CellType.Boolean)
+ value = row.GetCell(j).BooleanCellValue;
+ else
+ value = row.GetCell(j).StringCellValue;
+
+ var prop = dict[title];
+ if (prop.PropertyType == typeof(string))
+ {
+ value = Convert.ToString(value);
+ }
+ else if (prop.PropertyType == typeof(double) || prop.PropertyType == typeof(double?))
+ {
+ value = Convert.ToDouble(value);
+ }
+ else if (prop.PropertyType == typeof(int) || prop.PropertyType == typeof(int?))
+ {
+ value = Convert.ToInt16(value);
+ }
+ else if (prop.PropertyType == typeof(bool) || prop.PropertyType == typeof(bool?))
+ {
+ value = Convert.ToBoolean(value);
+ }
+ else if (prop.PropertyType.IsEnum)
+ {
+ value = Enum.Parse(prop.PropertyType, value.ToString());
+ }
+ prop.SetValue(obj, value);
+ isEmpty = false;
+ }
+ }
+ if (!isEmpty) result.Add(obj);
+ }
+ }
+ return result;
+ }
+ catch (Exception ex)
+ {
+ throw new Exception($"绗瑊currentRow}琛岃В鏋愰敊璇細{ex.Message}", ex);
+ }
+ finally
+ {
+ workbook.Close();
+ }
}
}
}
diff --git a/Plugin.ChangeModel/AssemblyInfo.cs b/Plugin.ChangeModel/AssemblyInfo.cs
new file mode 100644
index 0000000..cc29e7f
--- /dev/null
+++ b/Plugin.ChangeModel/AssemblyInfo.cs
@@ -0,0 +1,10 @@
+using System.Windows;
+
+[assembly:ThemeInfo(
+ ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
+ //(used if a resource is not found in the page,
+ // or application resource dictionaries)
+ ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
+ //(used if a resource is not found in the page,
+ // app, or any theme specific resource dictionaries)
+)]
diff --git a/Plugin.ChangeModel/ChangeModel.xaml b/Plugin.ChangeModel/ChangeModel.xaml
new file mode 100644
index 0000000..db63d92
--- /dev/null
+++ b/Plugin.ChangeModel/ChangeModel.xaml
@@ -0,0 +1,144 @@
+锘�<hb:SimpleMaskControl x:Class="Plugin.ChangeModel.ChangeModel"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:local="clr-namespace:Plugin.ChangeModel"
+ mc:Ignorable="d"
+ xmlns:hb="clr-namespace:HMI.Base;assembly=HMI.Base"
+ xmlns:uic="clr-namespace:HMI.UI.Converter;assembly=HMI.UI"
+ xmlns:pw="https://opensource.panuon.com/wpf"
+ xmlns:pu="https://opensource.panuon.com/wpf-ui"
+ xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
+ Loaded="SimpleControl_Loaded"
+ Style="{StaticResource simpleMaskControl}"
+ d:DesignHeight="450" d:DesignWidth="800">
+ <hb:SimpleMaskControl.Resources>
+ <ResourceDictionary>
+ <ResourceDictionary.MergedDictionaries>
+ <ResourceDictionary Source="/HMI.UI;component/Style/PanuonDataGrid.xaml"/>
+ </ResourceDictionary.MergedDictionaries>
+ </ResourceDictionary>
+ </hb:SimpleMaskControl.Resources>
+ <Border Style="{StaticResource CardBoarder}">
+ <Grid dp:GridHelper.Space="10" Cursor="">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition/>
+ </Grid.RowDefinitions>
+
+ <TextBlock FontSize="{StaticResource TitleFontSize}"
+VerticalAlignment="Center" HorizontalAlignment="Left" Text="{DynamicResource cm.title}"/>
+
+ <DockPanel Grid.Row="1" Cursor="">
+ <StackPanel DockPanel.Dock="Right" Style="{StaticResource ButtonGroup}">
+
+ <Button Style="{StaticResource RfhBtn}"
+ Content="{DynamicResource cm.rfhLog}"
+ x:Name="refreshLogBtn" Click="Button_Click"/>
+
+ <Button Style="{StaticResource DelBtn}" Content="{DynamicResource cm.clrLog}"
+ x:Name="deleteLogBtn" Click="Button_Click"/>
+
+ </StackPanel>
+
+ <StackPanel Style="{StaticResource ButtonGroup}" HorizontalAlignment="Left" dp:StackPanelHelper.ChildSpace="10">
+ <TextBlock Style="{StaticResource TitleBox}" FontSize="14" Text="{DynamicResource cm.lineName}"/>
+ <ComboBox Style="{StaticResource FormComboxStyle}" Width="180"
+ ItemsSource="{Binding LineNameSource}"
+ SelectedItem="{Binding CurrentLineName}"
+ SelectedValuePath="Content">
+ </ComboBox>
+
+ <TextBlock Style="{StaticResource TitleBox}" FontSize="14" Visibility="{Binding WorkOrderVisiable}"
+ Text="{DynamicResource cm.workorder}"/>
+ <ComboBox Style="{StaticResource FormComboxStyle}" Width="180"
+ Visibility="{Binding WorkOrderVisiable}"
+ ItemsSource="{Binding WorkorderSource}"
+ SelectedItem="{Binding CurrentWorkorder}" SelectedValuePath="Content">
+ </ComboBox>
+
+ <TextBlock Style="{StaticResource TitleBox}" FontSize="14" Text="{DynamicResource cm.productModel}"/>
+ <ComboBox Style="{StaticResource FormComboxStyle}" Width="180"
+ ItemsSource="{Binding ProductModelSource}"
+ SelectedItem="{Binding CurrentProductModel}" SelectedValuePath="Content">
+ </ComboBox>
+
+ <Button Style="{StaticResource EditBtn}" x:Name="changeModelBtn" Content="{DynamicResource cm.cm}"
+ Click="Button_Click"/>
+ <Button Style="{StaticResource RfhBtn}" Content="{DynamicResource cm.rfhInfo}" x:Name="refreshInfoBtn"
+ Click="Button_Click"/>
+ </StackPanel>
+ </DockPanel>
+
+ <DataGrid Grid.Row="2" x:Name="table" Style="{StaticResource DefaultDataGrid}">
+ <DataGrid.RowStyle>
+ <Style TargetType="DataGridRow" BasedOn="{StaticResource {x:Static pu:StyleKeys.DataGridRowStyle}}">
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding level}" Value="Warn">
+ <Setter Property="Background" Value="{StaticResource WarningColor}"/>
+ <Setter Property="Foreground" Value="Black"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding level}" Value="Error">
+ <Setter Property="Background" Value="{StaticResource DangerColor}"/>
+ <Setter Property="Foreground" Value="Black"/>
+ </DataTrigger>
+ <Trigger Property="IsSelected" Value="True">
+ <Setter Property="Background" Value="Transparent"/>
+ </Trigger>
+ <Trigger Property="IsMouseOver" Value="True">
+ <Setter Property="Background" Value="Transparent"/>
+ </Trigger>
+ </Style.Triggers>
+ </Style>
+ </DataGrid.RowStyle>
+ <DataGrid.Columns>
+ <DataGridTemplateColumn Header="#" CanUserResize="False">
+ <DataGridTemplateColumn.CellTemplate>
+ <DataTemplate>
+ <TextBlock Text="{Binding Converter={StaticResource rowNumber},
+ RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGridRow},AncestorLevel=1}}"/>
+ </DataTemplate>
+ </DataGridTemplateColumn.CellTemplate>
+ </DataGridTemplateColumn>
+ <DataGridTextColumn Width="*" Binding="{Binding LineName}">
+ <DataGridTextColumn.Header>
+ <TextBlock Text="{DynamicResource cm.lineName}"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>
+ <DataGridTextColumn Width="*" Binding="{Binding ProductModel}">
+ <DataGridTextColumn.Header>
+ <TextBlock Text="{DynamicResource cm.productModel}"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>
+ <DataGridTextColumn Width="*" Binding="{Binding CustomProperty}">
+ <DataGridTextColumn.Header>
+ <TextBlock Text="{DynamicResource cm.customProperty}"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>
+ <!--<DataGridTextColumn Width="*" Binding="{Binding Workstation}">
+ <DataGridTextColumn.Header>
+ <TextBlock Text="{DynamicResource cm.workstation}"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>-->
+ <DataGridTextColumn Width="*" Binding="{Binding ChangeTime}">
+ <DataGridTextColumn.Header>
+ <TextBlock Text="{DynamicResource cm.changeTime}"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>
+ <DataGridTextColumn Width="*" Binding="{Binding ChangeResult}">
+ <DataGridTextColumn.Header>
+ <TextBlock Text="{DynamicResource cm.changeResult}"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>
+ <DataGridTextColumn Width="*" Binding="{Binding Info}">
+ <DataGridTextColumn.Header>
+ <TextBlock Text="{DynamicResource cm.info}"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>
+ </DataGrid.Columns>
+ </DataGrid>
+ </Grid>
+ </Border>
+</hb:SimpleMaskControl>
diff --git a/Plugin.ChangeModel/ChangeModel.xaml.cs b/Plugin.ChangeModel/ChangeModel.xaml.cs
new file mode 100644
index 0000000..9bab845
--- /dev/null
+++ b/Plugin.ChangeModel/ChangeModel.xaml.cs
@@ -0,0 +1,430 @@
+锘縰sing CommunityToolkit.Mvvm.ComponentModel;
+using HMI.Base;
+using HMI.Core.Entity;
+using HMI.Core.Manager;
+using HMI.Core.Util;
+using HMI.UI.Util;
+using LSMSInterface;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using Plugin.ChangeModel.Entity;
+using System.Collections.ObjectModel;
+using System.Data;
+using System.IO;
+using System.Windows;
+using System.Windows.Controls;
+
+namespace Plugin.ChangeModel
+{
+ /// <summary>
+ /// ChangeModel.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ [ObservableObject]
+ public partial class ChangeModel : SimpleMaskControl
+ {
+ public ChangeModel()
+ {
+ api = new LSMSApi();
+ DataContext = this;
+ InitializeComponent();
+ }
+
+ [ObservableProperty]
+ private ObservableCollection<CmLogData> datasource;
+
+ [ObservableProperty]
+ private ObservableCollection<string> lineNameSource;
+
+ [ObservableProperty]
+ private ObservableCollection<string> workorderSource;
+
+ [ObservableProperty]
+ private ObservableCollection<string> productModelSource;
+
+ [ObservableProperty]
+ private string currentLineName;
+ [ObservableProperty]
+ private string currentWorkorder;
+ [ObservableProperty]
+ private string currentProductModel;
+ [ObservableProperty]
+ private Visibility workOrderVisiable = Visibility.Collapsed;
+
+ private string configLineName;
+ private string mesIp;
+ private int mesPort;
+ private LSMSApi api;
+ private bool isMesConnected = false;
+ private SqliteHelper sqliteHelper;
+
+ public void ConnectMes()
+ {
+ string msg = string.Empty;
+ try
+ {
+ if (api.Connect(this.mesIp, this.mesPort, ref msg))
+ {
+ isMesConnected = true;
+ }
+ else
+ {
+ throw new Exception(msg);
+ }
+ }
+ catch (Exception ex)
+ {
+ isMesConnected = false;
+ log.Error("ConnectMes Failed.", ex);
+ MsgBoxHelper.Error(Window.GetWindow(this), this.lang("cm.mesConnectFail", ex.Message));
+ }
+ }
+
+ public override void InitFinish()
+ {
+ base.InitFinish();
+ ParameterData parameter;
+ try
+ {
+ parameter = ParameterManager.GetCommonParameterByName("MesIp");
+ mesIp = parameter.Value;
+ }
+ catch
+ {
+ mesIp = "127.0.0.1";
+ }
+ try
+ {
+ parameter = ParameterManager.GetCommonParameterByName("MesPort");
+ mesPort = int.Parse(parameter.Value);
+ }
+ catch
+ {
+ mesPort = 9909;
+ }
+
+ try
+ {
+ parameter = ParameterManager.GetCommonParameterByName("ChangeModelByWorkOrder");
+ var res = bool.Parse(parameter.Value);
+ if (res) WorkOrderVisiable = Visibility.Visible;
+ }
+ catch
+ {
+ WorkOrderVisiable = Visibility.Collapsed;
+ }
+
+ try
+ {
+ var dbPath = Path.Combine(BaseFolder, "ChangeModel.db");
+ if (!File.Exists(dbPath))
+ {
+ SqliteHelper.CreateDatabase(dbPath);
+ }
+ sqliteHelper = new SqliteHelper(dbPath);
+ sqliteHelper.ExecuteSql(@"CREATE TABLE IF NOT EXISTS change_model_record (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ lineName TEXT NOT NULL,
+ workOrder TEXT,
+ productModel TEXT NOT NULL,
+ customProperty TEXT,
+ changeTime TIME,
+ changeResult TEXT,
+ info TEXT);");
+ }
+ catch (Exception ex)
+ {
+ log.Error("Init ChangeModel DB Failed.", ex);
+ }
+ }
+
+ public override void Active()
+ {
+ base.Active();
+ if (!isMesConnected)
+ {
+ ConnectMes();
+ RefreshLineNameSource();
+ }
+ }
+
+ public override void DoClose(object sender, EventArgs e)
+ {
+ try
+ {
+ sqliteHelper?.Dispose();
+ string errMsg = string.Empty;
+ api?.DisConnect(ref errMsg);
+ base.DoClose(sender, e);
+ }
+ catch {
+ }
+ }
+
+ private void RefreshLineNameSource()
+ {
+ try
+ {
+ if (PingMes(out string errMsg))
+ {
+ string lineStr = api.GetAllLine();
+ JObject job = (JObject)JsonConvert.DeserializeObject(lineStr);
+ LineNameSource = new ObservableCollection<string>(job["ProductLines"].ToString().Split(','));
+ try
+ {
+ var parameter = ParameterManager.GetCommonParameterByName("LineName");
+ configLineName = parameter.Value;
+ CurrentLineName = parameter.Value;
+ }
+ catch
+ {
+
+ }
+ }
+ else
+ {
+ throw new Exception(errMsg);
+ }
+ }
+ catch (Exception ex)
+ {
+ log.Error("RefreshLineNameSource Failed.", ex);
+ MsgBoxHelper.ErrorMessage(Window.GetWindow(this), this.lang("cm.rfhLineNameFail", ex.Message));
+ }
+ }
+
+ private void RefreshWorkOrderByLineName(string lineName)
+ {
+ try
+ {
+ if (PingMes(out string errMsg))
+ {
+ string workOrderStr = api.GetWorkOrderByLineName(lineName, out errMsg);
+ if (string.IsNullOrEmpty(errMsg))
+ {
+ JObject res = (JObject)JsonConvert.DeserializeObject(workOrderStr);
+ JArray workOrders = (JArray)res["Data"];
+ WorkorderSource = new ObservableCollection<string>(workOrders.Select(j => j["Code"].ToString()).ToArray());
+ }
+
+ string infoStr = api.GetProductInfoByLineName(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.FFF"), lineName, out errMsg);
+ if (string.IsNullOrEmpty(errMsg))
+ {
+ JObject job = JsonConvert.DeserializeObject(infoStr) as JObject;
+ CurrentWorkorder = job["Order"]?.ToString();
+ }
+ }
+ else
+ {
+ throw new Exception(errMsg);
+ }
+ }
+ catch (Exception ex)
+ {
+ log.Error("RefreshWorkOrderByLineName Failed.", ex);
+ MsgBoxHelper.ErrorMessage(Window.GetWindow(this), this.lang("cm.rfhWorkOrderFail", ex.Message));
+ }
+ }
+
+ private void RefreshProductByLineName(string lineName)
+ {
+ try
+ {
+ if (PingMes(out string errMsg))
+ {
+ string workOrderStr = api.GetProductsByLineName(lineName, out string ErrMsg);
+ if (string.IsNullOrEmpty(errMsg))
+ {
+ JObject res = (JObject)JsonConvert.DeserializeObject(workOrderStr);
+ JArray arr = res["Products"] as JArray;
+ ProductModelSource = new ObservableCollection<string>(arr.Select(j => j["model"].ToString()).ToArray());
+ }
+
+ string lineStr = api.GetProductInfoByLineName(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.FFF"), lineName, out errMsg);
+ if (string.IsNullOrEmpty(errMsg))
+ {
+ JObject job = (JObject)JsonConvert.DeserializeObject(lineStr);
+ CurrentProductModel = job["Model"]?.ToString();
+ }
+ }
+ else
+ {
+ throw new Exception(errMsg);
+ }
+ }
+ catch (Exception ex)
+ {
+ log.Error("RefreshProductByLineName Failed.", ex);
+ MsgBoxHelper.ErrorMessage(Window.GetWindow(this), this.lang("cm.rfhModelFail", ex.Message));
+ }
+ }
+
+ private void MesChangeModel()
+ {
+ ShowMask(() =>
+ {
+ if (PingMes(out string errMsg))
+ {
+ var info = new Dictionary<string, object>() {
+ { "Model",CurrentProductModel}
+ };
+ if (WorkOrderVisiable == Visibility.Visible)
+ {
+ info["Order"] = CurrentWorkorder;
+ }
+ if (!api.ChangeModel2(CurrentLineName, info, out errMsg))
+ {
+ throw new Exception(errMsg);
+ }
+ sqliteHelper.ExecuteSql($@"INSERT INTO change_model_record (lineName, workOrder,productModel, customProperty,
+changeTime,changeResult,info) Values
+('{CurrentLineName}','{CurrentWorkorder}','{CurrentProductModel}',NULL,'{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.FFF")}', 'OK', NULL)");
+ RefreshLog();
+ if (!api.RefreshCache(out errMsg))
+ {
+ throw new Exception($"Refresh MES Cache Failed.: {errMsg}");
+ }
+ ToastHelper.Success("鎹㈠瀷鎴愬姛");
+ }
+ else
+ {
+ throw new Exception(errMsg);
+ }
+ },
+ (ex) =>
+ {
+ log.Error("MesChangeModel Failed.", ex);
+ MsgBoxHelper.ErrorMessage(Window.GetWindow(this), this.lang("cm.changeFail", ex.Message));
+ }, "璇风◢鍚�", "鎹㈠瀷涓�...");
+ }
+
+
+
+ private bool PingMes(out string errMsg)
+ {
+ errMsg = string.Empty;
+ if (!isMesConnected)
+ {
+ errMsg = "MES鏈繛鎺ワ紝璇峰厛杩炴帴MES";
+ return false;
+ }
+ try
+ {
+ if (!api.IsConnect(ref errMsg))
+ {
+ isMesConnected = false;
+ return false;
+ }
+ return true;
+ }
+ catch (Exception ex)
+ {
+ errMsg = ex.Message;
+ isMesConnected = false;
+ return false;
+ }
+ }
+
+ private void RefreshLog()
+ {
+ try
+ {
+ DataTable dt = sqliteHelper.GetDataTable(@"SELECT lineName AS LineName
+,productModel AS ProductModel
+,customProperty AS CustomProperty
+,changeTime AS ChangeTime
+,changeResult AS ChangeResult
+,info AS Info
+FROM change_model_record order by changeTime desc limit 100;");
+ this.Dispatcher.BeginInvoke((Action)delegate ()
+ {
+ table.ItemsSource = dt.DefaultView;
+ });
+ }
+ catch (Exception ex)
+ {
+ log.Error("Refresh ChangeModel Log Failed.", ex);
+ ToastHelper.Error(this.lang("cm.rfhLogFail", ex.Message));
+ }
+ }
+
+ partial void OnCurrentLineNameChanged(string lineName)
+ {
+ RefreshWorkOrderByLineName(lineName);
+ RefreshProductByLineName(lineName);
+ }
+
+
+ private void Button_Click(object sender, RoutedEventArgs e)
+ {
+ switch ((sender as Button).Name)
+ {
+ case "changeModelBtn":
+ DoChangeModel();
+ break;
+ case "refreshLogBtn":
+ ShowMask(RefreshLog, null, "璇风◢鍚�", "姝e湪鍒锋柊...");
+ break;
+ case "refreshInfoBtn":
+ RefreshInfo();
+ break;
+ case "deleteLogBtn":
+ DeleteLog();
+ break;
+ default:
+ break;
+ }
+ }
+
+ private void DeleteLog()
+ {
+ if (MsgBoxHelper.WarnMessage(this, this.lang("cm.makeSureDelLog")) != MessageBoxResult.OK)
+ {
+ return;
+ }
+ ShowMask(() =>
+ {
+ try
+ {
+ sqliteHelper.ExecuteSql($@"DELETE FROM change_model_record WHERE ID NOT IN
+(SELECT id FROM change_model_record Order by changeTime DESC limit 10);");
+ RefreshLog();
+ }
+ catch (Exception ex)
+ {
+ log.Error("DeleteLog Failed.", ex);
+ ToastHelper.Error(this.lang("cm.delLogFail", ex.Message));
+ }
+ }, null, "璇风◢鍚�", "姝e湪娓呯悊...");
+ }
+
+ private void RefreshInfo()
+ {
+ try
+ {
+ RefreshLineNameSource();
+ RefreshWorkOrderByLineName(CurrentLineName);
+ RefreshProductByLineName(CurrentLineName);
+ }
+ catch (Exception ex)
+ {
+ log.Error("Refresh Info Failed.", ex);
+ ToastHelper.Error(this.lang("cm.rfhInfoErr", ex.Message));
+ }
+ }
+
+ private void DoChangeModel()
+ {
+ if (string.IsNullOrEmpty(CurrentLineName) || string.IsNullOrEmpty(CurrentProductModel)) return;
+ if (MsgBoxHelper.WarnMessage(this, this.lang("cm.makeSureChangeModel")) != MessageBoxResult.OK)
+ {
+ return;
+ }
+ MesChangeModel();
+ }
+
+ private void SimpleControl_Loaded(object sender, RoutedEventArgs e)
+ {
+ RefreshLog();
+ }
+ }
+}
diff --git a/Plugin.ChangeModel/Entity/CmLogData.cs b/Plugin.ChangeModel/Entity/CmLogData.cs
new file mode 100644
index 0000000..2e03437
--- /dev/null
+++ b/Plugin.ChangeModel/Entity/CmLogData.cs
@@ -0,0 +1,13 @@
+锘縩amespace Plugin.ChangeModel.Entity
+{
+ public class CmLogData
+ {
+ public string LineName { get; set; }
+ public string ProductModel { get; set; }
+ public string CustomProperty { get; set; }
+ public string Workstation { get; set; }
+ public DateTime ChangeTime { get; set; }
+ public string ChangeResult { get; set; }
+ public string Info { get; set; }
+ }
+}
diff --git a/Plugin.ChangeModel/Entity/ModelData.cs b/Plugin.ChangeModel/Entity/ModelData.cs
new file mode 100644
index 0000000..2bfe432
--- /dev/null
+++ b/Plugin.ChangeModel/Entity/ModelData.cs
@@ -0,0 +1,13 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Plugin.ChangeModel.Entity
+{
+ public class ModelData
+ {
+ public string Model { get; set; }
+ }
+}
diff --git a/Plugin.ChangeModel/Entity/WorkOrderData.cs b/Plugin.ChangeModel/Entity/WorkOrderData.cs
new file mode 100644
index 0000000..3384765
--- /dev/null
+++ b/Plugin.ChangeModel/Entity/WorkOrderData.cs
@@ -0,0 +1,7 @@
+锘縩amespace Plugin.ChangeModel.Entity
+{
+ public class WorkOrderData
+ {
+ public string Code { get; set; }
+ }
+}
diff --git a/Plugin.ChangeModel/Plugin.ChangeModel.csproj b/Plugin.ChangeModel/Plugin.ChangeModel.csproj
new file mode 100644
index 0000000..c85ac8f
--- /dev/null
+++ b/Plugin.ChangeModel/Plugin.ChangeModel.csproj
@@ -0,0 +1,27 @@
+锘�<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <OutputType>Library</OutputType>
+ <TargetFramework>net472</TargetFramework>
+ <Nullable>enable</Nullable>
+ <LangVersion>10.0</LangVersion>
+ <ImplicitUsings>enable</ImplicitUsings>
+ <UseWPF>true</UseWPF>
+ <Platforms>AnyCPU;x64</Platforms>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
+ <PackageReference Include="log4net" Version="3.0.4" />
+ <PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.135" />
+ <PackageReference Include="Panuon.WPF.UI" Version="1.3.0.2" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\..\MesApi\lmes.csproj" />
+ <ProjectReference Include="..\HMI.Base\HMI.Base.csproj" />
+ <ProjectReference Include="..\HMI.Core\HMI.Core.csproj" />
+ <ProjectReference Include="..\HMI.UI\HMI.UI.csproj" />
+ </ItemGroup>
+
+</Project>
diff --git a/Plugin.DOControl/DOControl.xaml b/Plugin.DOControl/DOControl.xaml
index 2df075e..db18129 100644
--- a/Plugin.DOControl/DOControl.xaml
+++ b/Plugin.DOControl/DOControl.xaml
@@ -3,13 +3,13 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:hb="clr-namespace:HMI.Base;assembly=HMI.Base"
xmlns:local="clr-namespace:Plugin.DOControl"
+ mc:Ignorable="d"
+ xmlns:hb="clr-namespace:HMI.Base;assembly=HMI.Base"
xmlns:uic="clr-namespace:HMI.UI.Converter;assembly=HMI.UI"
xmlns:pw="https://opensource.panuon.com/wpf"
xmlns:pu="https://opensource.panuon.com/wpf-ui"
xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
- mc:Ignorable="d"
Loaded="UserControl_Loaded"
Background="{StaticResource WorkspaceBackground}"
d:DesignHeight="450" d:DesignWidth="800">
diff --git a/Plugin.DOControl/DOControl.xaml.cs b/Plugin.DOControl/DOControl.xaml.cs
index b5e1924..405c4ff 100644
--- a/Plugin.DOControl/DOControl.xaml.cs
+++ b/Plugin.DOControl/DOControl.xaml.cs
@@ -5,6 +5,7 @@
using HMI.UI;
using HMI.UI.Util;
using log4net;
+using OPCConnection;
using Panuon.WPF.UI;
using Plugin.DOControl.Entity;
using System;
@@ -26,8 +27,8 @@
/// <summary>
/// 瀹炰緥鍖栨湇鍔″櫒鎺ュ彛鍑芥暟
/// </summary>
- //private OpcInterface.OpcInterface lTSCADAApi = new OpcInterface.OpcInterface();
- private PipeClient pipeClient = new PipeClient("DAService");
+ private SCADAApi lTSCADAApi = new OPCClient();
+ //private PipeClient pipeClient = new PipeClient("DAService");
private ObservableCollection<string> groups;
public ObservableCollection<string> Groups
@@ -99,8 +100,14 @@
public override void DoClose(object sender, EventArgs e)
{
- motorMonitorTimer.Enabled = false;
- base.DoClose(sender, e);
+ try
+ {
+
+ motorMonitorTimer.Enabled = false;
+ base.DoClose(sender, e);
+ }
+ catch {
+ }
}
public static string FilePath { get; private set; }
@@ -376,24 +383,24 @@
/// <param name="value">鍊�</param>
private void SetPlcValue(string key, string value)
{
- //if (!lTSCADAApi.DoFctWriteSingle(key, value, out string errMsg))
- //{
- // ToastHelper.Error(this, errMsg);
- //}
+ if (!lTSCADAApi.DoFctWriteSingle(key, value, out string errMsg))
+ {
+ ToastHelper.Error(this, errMsg);
+ }
- pipeClient.SendMessage("asdsadasda", out _);
+ //lTSCADAApi.SendMessage("asdsadasda", out _);
}
private string GetPlcValue(string key)
{
- //if (lTSCADAApi.DoFctReadSingle(key, out string Val, out string errMsg))
- //{
- // return Val;
- //}
- //else
- //{
- // return null;
- //}
+ if (lTSCADAApi.DoFctReadSingle(key, out string Val, out string errMsg))
+ {
+ return Val;
+ }
+ else
+ {
+ return null;
+ }
return null;
}
@@ -450,25 +457,25 @@
LoadData();
if (SystemSetting.Instance.PlcEnabled)
{
- //if (lTSCADAApi.Connect2("127.0.0.1", 6543, 18888, out string errMsg))
- //{
- // motorMonitorTimer.Enabled = true;
- // RefreshControl();
- //}
- //else
- //{
- // MsgBoxHelper2.Error(errMsg);
- //}
- try
+ if (lTSCADAApi.Connect2("127.0.0.1", 6543, 28888, out string errMsg))
{
- pipeClient.OnConnected += PipeClient_OnConnected;
+ motorMonitorTimer.Enabled = true;
+ RefreshControl();
+ }
+ else
+ {
+ MsgBoxHelper2.Error(errMsg);
+ }
+ //try
+ //{
+ // pipeClient.OnConnected += PipeClient_OnConnected;
- pipeClient.Connect();
- }
- catch (Exception ex)
- {
- MsgBoxHelper.Error(this, ex.Message);
- }
+ // pipeClient.Connect();
+ //}
+ //catch (Exception ex)
+ //{
+ // MsgBoxHelper.Error(this, ex.Message);
+ //}
}
Loaded -= UserControl_Loaded;
}
diff --git a/Plugin.DOControl/Plugin.DOControl.csproj b/Plugin.DOControl/Plugin.DOControl.csproj
index c380687..0d99dca 100644
--- a/Plugin.DOControl/Plugin.DOControl.csproj
+++ b/Plugin.DOControl/Plugin.DOControl.csproj
@@ -145,6 +145,10 @@
<Project>{afea100a-9223-448d-ab10-3015d93dd98c}</Project>
<Name>HMI.Util</Name>
</ProjectReference>
+ <ProjectReference Include="..\OPCClient\OPCClient.csproj">
+ <Project>{E5740BB5-9FC6-4A20-B7C2-CC90C281ED05}</Project>
+ <Name>OPCClient</Name>
+ </ProjectReference>
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
diff --git a/Plugin.DODriverControl/Api/Dask.cs b/Plugin.DODriverControl/Api/Dask.cs
new file mode 100644
index 0000000..a77f6bf
--- /dev/null
+++ b/Plugin.DODriverControl/Api/Dask.cs
@@ -0,0 +1,801 @@
+using System.Runtime.InteropServices;
+
+namespace Plugin.DODriverControl.Api;
+
+public delegate void CallbackDelegate();
+
+public class DASK
+{
+ //ADLink PCI Card Type
+ public const ushort PCI_6208V =1;
+ public const ushort PCI_6208A =2;
+ public const ushort PCI_6308V =3;
+ public const ushort PCI_6308A =4;
+ public const ushort PCI_7200 =5;
+ public const ushort PCI_7230 =6;
+ public const ushort PCI_7233 =7;
+ public const ushort PCI_7234 =8;
+ public const ushort PCI_7248 =9;
+ public const ushort PCI_7249 =10;
+ public const ushort PCI_7250 =11;
+ public const ushort PCI_7252 =12;
+ public const ushort PCI_7296 =13;
+ public const ushort PCI_7300A_RevA =14;
+ public const ushort PCI_7300A_RevB =15;
+ public const ushort PCI_7432 =16;
+ public const ushort PCI_7433 =17;
+ public const ushort PCI_7434 =18;
+ public const ushort PCI_8554 =19;
+ public const ushort PCI_9111DG =20;
+ public const ushort PCI_9111HR =21;
+ public const ushort PCI_9112 =22;
+ public const ushort PCI_9113 =23;
+ public const ushort PCI_9114DG =24;
+ public const ushort PCI_9114HG =25;
+ public const ushort PCI_9118DG =26;
+ public const ushort PCI_9118HG =27;
+ public const ushort PCI_9118HR =28;
+ public const ushort PCI_9810 =29;
+ public const ushort PCI_9812 =30;
+ public const ushort PCI_7396 =31;
+ public const ushort PCI_9116 =32;
+ public const ushort PCI_7256 =33;
+ public const ushort PCI_7258 =34;
+ public const ushort PCI_7260 =35;
+ public const ushort PCI_7452 =36;
+ public const ushort PCI_7442 =37;
+
+ public const ushort MAX_CARD =32;
+
+//Error Number
+ public const short NoError =0;
+ public const short ErrorUnknownCardType =-1;
+ public const short ErrorInvalidCardNumber =-2;
+ public const short ErrorTooManyCardRegistered =-3;
+ public const short ErrorCardNotRegistered =-4;
+ public const short ErrorFuncNotSupport =-5;
+ public const short ErrorInvalidIoChannel =-6;
+ public const short ErrorInvalidAdRange =-7;
+ public const short ErrorContIoNotAllowed =-8;
+ public const short ErrorDiffRangeNotSupport =-9;
+ public const short ErrorLastChannelNotZero =-10;
+ public const short ErrorChannelNotDescending =-11;
+ public const short ErrorChannelNotAscending =-12;
+ public const short ErrorOpenDriverFailed =-13;
+ public const short ErrorOpenEventFailed =-14;
+ public const short ErrorTransferCountTooLarge =-15;
+ public const short ErrorNotDoubleBufferMode =-16;
+ public const short ErrorInvalidSampleRate =-17;
+ public const short ErrorInvalidCounterMode =-18;
+ public const short ErrorInvalidCounter =-19;
+ public const short ErrorInvalidCounterState =-20;
+ public const short ErrorInvalidBinBcdParam =-21;
+ public const short ErrorBadCardType =-22;
+ public const short ErrorInvalidDaRefVoltage =-23;
+ public const short ErrorAdTimeOut =-24;
+ public const short ErrorNoAsyncAI =-25;
+ public const short ErrorNoAsyncAO =-26;
+ public const short ErrorNoAsyncDI =-27;
+ public const short ErrorNoAsyncDO =-28;
+ public const short ErrorNotInputPort =-29;
+ public const short ErrorNotOutputPort =-30;
+ public const short ErrorInvalidDioPort =-31;
+ public const short ErrorInvalidDioLine =-32;
+ public const short ErrorContIoActive =-33;
+ public const short ErrorDblBufModeNotAllowed =-34;
+ public const short ErrorConfigFailed =-35;
+ public const short ErrorInvalidPortDirection =-36;
+ public const short ErrorBeginThreadError =-37;
+ public const short ErrorInvalidPortWidth =-38;
+ public const short ErrorInvalidCtrSource =-39;
+ public const short ErrorOpenFile =-40;
+ public const short ErrorAllocateMemory =-41;
+ public const short ErrorDaVoltageOutOfRange =-42;
+ public const short ErrorDaExtRefNotAllowed =-43;
+ public const short ErrorDIODataWidthError =-44;
+ public const short ErrorTaskCodeError =-45;
+ public const short ErrortriggercountError =-46;
+ public const short ErrorInvalidTriggerMode =-47;
+ public const short ErrorInvalidTriggerType =-48;
+ public const short ErrorInvalidCounterValue =-50;
+ public const short ErrorInvalidEventHandle =-60;
+ public const short ErrorNoMessageAvailable =-61;
+ public const short ErrorEventMessgaeNotAdded =-62;
+//Error number for driver API
+ public const short ErrorConfigIoctl =-201;
+ public const short ErrorAsyncSetIoctl =-202;
+ public const short ErrorDBSetIoctl =-203;
+ public const short ErrorDBHalfReadyIoctl =-204;
+ public const short ErrorContOPIoctl =-205;
+ public const short ErrorContStatusIoctl =-206;
+ public const short ErrorPIOIoctl =-207;
+ public const short ErrorDIntSetIoctl =-208;
+ public const short ErrorWaitEvtIoctl =-209;
+ public const short ErrorOpenEvtIoctl =-210;
+ public const short ErrorCOSIntSetIoctl =-211;
+ public const short ErrorMemMapIoctl =-212;
+ public const short ErrorMemUMapSetIoctl =-213;
+ public const short ErrorCTRIoctl =-214;
+ public const short ErrorGetResIoctl =-215;
+
+//Synchronous Mode
+ public const ushort SYNCH_OP =1;
+ public const ushort ASYNCH_OP =2;
+
+//AD Range
+ public const ushort AD_B_10_V =1;
+ public const ushort AD_B_5_V =2;
+ public const ushort AD_B_2_5_V =3;
+ public const ushort AD_B_1_25_V =4;
+ public const ushort AD_B_0_625_V =5;
+ public const ushort AD_B_0_3125_V =6;
+ public const ushort AD_B_0_5_V =7;
+ public const ushort AD_B_0_05_V =8;
+ public const ushort AD_B_0_005_V =9;
+ public const ushort AD_B_1_V =10;
+ public const ushort AD_B_0_1_V =11;
+ public const ushort AD_B_0_01_V =12;
+ public const ushort AD_B_0_001_V =13;
+ public const ushort AD_U_20_V =14;
+ public const ushort AD_U_10_V =15;
+ public const ushort AD_U_5_V =16;
+ public const ushort AD_U_2_5_V =17;
+ public const ushort AD_U_1_25_V =18;
+ public const ushort AD_U_1_V =19;
+ public const ushort AD_U_0_1_V =20;
+ public const ushort AD_U_0_01_V =21;
+ public const ushort AD_U_0_001_V =22;
+
+//Clock Mode
+ public const ushort TRIG_SOFTWARE =0;
+ public const ushort TRIG_INT_PACER =1;
+ public const ushort TRIG_EXT_STROBE =2;
+ public const ushort TRIG_HANDSHAKE =3;
+ public const ushort TRIG_CLK_10MHZ =4; //PCI-7300A
+ public const ushort TRIG_CLK_20MHZ =5; //PCI-7300A
+ public const ushort TRIG_DO_CLK_TIMER_ACK =6; //PCI-7300A Rev. B
+ public const ushort TRIG_DO_CLK_10M_ACK =7; //PCI-7300A Rev. B
+ public const ushort TRIG_DO_CLK_20M_ACK =8; //PCI-7300A Rev. B
+//Virtual Sampling Rate for using external clock as the clock source
+ public const double CLKSRC_EXT_SampRate =10000;
+
+//-------- Constants for PCI-6208A/PCI-6308A/PCI-6308V -------------------
+//Output Mode
+ public const ushort P6208_CURRENT_0_20MA =0;
+ public const ushort P6208_CURRENT_4_20MA =3;
+ public const ushort P6208_CURRENT_5_25MA =1;
+ public const ushort P6308_CURRENT_0_20MA =0;
+ public const ushort P6308_CURRENT_4_20MA =3;
+ public const ushort P6308_CURRENT_5_25MA =1;
+//AO Setting
+ public const ushort P6308V_AO_CH0_3 =0;
+ public const ushort P6308V_AO_CH4_7 =1;
+ public const ushort P6308V_AO_UNIPOLAR =0;
+ public const ushort P6308V_AO_BIPOLAR =1;
+//-------- Constants for PCI-7200 --------------------
+//InputMode
+ public const ushort DI_WAITING =0x02;
+ public const ushort DI_NOWAITING =0x00;
+
+ public const ushort DI_TRIG_RISING =0x04;
+ public const ushort DI_TRIG_FALLING =0x00;
+
+ public const ushort IREQ_RISING =0x08;
+ public const ushort IREQ_FALLING =0x00;
+
+//Output Mode
+ public const ushort OREQ_ENABLE =0x10;
+ public const ushort OREQ_DISABLE =0x00;
+
+ public const ushort OTRIG_HIGH =0x20;
+ public const ushort OTRIG_LOW =0x00;
+
+//-------- Constants for PCI-7248/7296/7396/7442 ---------------
+//DIO Port Direction
+ public const ushort INPUT_PORT = 1;
+ public const ushort OUTPUT_PORT = 2;
+//DIO Line Direction
+ public const ushort INPUT_LINE = 1;
+ public const ushort OUTPUT_LINE = 2;
+
+//Channel & Port
+ public const ushort Channel_P1A =0;
+ public const ushort Channel_P1B =1;
+ public const ushort Channel_P1C =2;
+ public const ushort Channel_P1CL =3;
+ public const ushort Channel_P1CH =4;
+ public const ushort Channel_P1AE =10;
+ public const ushort Channel_P1BE =11;
+ public const ushort Channel_P1CE =12;
+ public const ushort Channel_P2A =5;
+ public const ushort Channel_P2B =6;
+ public const ushort Channel_P2C =7;
+ public const ushort Channel_P2CL =8;
+ public const ushort Channel_P2CH =9;
+ public const ushort Channel_P2AE =15;
+ public const ushort Channel_P2BE =16;
+ public const ushort Channel_P2CE =17;
+ public const ushort Channel_P3A =10;
+ public const ushort Channel_P3B =11;
+ public const ushort Channel_P3C =12;
+ public const ushort Channel_P3CL =13;
+ public const ushort Channel_P3CH =14;
+ public const ushort Channel_P4A =15;
+ public const ushort Channel_P4B =16;
+ public const ushort Channel_P4C =17;
+ public const ushort Channel_P4CL =18;
+ public const ushort Channel_P4CH =19;
+ public const ushort Channel_P5A =20;
+ public const ushort Channel_P5B =21;
+ public const ushort Channel_P5C =22;
+ public const ushort Channel_P5CL =23;
+ public const ushort Channel_P5CH =24;
+ public const ushort Channel_P6A =25;
+ public const ushort Channel_P6B =26;
+ public const ushort Channel_P6C =27;
+ public const ushort Channel_P6CL =28;
+ public const ushort Channel_P6CH =29;
+//the following are used for PCI7396
+ public const ushort Channel_P1 =30;
+ public const ushort Channel_P2 =31;
+ public const ushort Channel_P3 =32;
+ public const ushort Channel_P4 =33;
+ public const ushort Channel_P1E =34; //only used by DIO_PortConfig function
+ public const ushort Channel_P2E =35; //only used by DIO_PortConfig function
+ public const ushort Channel_P3E =36; //only used by DIO_PortConfig function
+ public const ushort Channel_P4E =37; //only used by DIO_PortConfig function
+//7442
+ public const ushort P7442_CH0 = 0;
+ public const ushort P7442_CH1 = 1;
+ public const ushort P7442_TTL0 = 2;
+ public const ushort P7442_TTL1 = 3;
+//-------- Constants for PCI-7300A -------------------
+//Wait Status
+ public const ushort P7300_WAIT_NO =0;
+ public const ushort P7300_WAIT_TRG =1;
+ public const ushort P7300_WAIT_FIFO =2;
+ public const ushort P7300_WAIT_BOTH =3;
+
+//Terminator control
+ public const ushort P7300_TERM_OFF =0;
+ public const ushort P7300_TERM_ON =1;
+
+//DI control signals polarity for PCI-7300A Rev. B
+ public const ushort P7300_DIREQ_POS =0x00000000;
+ public const ushort P7300_DIREQ_NEG =0x00000001;
+ public const ushort P7300_DIACK_POS =0x00000000;
+ public const ushort P7300_DIACK_NEG =0x00000002;
+ public const ushort P7300_DITRIG_POS =0x00000000;
+ public const ushort P7300_DITRIG_NEG =0x00000004;
+
+//DO control signals polarity for PCI-7300A Rev. B
+ public const ushort P7300_DOREQ_POS =0x00000000;
+ public const ushort P7300_DOREQ_NEG =0x00000008;
+ public const ushort P7300_DOACK_POS =0x00000000;
+ public const ushort P7300_DOACK_NEG =0x00000010;
+ public const ushort P7300_DOTRIG_POS =0x00000000;
+ public const ushort P7300_DOTRIG_NEG =0x00000020;
+//-------- Constants for PCI-7432/7433/7434 ---------------
+ public const ushort PORT_DI_LOW =0;
+ public const ushort PORT_DI_HIGH =1;
+ public const ushort PORT_DO_LOW =0;
+ public const ushort PORT_DO_HIGH =1;
+ public const ushort P7432R_DO_LED =1;
+ public const ushort P7433R_DO_LED =0;
+ public const ushort P7434R_DO_LED =2;
+ public const ushort P7432R_DI_SLOT =1;
+ public const ushort P7433R_DI_SLOT =2;
+ public const ushort P7434R_DI_SLOT =0;
+//-- Dual-Interrupt Source control for PCI-7248/96 & 7432/33 & 7230 & 8554 & 7396 &7256 &7260 ---
+ public const short INT1_DISABLE =-1; //INT1 Disabled
+ public const short INT1_COS =0; //INT1 COS : only available for PCI-7396, PCI-7256, PCI-7260
+ public const short INT1_FP1C0 =1; //INT1 by Falling edge of P1C0 : only available for PCI7248/96/7396
+ public const short INT1_RP1C0_FP1C3 =2; //INT1 by P1C0 Rising or P1C3 Falling : only available for PCI7248/96/7396
+ public const short INT1_EVENT_COUNTER =3; //INT1 by Event Counter down to zero : only available for PCI7248/96/7396
+ public const short INT1_EXT_SIGNAL =1; //INT1 by external signal : only available for PCI7432/7433/7230/8554
+ public const short INT1_COUT12 =1; //INT1 COUT12 : only available for PCI8554
+ public const short INT1_CH0 =1; //INT1 CH0 : only available for PCI7256, PCI7260
+ public const short INT1_COS0 =1; //INT1 COS0 : only available for PCI-7452/PCI-7442
+ public const short INT1_COS1 =2; //INT1 COS1 : only available for PCI-7452/PCI-7442
+ public const short INT1_COS2 =4; //INT1 COS2 : only available for PCI-7452/PCI-7442
+ public const short INT1_COS3 =8; //INT1 COS3 : only available for PCI-7452/PCI-7442
+ public const short INT2_DISABLE =-1; //INT2 Disabled
+ public const short INT2_COS =0; //INT2 COS : only available for PCI-7396
+ public const short INT2_FP2C0 =1; //INT2 by Falling edge of P2C0 : only available for PCI7248/96/7396
+ public const short INT2_RP2C0_FP2C3 =2; //INT2 by P2C0 Rising or P2C3 Falling : only available for PCI7248/96/7396
+ public const short INT2_TIMER_COUNTER =3; //INT2 by Timer Counter down to zero : only available for PCI7248/96/7396
+ public const short INT2_EXT_SIGNAL =1; //INT2 by external signal : only available for PCI7432/7433/7230/8554
+ public const short INT2_CH1 =2; //INT2 CH1 : only available for PCI7256, PCI7260
+ public const short INT2_WDT =4; //INT2 by WDT
+
+ public const ushort ManualResetIEvt =0x4000;//interrupt event is manually reset by user
+ public const ushort WDT_OVRFLOW_SAFETYOUT =0x8000;// enable safteyout while WDT overflow
+//-------- Constants for PCI-8554 --------------------
+//Clock Source of Cunter N
+ public const ushort ECKN =0;
+ public const ushort COUTN_1 =1;
+ public const ushort CK1 =2;
+ public const ushort COUT10 =3;
+
+//Clock Source of CK1
+ public const ushort CK1_C8M =0;
+ public const ushort CK1_COUT11 =1;
+
+//Debounce Clock
+ public const ushort DBCLK_COUT11 =0;
+ public const ushort DBCLK_2MHZ =1;
+
+//-------- Constants for PCI-9111 --------------------
+//Dual Interrupt Mode
+ public const ushort P9111_INT1_EOC =0; //Ending of AD conversion
+ public const ushort P9111_INT1_FIFO_HF =1; //FIFO Half Full
+ public const ushort P9111_INT2_PACER =0; //Every Timer tick
+ public const ushort P9111_INT2_EXT_TRG =1; //ExtTrig High->Low
+
+//Channel Count
+ public const ushort P9111_CHANNEL_DO =0;
+ public const ushort P9111_CHANNEL_EDO =1;
+ public const ushort P9111_CHANNEL_DI =0;
+ public const ushort P9111_CHANNEL_EDI =1;
+
+//EDO function
+ public const ushort P9111_EDO_INPUT =1; //EDO port set as Input port
+ public const ushort P9111_EDO_OUT_EDO =2; //EDO port set as Output port
+ public const ushort P9111_EDO_OUT_CHN =3; //EDO port set as channel number ouput port
+
+//Trigger Mode
+ public const ushort P9111_TRGMOD_SOFT =0x00; //Software Trigger Mode
+ public const ushort P9111_TRGMOD_PRE =0x01; //Pre-Trigger Mode
+ public const ushort P9111_TRGMOD_POST =0x02; //Post Trigger Mode
+
+//AO Setting
+ public const ushort P9111_AO_UNIPOLAR =0;
+ public const ushort P9111_AO_BIPOLAR =1;
+
+//-------- Constants for PCI-9118 --------------------
+ public const ushort P9118_AI_BiPolar =0x00;
+ public const ushort P9118_AI_UniPolar =0x01;
+
+ public const ushort P9118_AI_SingEnded =0x00;
+ public const ushort P9118_AI_Differential =0x02;
+
+ public const ushort P9118_AI_ExtG =0x04;
+
+ public const ushort P9118_AI_ExtTrig =0x08;
+
+ public const ushort P9118_AI_DtrgNegative =0x00;
+ public const ushort P9118_AI_DtrgPositive =0x10;
+
+ public const ushort P9118_AI_EtrgNegative =0x00;
+ public const ushort P9118_AI_EtrgPositive =0x20;
+
+ public const ushort P9118_AI_BurstModeEn =0x40;
+ public const ushort P9118_AI_SampleHold =0x80;
+ public const ushort P9118_AI_PostTrgEn =0x100;
+ public const ushort P9118_AI_AboutTrgEn =0x200;
+
+//-------- Constants for PCI-9116 --------------------
+ public const ushort P9116_AI_LocalGND =0x00;
+ public const ushort P9116_AI_UserCMMD =0x01;
+ public const ushort P9116_AI_SingEnded =0x00;
+ public const ushort P9116_AI_Differential =0x02;
+ public const ushort P9116_AI_BiPolar =0x00;
+ public const ushort P9116_AI_UniPolar =0x04;
+
+ public const ushort P9116_TRGMOD_SOFT =0x00; //Software Trigger Mode
+ public const ushort P9116_TRGMOD_POST =0x10; //Post Trigger Mode
+ public const ushort P9116_TRGMOD_DELAY =0x20; //Delay Trigger Mode
+ public const ushort P9116_TRGMOD_PRE =0x30; //Pre-Trigger Mode
+ public const ushort P9116_TRGMOD_MIDL =0x40; //Middle Trigger Mode
+ public const ushort P9116_AI_TrgPositive =0x00;
+ public const ushort P9116_AI_TrgNegative =0x80;
+ public const ushort P9116_AI_ExtTimeBase =0x100;
+ public const ushort P9116_AI_IntTimeBase =0x000;
+ public const ushort P9116_AI_DlyInSamples =0x200;
+ public const ushort P9116_AI_DlyInTimebase =0x000;
+ public const ushort P9116_AI_ReTrigEn =0x400;
+ public const ushort P9116_AI_MCounterEn =0x800;
+ public const ushort P9116_AI_SoftPolling =0x0000;
+ public const ushort P9116_AI_INT =0x1000;
+ public const ushort P9116_AI_DMA =0x2000;
+
+//-------- Constants for PCI-9812 --------------------
+//Trigger Mode
+ public const ushort P9812_TRGMOD_SOFT =0x00; //Software Trigger Mode
+ public const ushort P9812_TRGMOD_POST =0x01; //Post Trigger Mode
+ public const ushort P9812_TRGMOD_PRE =0x02; //Pre-Trigger Mode
+ public const ushort P9812_TRGMOD_DELAY =0x03; //Delay Trigger Mode
+ public const ushort P9812_TRGMOD_MIDL =0x04; //Middle Trigger Mode
+
+ public const ushort P9812_AIEvent_Manual =0x08; //Middle Trigger Mode
+
+ //Trigger Source
+ public const ushort P9812_TRGSRC_CH0 =0x00; //trigger source --CH0
+ public const ushort P9812_TRGSRC_CH1 =0x08; //trigger source --CH1
+ public const ushort P9812_TRGSRC_CH2 =0x10; //trigger source --CH2
+ public const ushort P9812_TRGSRC_CH3 =0x18; //trigger source --CH3
+ public const ushort P9812_TRGSRC_EXT_DIG =0x20; //External Digital Trigger
+
+//Trigger Polarity
+ public const ushort P9812_TRGSLP_POS =0x00; //Positive slope trigger
+ public const ushort P9812_TRGSLP_NEG =0x40; //Negative slope trigger
+
+//Frequency Selection
+ public const ushort P9812_AD2_GT_PCI =0x80; //Freq. of A/D clock > PCI clock freq.
+ public const ushort P9812_AD2_LT_PCI =0x00; //Freq. of A/D clock < PCI clock freq.
+
+//Clock Source
+ public const ushort P9812_CLKSRC_INT =0x000; //Internal clock
+ public const ushort P9812_CLKSRC_EXT_SIN =0x100; //External SIN wave clock
+ public const ushort P9812_CLKSRC_EXT_DIG =0x200; //External Square wave clock
+
+//EMG shdn ctrl code
+ public const ushort EMGSHDN_OFF =0; //off
+ public const ushort EMGSHDN_ON =1; //on
+ public const ushort EMGSHDN_RECOVERY =2; //recovery
+
+//Hot Reset Hold ctrl code
+ public const ushort HRH_OFF =0; //off
+ public const ushort HRH_ON =1; //on
+
+//-------- Timer/Counter -----------------------------
+//Counter Mode (8254)
+ public const ushort TOGGLE_OUTPUT =0; //Toggle output from low to high on terminal count
+ public const ushort PROG_ONE_SHOT =1; //Programmable one-shot
+ public const ushort RATE_GENERATOR =2; //Rate generator
+ public const ushort SQ_WAVE_RATE_GENERATOR =3; //Square wave rate generator
+ public const ushort SOFT_TRIG =4; //Software-triggered strobe
+ public const ushort HARD_TRIG =5; //Hardware-triggered strobe
+
+//General Purpose Timer/Counter
+//Counter Mode
+ public const ushort General_Counter =0x00; //general counter
+ public const ushort Pulse_Generation =0x01; //pulse generation
+//GPTC clock source
+ public const ushort GPTC_CLKSRC_EXT =0x08;
+ public const ushort GPTC_CLKSRC_INT =0x00;
+ public const ushort GPTC_GATESRC_EXT =0x10;
+ public const ushort GPTC_GATESRC_INT =0x00;
+ public const ushort GPTC_UPDOWN_SELECT_EXT =0x20;
+ public const ushort GPTC_UPDOWN_SELECT_SOFT =0x00;
+ public const ushort GPTC_UP_CTR =0x40;
+ public const ushort GPTC_DOWN_CTR =0x00;
+ public const ushort GPTC_ENABLE =0x80;
+ public const ushort GPTC_DISABLE =0x00;
+
+//Watchdog Timer
+//Counter action
+ public const ushort WDT_DISARM =0;
+ public const ushort WDT_ARM =1;
+ public const ushort WDT_RESTART =2;
+
+//Pattern ID
+ public const ushort INIT_PTN =0;
+ public const ushort EMGSHDN_PTN =1;
+
+//16-bit binary or 4-decade BCD counter
+ public const ushort BIN =0;
+ public const ushort BCD =1;
+
+//Pattern ID for 7442
+ public const ushort INIT_PTN_CH0 = 0;
+ public const ushort INIT_PTN_CH1 =1;
+ public const ushort SAFTOUT_PTN_CH0 =4;
+ public const ushort SAFTOUT_PTN_CH1 =5;
+
+//DAQ Event type for the event message
+ public const ushort AIEnd =0;
+ public const ushort DIEnd =0;
+ public const ushort DOEnd =0;
+ public const ushort DBEvent =1;
+
+ public const ushort RegBySlot=0x8000;
+
+/*------------------------------------------------------------------
+** PCIS-DASK Function prototype
+------------------------------------------------------------------*/
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short Register_Card (ushort CardType, ushort card_num);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short Release_Card (ushort CardNumber);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short GetActualRate (ushort CardNumber, double fSampleRate, out double fActualRate);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short EMGShutDownControl (ushort CardNumber, byte ctrl);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short EMGShutDownStatus (ushort CardNumber, out byte sts);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short HotResetHoldControl(ushort wCardNumber, byte enable);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short HotResetHoldStatus(ushort wCardNumber, out byte sts);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short GetInitPattern (ushort CardNumber, byte patID, out uint pattern);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short SetInitPattern(ushort wCardNumber, byte patID, uint pattern);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short IdentifyLED_Control (ushort CardNumber, byte ctrl);
+/*---------------------------------------------------------------------------*/
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short AI_9111_Config (ushort CardNumber, ushort TrigSource, ushort TrgMode, ushort TraceCnt);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short AI_9112_Config (ushort CardNumber, ushort TrigSource);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short AI_9113_Config (ushort CardNumber, ushort TrigSource);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short AI_9114_Config (ushort CardNumber, ushort TrigSource);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short AI_9116_Config (ushort CardNumber, ushort ConfigCtrl, ushort TrigCtrl, ushort PostCnt, ushort MCnt, ushort ReTrgCnt);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short AI_9118_Config (ushort CardNumber, ushort ModeCtrl, ushort FunCtrl, ushort BurstCnt, ushort PostCnt);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short AI_9812_Config (ushort CardNumber, ushort TrgMode, ushort TrgSrc, ushort TrgPol, ushort ClkSel, ushort TrgLevel, ushort PostCnt);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short AI_9812_SetDiv (ushort wCardNumber, uint PacerVal);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short AI_9114_PreTrigConfig (ushort CardNumber, ushort PreTrgEn, ushort TraceCnt);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short AI_9116_CounterInterval (ushort wCardNumber, uint ScanIntrv, uint SampIntrv);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short AI_InitialMemoryAllocated (ushort CardNumber, out uint MemSize);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short AI_ReadChannel (ushort CardNumber, ushort Channel, ushort AdRange, out ushort Value);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short AI_VReadChannel (ushort CardNumber, ushort Channel, ushort AdRange, out double voltage);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short AI_VoltScale (ushort CardNumber, ushort AdRange, ushort reading, out double voltage);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short AI_ContReadChannel (ushort CardNumber, ushort Channel, ushort AdRange,
+ ushort[] Buffer, uint ReadCount, double SampleRate, ushort SyncMode);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short AI_ContReadMultiChannels (ushort CardNumber, ushort NumChans, ushort[] Chans,
+ ushort[] AdRanges, ushort[] Buffer, uint ReadCount,
+ double SampleRate, ushort SyncMode);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short AI_ContScanChannels (ushort CardNumber, ushort Channel, ushort AdRange,
+ ushort[] Buffer, uint ReadCount, double SampleRate, ushort SyncMode);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short AI_ContReadChannelToFile (ushort CardNumber, ushort Channel, ushort AdRange,
+ string FileName, uint ReadCount, double SampleRate, ushort SyncMode);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short AI_ContReadMultiChannelsToFile (ushort CardNumber, ushort NumChans, ushort[] Chans,
+ ushort[] AdRanges, string[] FileName, uint ReadCount,
+ double SampleRate, ushort SyncMode);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short AI_ContScanChannelsToFile (ushort CardNumber, ushort Channel, ushort AdRange,
+ string FileName, uint ReadCount, double SampleRate, ushort SyncMode);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short AI_ContStatus (ushort CardNumber, out ushort Status);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short AI_ContVScale (ushort wCardNumber, ushort adRange, ushort[] readingArray, double[] voltageArray, int count);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short AI_AsyncCheck(ushort CardNumber, out byte Stopped, out uint AccessCnt);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short AI_AsyncClear (ushort CardNumber, out uint AccessCnt);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short AI_AsyncDblBufferHalfReady(ushort CardNumber, out byte HalfReady, out byte StopFlag);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short AI_AsyncDblBufferMode (ushort CardNumber, bool Enable);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short AI_AsyncDblBufferTransfer (ushort CardNumber, ushort[] Buffer);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short AI_AsyncDblBufferOverrun (ushort CardNumber, ushort op, out ushort overrunFlag);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short AI_EventCallBack(ushort CardNumber, ushort mode, ushort EventType, MulticastDelegate callbackAddr);
+/*---------------------------------------------------------------------------*/
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short AO_6208A_Config (ushort CardNumber, ushort V2AMode);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short AO_6308A_Config (ushort CardNumber, ushort V2AMode);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short AO_6308V_Config (ushort wCardNumber, ushort Channel, ushort wOutputPolarity, double refVoltage);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short AO_9111_Config (ushort CardNumber, ushort OutputPolarity);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short AO_9112_Config (ushort CardNumber, ushort Channel, double refVoltage);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short AO_WriteChannel (ushort CardNumber, ushort Channel, short Value);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short AO_VWriteChannel (ushort CardNumber, ushort Channel, double Voltage);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short AO_VoltScale (ushort CardNumber, ushort Channel, double Voltage, out short binValue);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short AO_SimuWriteChannel (ushort wCardNumber, ushort wGroup, short[] pwBuffer);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short AO_SimuVWriteChannel (ushort wCardNumber, ushort wGroup, double[] VBuffer);
+/*---------------------------------------------------------------------------*/
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DI_7200_Config (ushort CardNumber, ushort TrigSource, ushort ExtTrigEn, ushort TrigPol, ushort I_REQ_Pol);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DI_7300A_Config (ushort CardNumber, ushort PortWidth, ushort TrigSource, ushort WaitStatus, ushort Terminator, ushort I_REQ_Pol, bool clear_fifo, bool disable_di);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DI_7300B_Config (ushort CardNumber, ushort PortWidth, ushort TrigSource, ushort WaitStatus, ushort Terminator, ushort I_Cntrl_Pol, bool clear_fifo, bool disable_di);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DI_InitialMemoryAllocated (ushort CardNumber, out uint DmaSize);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DI_ReadLine (ushort CardNumber, ushort Port, ushort Line, out ushort State);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DI_ReadPort (ushort CardNumber, ushort Port, out uint Value);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DI_ContReadPort (ushort CardNumber, ushort Port, byte[] Buffer,
+ uint ReadCount, double SampleRate, ushort SyncMode);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DI_ContReadPort (ushort CardNumber, ushort Port, ushort[] Buffer,
+ uint ReadCount, double SampleRate, ushort SyncMode);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DI_ContReadPort(ushort CardNumber, ushort Port, uint[] Buffer,
+ uint ReadCount, double SampleRate, ushort SyncMode);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DI_ContReadPortToFile (ushort CardNumber, ushort Port, string FileName,
+ uint ReadCount, double SampleRate, ushort SyncMode);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DI_ContStatus (ushort CardNumber, out ushort Status);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DI_AsyncCheck (ushort CardNumber, out byte Stopped, out uint AccessCnt);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DI_AsyncClear (ushort CardNumber, out uint AccessCnt);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DI_AsyncDblBufferHalfReady(ushort CardNumber, out byte HalfReady);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DI_AsyncDblBufferMode (ushort CardNumber, bool Enable);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DI_AsyncDblBufferTransfer (ushort CardNumber, byte[] Buffer);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DI_AsyncDblBufferTransfer (ushort CardNumber, short[] Buffer);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DI_AsyncDblBufferTransfer(ushort CardNumber, uint[] Buffer);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DI_ContMultiBufferSetup (ushort wCardNumber, byte[] pwBuffer, uint dwReadCount, out ushort BufferId);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DI_ContMultiBufferSetup (ushort wCardNumber, short[] pwBuffer, uint dwReadCount, out ushort BufferId);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DI_ContMultiBufferSetup(ushort wCardNumber, uint[] pwBuffer, uint dwReadCount, out ushort BufferId);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DI_ContMultiBufferStart (ushort wCardNumber, ushort wPort, double fSampleRate);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DI_AsyncMultiBufferNextReady(ushort CardNumber, out byte bNextReady, out ushort wBufferId);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DI_AsyncDblBufferOverrun (ushort CardNumber, ushort op, out ushort overrunFlag);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DI_EventCallBack(ushort CardNumber, short mode, short EventType, MulticastDelegate callbackAddr);
+/*---------------------------------------------------------------------------*/
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DO_7200_Config (ushort CardNumber, ushort TrigSource, ushort OutReqEn, ushort OutTrigSig);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DO_7300A_Config (ushort CardNumber, ushort PortWidth, ushort TrigSource, ushort WaitStatus, ushort Terminator, ushort O_REQ_Pol);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DO_7300B_Config (ushort CardNumber, ushort PortWidth, ushort TrigSource, ushort WaitStatus, ushort Terminator, ushort O_Cntrl_Pol, uint FifoThreshold);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DO_InitialMemoryAllocated (ushort CardNumber, out uint MemSize);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DO_WriteLine (ushort CardNumber, ushort Port, ushort Line, ushort Value);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DO_WritePort (ushort CardNumber, byte Port, uint Value);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DO_WritePort (ushort CardNumber, ushort Port, uint Value);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DO_WritePort(ushort CardNumber, uint Port, uint Value);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DO_WriteExtTrigLine (ushort CardNumber, ushort Value);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DO_ReadLine (ushort CardNumber, ushort Port, ushort Line, out ushort Value);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DO_ReadPort (ushort CardNumber, ushort Port, out uint Value);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DO_ContWritePort (ushort CardNumber, ushort Port, byte[] Buffer,
+ uint WriteCount, ushort Iterations, double SampleRate, ushort SyncMode);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DO_ContWritePort (ushort CardNumber, ushort Port, ushort[] Buffer,
+ uint WriteCount, ushort Iterations, double SampleRate, ushort SyncMode);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DO_ContWritePort (ushort CardNumber, ushort Port, uint[] Buffer,
+ uint WriteCount, ushort Iterations, double SampleRate, ushort SyncMode);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DO_PGStart (ushort CardNumber, byte[] Buffer, uint WriteCount, double SampleRate);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DO_PGStart (ushort CardNumber, short[] Buffer, uint WriteCount, double SampleRate);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DO_PGStart(ushort CardNumber, uint[] Buffer, uint WriteCount, double SampleRate);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DO_PGStop (ushort CardNumber);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DO_ContStatus (ushort CardNumber, out ushort Status);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DO_AsyncCheck(ushort CardNumber, out byte Stopped, out uint AccessCnt);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DO_AsyncClear (ushort CardNumber, out uint AccessCnt);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short EDO_9111_Config (ushort CardNumber, ushort EDO_Fun);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DO_ContMultiBufferSetup (ushort CardNumber, byte[] pwBuffer, uint dwWriteCount, out ushort BufferId);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DO_ContMultiBufferSetup (ushort CardNumber, short[] pwBuffer, uint dwWriteCount, out ushort BufferId);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DO_ContMultiBufferSetup(ushort CardNumber, uint[] pwBuffer, uint dwWriteCount, out ushort BufferId);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DO_AsyncMultiBufferNextReady(ushort CardNumber, out byte bNextReady, out ushort wBufferId);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DO_ContMultiBufferStart (ushort wCardNumber, ushort wPort, double fSampleRate);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DO_EventCallBack(ushort CardNumber, short mode, short EventType, MulticastDelegate callbackAddr);
+/*---------------------------------------------------------------------------*/
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DIO_PortConfig (ushort CardNumber, ushort Port, ushort Direction);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DIO_LinesConfig(ushort wCardNumber, ushort wPort, ushort wLinesdirmap);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DIO_LineConfig(ushort wCardNumber, ushort wPort, ushort wLine, ushort wDirection);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DIO_SetDualInterrupt (ushort CardNumber, short Int1Mode, short Int2Mode, long hEvent);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DIO_SetCOSInterrupt (ushort CardNumber, ushort Port, ushort ctlA, ushort ctlB, ushort ctlC);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DIO_INT1_EventMessage(ushort CardNumber, short Int1Mode, long windowHandle, long message, MulticastDelegate callbackAddr);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DIO_INT2_EventMessage(ushort CardNumber, short Int2Mode, long windowHandle, long message, MulticastDelegate callbackAddr);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DIO_7300SetInterrupt (ushort CardNumber, short AuxDIEn, short T2En, long hEvent);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DIO_AUXDI_EventMessage(ushort CardNumber, short AuxDIEn, long windowHandle, uint message, MulticastDelegate callbackAddr);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DIO_T2_EventMessage(ushort CardNumber, short T2En, long windowHandle, uint message, MulticastDelegate callbackAddr);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DIO_GetCOSLatchData(ushort wCardNumber, out ushort CosLData);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DIO_SetCOSInterrupt32(ushort wCardNumber, byte Port, uint ctl, out long hEvent, bool bManualReset);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DIO_GetCOSLatchDataInt32(ushort wCardNumber, byte Port, out uint CosLData);
+/*---------------------------------------------------------------------------*/
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short CTR_Setup (ushort CardNumber, ushort Ctr, ushort Mode, uint Count, ushort BinBcd);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short CTR_Clear (ushort CardNumber, ushort Ctr, ushort State);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short CTR_Read (ushort CardNumber, ushort Ctr, out uint Value);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short CTR_Update (ushort CardNumber, ushort Ctr, uint Count);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short CTR_8554_ClkSrc_Config (ushort CardNumber, ushort Ctr, ushort ClockSource);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short CTR_8554_CK1_Config (ushort CardNumber, ushort ClockSource);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short CTR_8554_Debounce_Config (ushort CardNumber, ushort DebounceClock);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short GCTR_Setup (ushort wCardNumber, ushort wGCtr, ushort wGCtrCtrl,uint dwCount);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short GCTR_Clear (ushort wCardNumber, ushort wGCtr);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short GCTR_Read (ushort wCardNumber, ushort wGCtr, out uint pValue);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short WDT_Setup (ushort CardNumber, ushort wCtr, float ovflowSec, out float actualSec, out long hEvent);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short WDT_Control (ushort wCardNumber, ushort wCtr, ushort action);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short WDT_Status (ushort wCardNumber, ushort Ctr, out uint pValue);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short WDT_Reload(ushort wCardNumber, float ovflowSec, out float actualSec);
+/*---------------------------------------------------------------------------*/
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short AI_GetEvent(ushort wCardNumber, out long hEvent);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short AO_GetEvent(ushort wCardNumber, out long hEvent);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DI_GetEvent(ushort wCardNumber, out long hEvent);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DO_GetEvent(ushort wCardNumber, out long hEvent);
+/*---------------------------------------------------------------------------*/
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short AI_GetView(ushort wCardNumber, uint[] pView);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DI_GetView(ushort wCardNumber, uint[] pView);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short DO_GetView(ushort wCardNumber, uint[] pView);
+/*---------------------------------------------------------------------------*/
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short GetCardType (ushort wCardNumber, out ushort cardType);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short GetCardIndexFromID (ushort wCardNumber, out ushort cardType, out ushort cardIndex);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short GetBaseAddr(ushort wCardNumber, uint[] BaseAddr, uint[] BaseAddr2);
+ [DllImport("PCI-Dask64.dll")]
+ public static extern short GetLCRAddr(ushort wCardNumber, uint[] LcrAddr);
+}
\ No newline at end of file
diff --git a/Plugin.DODriverControl/Api/DaskHelper.cs b/Plugin.DODriverControl/Api/DaskHelper.cs
new file mode 100644
index 0000000..4f5241e
--- /dev/null
+++ b/Plugin.DODriverControl/Api/DaskHelper.cs
@@ -0,0 +1,132 @@
+锘縩amespace Plugin.DODriverControl.Api
+{
+ public class DaskHelper
+ {
+ public static ushort CardType(string name)
+ {
+ ushort cardtype = 0;
+ switch (name)
+ {
+ case "PCI_6208V":
+ cardtype = 1;
+ break;
+ case "PCI_6208A":
+ cardtype = 2;
+ break;
+ case "PCI_6308V":
+ cardtype = 3;
+ break;
+ case "PCI_6308A":
+ cardtype = 4;
+ break;
+ case "PCI_7200":
+ cardtype = 5;
+ break;
+ case "PCI_7230":
+ cardtype = 6;
+ break;
+ case "PCI_7233":
+ cardtype = 7;
+ break;
+ case "PCI_7234":
+ cardtype = 8;
+ break;
+ case "PCI_7248":
+ cardtype = 9;
+ break;
+ case "PCI_7249":
+ cardtype = 10;
+ break;
+ case "PCI_7250":
+ cardtype = 11;
+ break;
+ case "PCI_7252":
+ cardtype = 12;
+ break;
+ case "PCI_7296":
+ cardtype = 13;
+ break;
+ case "PCI_7300A_RevA":
+ cardtype = 14;
+ break;
+ case "PCI_7300A_RevB":
+ cardtype = 15;
+ break;
+ case "PCI_7432":
+ cardtype = 16;
+ break;
+ case "PCI_7433":
+ cardtype = 17;
+ break;
+ case "PCI_7434":
+ cardtype = 18;
+ break;
+ case "PCI_8554":
+ cardtype = 19;
+ break;
+ case "PCI_9111DG":
+ cardtype = 20;
+ break;
+ case "PCI_9111HR":
+ cardtype = 21;
+ break;
+ case "PCI_9112":
+ cardtype = 22;
+ break;
+ case "PCI_9113":
+ cardtype = 23;
+ break;
+ case "PCI_9114DG":
+ cardtype = 24;
+ break;
+ case "PCI_9114HG":
+ cardtype = 25;
+ break;
+ case "PCI_9118DG":
+ cardtype = 26;
+ break;
+ case "PCI_9118HG":
+ cardtype = 27;
+ break;
+ case "PCI_9118HR":
+ cardtype = 28;
+ break;
+ case "PCI_9810":
+ cardtype = 29;
+ break;
+ case "PCI_9812":
+ cardtype = 30;
+ break;
+ case "PCI_7396":
+ cardtype = 31;
+ break;
+ case "PCI_9116":
+ cardtype = 32;
+ break;
+ case "PCI_7256":
+ cardtype = 33;
+ break;
+ case "PCI_7258":
+ cardtype = 34;
+ break;
+ case "PCI_7260":
+ cardtype = 35;
+ break;
+ case "PCI_7452":
+ cardtype = 36;
+ break;
+ case "PCI_7442":
+ cardtype = 37;
+ break;
+ case "MAX_CARD":
+ cardtype = 32;
+ break;
+ default:
+ cardtype = 16;
+ break;
+ }
+
+ return cardtype;
+ }
+ }
+}
diff --git a/Plugin.DODriverControl/Api/IDIOController.cs b/Plugin.DODriverControl/Api/IDIOController.cs
new file mode 100644
index 0000000..fa2252b
--- /dev/null
+++ b/Plugin.DODriverControl/Api/IDIOController.cs
@@ -0,0 +1,15 @@
+锘縩amespace Plugin.DODriverControl.Api
+{
+ public interface IDIOController : IDisposable
+ {
+ bool Start(out string msg);
+
+ bool ReadDIBool(string address, out bool res, out string msg);
+
+ bool ReadDOBool(string address, out bool res, out string msg);
+
+ bool WriteBool(string address, bool value, out string msg);
+
+ bool Close();
+ }
+}
diff --git a/Plugin.DODriverControl/Api/ModBusTcpController.cs b/Plugin.DODriverControl/Api/ModBusTcpController.cs
new file mode 100644
index 0000000..f366f5e
--- /dev/null
+++ b/Plugin.DODriverControl/Api/ModBusTcpController.cs
@@ -0,0 +1,55 @@
+锘縰sing HslCommunication.ModBus;
+
+namespace Plugin.DODriverControl.Api
+{
+ public class ModBusTcpController : IDIOController
+ {
+ public string Ip { get; set; }
+ public int Port { get; set; }
+
+ private ModbusTcpNet client;
+
+ public bool Start(out string errMsg)
+ {
+ errMsg = string.Empty;
+ client = new ModbusTcpNet(Ip, Port);
+ var res = client.ConnectServer();
+ errMsg = res.Message;
+ return res.IsSuccess;
+ }
+
+ public bool ReadDIBool(string address, out bool res, out string msg)
+ {
+ var result = client?.ReadBool($"x=2;{address}");
+ msg = result?.Message;
+ res = result?.Content == true;
+ return result?.IsSuccess == true;
+ }
+
+ public bool ReadDOBool(string address, out bool res, out string msg)
+ {
+ var result = client?.ReadBool(address);
+ msg = result?.Message;
+ res = result?.Content == true;
+ return result?.IsSuccess == true;
+ }
+
+ public bool WriteBool(string address, bool value, out string msg)
+ {
+ msg = string.Empty;
+ var res = client?.Write(address, value);
+ msg = res.Message;
+ return res?.IsSuccess == true;
+ }
+
+ public bool Close()
+ {
+ return client?.ConnectClose()?.IsSuccess == true;
+
+ }
+ public void Dispose()
+ {
+ client?.Dispose();
+ }
+ }
+}
diff --git a/Plugin.DODriverControl/Api/PCIController.cs b/Plugin.DODriverControl/Api/PCIController.cs
new file mode 100644
index 0000000..a8d1f30
--- /dev/null
+++ b/Plugin.DODriverControl/Api/PCIController.cs
@@ -0,0 +1,49 @@
+锘縩amespace Plugin.DODriverControl.Api
+{
+ public class PCIController : IDIOController
+ {
+ public string Name { get; set; }
+
+ private short id;
+
+ public bool Start(out string msg)
+ {
+ msg = string.Empty;
+ id = DASK.Register_Card(DaskHelper.CardType(Name), 0);
+ return id >= 0;
+ }
+
+ public bool ReadDIBool(string address, out bool res, out string msg)
+ {
+ msg = string.Empty;
+ DASK.DI_ReadLine((ushort)id, 0, ushort.Parse(address), out ushort value);
+ res = Convert.ToBoolean(value);
+ return true;
+ }
+
+ public bool ReadDOBool(string address, out bool res, out string msg)
+ {
+ msg = string.Empty;
+ DASK.DO_ReadLine((ushort)id, 0, ushort.Parse(address), out ushort value);
+ res = Convert.ToBoolean(value);
+ return true;
+ }
+
+ public bool WriteBool(string address, bool value, out string msg)
+ {
+ msg = string.Empty;
+ var res = DASK.DO_WriteLine((ushort)id, 0, ushort.Parse(address), Convert.ToUInt16(value));
+ return res == 0;
+ }
+
+ public bool Close()
+ {
+ return DASK.Release_Card((ushort)id) == 0;
+ }
+
+ public void Dispose()
+ {
+ this.Close();
+ }
+ }
+}
diff --git a/Plugin.DODriverControl/AssemblyInfo.cs b/Plugin.DODriverControl/AssemblyInfo.cs
new file mode 100644
index 0000000..cc29e7f
--- /dev/null
+++ b/Plugin.DODriverControl/AssemblyInfo.cs
@@ -0,0 +1,10 @@
+using System.Windows;
+
+[assembly:ThemeInfo(
+ ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
+ //(used if a resource is not found in the page,
+ // or application resource dictionaries)
+ ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
+ //(used if a resource is not found in the page,
+ // app, or any theme specific resource dictionaries)
+)]
diff --git a/Plugin.DODriverControl/ConfigModal.xaml b/Plugin.DODriverControl/ConfigModal.xaml
new file mode 100644
index 0000000..c1e4102
--- /dev/null
+++ b/Plugin.DODriverControl/ConfigModal.xaml
@@ -0,0 +1,54 @@
+锘�<pu:WindowX x:Class="Plugin.DODriverControl.ConfigModal"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:local="clr-namespace:Plugin.DODriverControl"
+ xmlns:pw="https://opensource.panuon.com/wpf"
+ xmlns:pu="https://opensource.panuon.com/wpf-ui"
+ xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
+ xmlns:pde="clr-namespace:Plugin.DODriverControl.Entity"
+ xmlns:sys="clr-namespace:System;assembly=mscorlib"
+ mc:Ignorable="d"
+ Title="Form"
+ SizeToContent="Height"
+ Width="600"
+ WindowStartupLocation="CenterOwner"
+ Style="{StaticResource ModalWindow}">
+ <Window.Resources>
+ <ObjectDataProvider x:Key="types"
+ MethodName="GetValues"
+ ObjectType="{x:Type sys:Enum}">
+ <ObjectDataProvider.MethodParameters>
+ <x:Type TypeName="pde:ConfigType"/>
+ </ObjectDataProvider.MethodParameters>
+ </ObjectDataProvider>
+ </Window.Resources>
+
+ <Grid Margin="10">
+ <StackPanel x:Name="formPanel">
+ <pu:FormGroup x:Name="FgType" Header="绫诲瀷"
+ Style="{StaticResource InputFormGroupStyle}"
+ dp:FormGroupHelper.IsRequired="True"
+ GroupName="MyFormGroup">
+ <ComboBox x:Name="CbType" Style="{StaticResource FormComboxStyle}"
+ ItemsSource="{Binding Source={StaticResource types}}"
+ SelectedValuePath="Content"/>
+ </pu:FormGroup>
+
+ <pu:FormGroup x:Name="FgIP" Header="IP"
+ Style="{StaticResource InputFormGroupStyle}"
+ dp:FormGroupHelper.IsRequired="True"
+ GroupName="MyFormGroup">
+ <TextBox x:Name="TbIP" Style="{StaticResource EditorTextBoxStyle}" />
+ </pu:FormGroup>
+
+ <pu:FormGroup x:Name="FgPort" Header="Port"
+ Style="{StaticResource InputFormGroupStyle}"
+ dp:FormGroupHelper.IsRequired="True"
+ GroupName="MyFormGroup">
+ <TextBox x:Name="TbPort" Style="{StaticResource EditorTextBoxStyle}" />
+ </pu:FormGroup>
+ </StackPanel>
+ </Grid>
+</pu:WindowX>
diff --git a/Plugin.DODriverControl/ConfigModal.xaml.cs b/Plugin.DODriverControl/ConfigModal.xaml.cs
new file mode 100644
index 0000000..835ca16
--- /dev/null
+++ b/Plugin.DODriverControl/ConfigModal.xaml.cs
@@ -0,0 +1,108 @@
+锘縰sing HMI.UI.DpUtil;
+using HMI.UI.Util;
+using Panuon.WPF.UI;
+using Plugin.DODriverControl.Entity;
+using System.ComponentModel;
+
+namespace Plugin.DODriverControl
+{
+ /// <summary>
+ /// ModalWindow.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ public partial class ConfigModal : WindowX
+ {
+ public ConfigModal()
+ {
+ this.DataContext = this;
+ InitializeComponent();
+ }
+
+ public ConfigData config { get; private set; }
+
+ private bool _isProcessing;
+
+ protected override void OnClosing(CancelEventArgs e)
+ {
+ //Press Continue Button
+ if (DialogResult == true)
+ {
+ if (_isProcessing)
+ {
+ e.Cancel = true;
+ return;
+ }
+ var okButton = WindowXModalDialog.GetOKButton(this);
+ try
+ {
+ _isProcessing = true;
+ ButtonHelper.SetIsPending(okButton, true);
+ if (!ValidateForm())
+ {
+ e.Cancel = true;
+ return;
+ }
+ }
+ catch (Exception ex)
+ {
+ ToastHelper.Error(this, $"Error锛亄ex.Message}");
+ e.Cancel = true;
+ return;
+ }
+ finally
+ {
+ _isProcessing = false;
+ ButtonHelper.SetIsPending(okButton, false);
+ }
+ }
+ base.OnClosing(e);
+ }
+
+ private bool ValidateName(object value, out string err)
+ {
+ err = null;
+ //string group = TbGroup.Text;
+ //var temp = Datasource.FirstOrDefault(d => d.Group == group && d.Name == value.ToString());
+ //if (temp != null && temp != Data)
+ //{
+ // err = this.lang("App.MustBeUnique", $"{this.lang("doc.group")},{this.lang("doc.name")}");
+ // return false;
+ //}
+ return true;
+ }
+
+ private bool ValidateAddress(object value, out string err)
+ {
+ err = null;
+ //string group = TbGroup.Text;
+ //var temp = Datasource.FirstOrDefault(d => d.Address == value.ToString());
+ //if (temp != null && temp != Data)
+ //{
+ // err = this.lang("App.MustBeUnique", this.lang("doc.Address"));
+ // return false;
+ //}
+ return true;
+ }
+
+ private bool ValidateForm()
+ {
+ bool flag = FormGroupHelper.ValidateForm(formPanel);
+ if (flag)
+ {
+ config.Type = (ConfigType)CbType.SelectedItem;
+ config.IP = TbIP.Text;
+ config.Port = TbPort.Text;
+ }
+ return flag;
+ }
+
+ public bool? Open(ConfigData config)
+ {
+ this.config = config;
+
+ CbType.SelectedItem = config.Type;
+ TbIP.Text = config.IP;
+ TbPort.Text = config.Port;
+ return this.ShowDialog();
+ }
+ }
+}
diff --git a/Plugin.DODriverControl/DOControl.xaml b/Plugin.DODriverControl/DOControl.xaml
new file mode 100644
index 0000000..413dc8f
--- /dev/null
+++ b/Plugin.DODriverControl/DOControl.xaml
@@ -0,0 +1,22 @@
+锘�<hb:SimpleMaskControl x:Class="Plugin.DODriverControl.DOControl"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:local="clr-namespace:Plugin.DODriverControl"
+ mc:Ignorable="d"
+ xmlns:hb="clr-namespace:HMI.Base;assembly=HMI.Base"
+xmlns:uic="clr-namespace:HMI.UI.Converter;assembly=HMI.UI"
+xmlns:ui="clr-namespace:HMI.UI;assembly=HMI.UI"
+xmlns:mdi="clr-namespace:HMI.UI.MDI;assembly=HMI.UI"
+xmlns:pw="https://opensource.panuon.com/wpf"
+xmlns:pu="https://opensource.panuon.com/wpf-ui"
+xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
+ Loaded="PluginMaskControl_Loaded"
+ d:DesignHeight="450" d:DesignWidth="800">
+ <Border Style="{StaticResource CardBoarder}" Padding="0" Background="#e6e6e6">
+ <Grid>
+ <mdi:Workspace x:Name="workspace" SettingPath="{Binding WorkspaceSetting}"/>
+ </Grid>
+ </Border>
+</hb:SimpleMaskControl>
diff --git a/Plugin.DODriverControl/DOControl.xaml.cs b/Plugin.DODriverControl/DOControl.xaml.cs
new file mode 100644
index 0000000..78c1241
--- /dev/null
+++ b/Plugin.DODriverControl/DOControl.xaml.cs
@@ -0,0 +1,141 @@
+锘縰sing CommunityToolkit.Mvvm.ComponentModel;
+using HMI.Base;
+using HMI.UI.DpUtil;
+using HMI.UI.MDI;
+using System.ComponentModel;
+using System.IO;
+using System.Windows;
+
+namespace Plugin.DODriverControl
+{
+ /// <summary>
+ /// DOControl.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ [ObservableObject]
+ public partial class DOControl : SimpleMaskControl
+ {
+ public DOControl()
+ {
+ this.DataContext = this;
+ InitializeComponent();
+ }
+
+ [ObservableProperty]
+ private string workspaceSetting;
+
+ public override void InitFinish()
+ {
+ WorkspaceSetting = Path.Combine(BaseFolder, "Workspace.xml");
+ base.InitFinish();
+ }
+
+ private List<SingleControl> controls = new List<SingleControl>();
+
+ private List<CanvasPosition> InitGridSize()
+ {
+ List<CanvasPosition> result = new List<CanvasPosition>();
+ result.Add(new CanvasPosition
+ {
+ Left = 0,
+ Top = 0,
+ Width = 0.1 * ActualWidth,
+ Height = 0.5 * ActualHeight
+ });
+ result.Add(new CanvasPosition
+ {
+ Left = 0.1 * ActualWidth + 2,
+ Top = 0,
+ Width = 0.5 * ActualWidth - 4,
+ Height = ActualHeight,
+ });
+
+ result.Add(new CanvasPosition
+ {
+ Left = 0.6 * ActualWidth + 2,
+ Top = 0,
+ Width = 0.4 * ActualWidth - 2,
+ Height = 0.5 * ActualHeight - 2
+ });
+
+ result.Add(new CanvasPosition
+ {
+ Left = 0,
+ Top = 0.5 * ActualHeight + 2,
+ Width = 0.1 * ActualWidth - 2,
+ Height = 0.5 * ActualHeight - 2
+ });
+
+ result.Add(new CanvasPosition
+ {
+ Left = 0.6 * ActualWidth + 2,
+ Top = 0.5 * ActualHeight + 2,
+ Width = 0.4 * ActualWidth - 2,
+ Height = 0.5 * ActualHeight - 2
+ });
+
+ return result;
+ }
+
+ public override void Active()
+ {
+ foreach (var control in controls)
+ {
+ control.Active();
+ }
+ base.Active();
+ }
+
+ public override void DeActive()
+ {
+ foreach (var control in controls)
+ {
+ control.DeActive();
+ }
+ base.DeActive();
+ }
+
+ public override void OnClose(object sender, CancelEventArgs e)
+ {
+ Dispatcher.Invoke(() =>
+ {
+ foreach (var control in controls)
+ {
+ control.Close();
+ }
+ });
+ base.DoClose(sender, e);
+ }
+
+ private void LoadSingleControl()
+ {
+ var ps = InitGridSize();
+ var control = new SingleControl("DIO", BaseFolder)
+ {
+ log = log
+ };
+ controls.Add(control);
+ workspace.AddInnerWindow(control.name, new InnerWindow()
+ {
+ Title = control.name,
+ Content = control
+ });
+
+ //var control2 = new SingleControl("DIO2", BaseFolder)
+ //{
+ // log = log
+ //};
+ //controls.Add(control2);
+ //workspace.AddInnerWindow(control2.name, new InnerWindow()
+ //{
+ // Title = control2.name,
+ // Content = control2
+ //});
+ }
+
+ private void PluginMaskControl_Loaded(object sender, RoutedEventArgs e)
+ {
+ LoadSingleControl();
+ Loaded -= PluginMaskControl_Loaded;
+ }
+ }
+}
diff --git a/Plugin.DODriverControl/DataModal.xaml b/Plugin.DODriverControl/DataModal.xaml
new file mode 100644
index 0000000..b7920ca
--- /dev/null
+++ b/Plugin.DODriverControl/DataModal.xaml
@@ -0,0 +1,120 @@
+锘�<pu:WindowX x:Class="Plugin.DODriverControl.DataModal"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:local="clr-namespace:Plugin.DODriverControl"
+ xmlns:pw="https://opensource.panuon.com/wpf"
+ xmlns:pu="https://opensource.panuon.com/wpf-ui"
+ xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
+ xmlns:pde="clr-namespace:Plugin.DODriverControl.Entity"
+ xmlns:sys="clr-namespace:System;assembly=mscorlib"
+ mc:Ignorable="d"
+ Title="Form"
+ SizeToContent="Height"
+ Width="600"
+ WindowStartupLocation="CenterOwner"
+ Style="{StaticResource ModalWindow}">
+ <Window.Resources>
+ <ObjectDataProvider x:Key="enumValues"
+ MethodName="GetValues"
+ ObjectType="{x:Type sys:Enum}">
+ <ObjectDataProvider.MethodParameters>
+ <x:Type TypeName="pde:ControlType"/>
+ </ObjectDataProvider.MethodParameters>
+ </ObjectDataProvider>
+
+ <ObjectDataProvider x:Key="dioType"
+ MethodName="GetValues"
+ ObjectType="{x:Type sys:Enum}">
+ <ObjectDataProvider.MethodParameters>
+ <x:Type TypeName="pde:DIOType"/>
+ </ObjectDataProvider.MethodParameters>
+ </ObjectDataProvider>
+ </Window.Resources>
+ <Grid Margin="10">
+ <StackPanel x:Name="formPanel">
+ <!--<pu:FormGroup x:Name="FgGroup"
+ Header="{DynamicResource doc.group}"
+ Style="{StaticResource InputFormGroupStyle}"
+ dp:FormGroupHelper.IsRequired="True"
+ GroupName="MyFormGroup">
+ <TextBox x:Name="TbGroup" Style="{StaticResource EditorTextBoxStyle}" />
+ </pu:FormGroup>-->
+
+ <pu:FormGroup x:Name="FgName"
+ Header="{DynamicResource doc.name}"
+ Style="{StaticResource InputFormGroupStyle}"
+ dp:FormGroupHelper.IsRequired="True"
+ dp:FormGroupHelper.ValidateMethod="ValidateName"
+ GroupName="MyFormGroup">
+ <TextBox x:Name="TbName" Style="{StaticResource EditorTextBoxStyle}" />
+ </pu:FormGroup>
+
+ <pu:FormGroup x:Name="FgAddress"
+ Header="{DynamicResource doc.address}"
+ Style="{StaticResource InputFormGroupStyle}"
+ dp:FormGroupHelper.IsRequired="True"
+ dp:FormGroupHelper.ValidateMethod="ValidateAddress"
+ GroupName="MyFormGroup">
+ <TextBox x:Name="TbAddress" Style="{StaticResource EditorTextBoxStyle}" />
+ </pu:FormGroup>
+
+ <!--<pu:FormGroup x:Name="FgDio"
+Header="DI/O"
+Style="{StaticResource InputFormGroupStyle}"
+GroupName="MyFormGroup">
+ <CheckBox x:Name="CxReadOnly"/>
+ </pu:FormGroup>-->
+
+ <pu:FormGroup x:Name="FgDio"
+Header="DI/O"
+Style="{StaticResource InputFormGroupStyle}"
+GroupName="MyFormGroup">
+ <ComboBox x:Name="CbDio" Style="{StaticResource FormComboxStyle}"
+ ItemsSource="{Binding Source={StaticResource dioType}}"
+ SelectedValuePath="Content"/>
+ </pu:FormGroup>
+
+ <pu:FormGroup x:Name="FgControlType"
+Header="{DynamicResource doc.controlType}"
+Style="{StaticResource InputFormGroupStyle}"
+dp:FormGroupHelper.IsRequired="True"
+GroupName="MyFormGroup">
+ <ComboBox x:Name="CbControlType" Style="{StaticResource FormComboxStyle}"
+ SelectionChanged="CbControlType_SelectionChanged"
+ ItemsSource="{Binding Source={StaticResource enumValues}}"
+ SelectedValuePath="Content">
+ </ComboBox>
+ </pu:FormGroup>
+
+ <pu:FormGroup x:Name="FgPressDownValue"
+ Header="{DynamicResource doc.pressDownValue}"
+ Style="{StaticResource InputFormGroupStyle}"
+ dp:FormGroupHelper.IsRequired="True"
+ GroupName="MyFormGroup">
+ <TextBox x:Name="TbPressDownValue" Style="{StaticResource EditorTextBoxStyle}" />
+ </pu:FormGroup>
+
+ <pu:FormGroup x:Name="FgPressUpValue"
+Header="{DynamicResource doc.pressUpValue}"
+Style="{StaticResource InputFormGroupStyle}"
+dp:FormGroupHelper.IsRequired="True"
+GroupName="MyFormGroup">
+ <TextBox x:Name="TbPressUpValue" Style="{StaticResource EditorTextBoxStyle}" />
+ </pu:FormGroup>
+
+ <pu:FormGroup x:Name="FgPressDownText" Header="鎸変笅鏂囨湰"
+ dp:FormGroupHelper.IsRequired="True" Style="{StaticResource InputFormGroupStyle}"
+ GroupName="MyFormGroup">
+ <TextBox x:Name="TbPressDownText" Style="{StaticResource EditorTextBoxStyle}" />
+ </pu:FormGroup>
+
+ <pu:FormGroup x:Name="FgPressUpText" Header="寮硅捣鏂囨湰"
+ dp:FormGroupHelper.IsRequired="True" Style="{StaticResource InputFormGroupStyle}"
+ GroupName="MyFormGroup">
+ <TextBox x:Name="TbPressUpText" Style="{StaticResource EditorTextBoxStyle}" />
+ </pu:FormGroup>
+ </StackPanel>
+ </Grid>
+</pu:WindowX>
diff --git a/Plugin.DODriverControl/DataModal.xaml.cs b/Plugin.DODriverControl/DataModal.xaml.cs
new file mode 100644
index 0000000..ba7ac53
--- /dev/null
+++ b/Plugin.DODriverControl/DataModal.xaml.cs
@@ -0,0 +1,177 @@
+锘縰sing HMI.Core.Util;
+using HMI.UI.DpUtil;
+using HMI.UI.Util;
+using Panuon.WPF.UI;
+using Plugin.DODriverControl.Entity;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+
+namespace Plugin.DODriverControl
+{
+ /// <summary>
+ /// ModalWindow.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ public partial class DataModal : WindowX
+ {
+ public DataModal()
+ {
+ this.DataContext = this;
+ InitializeComponent();
+ }
+
+ private string filePath;
+ public DIOData Data { get; set; }
+
+ private ObservableCollection<DIOData> Datasource;
+ private bool _isProcessing;
+
+ protected override void OnClosing(CancelEventArgs e)
+ {
+ //Press Continue Button
+ if (DialogResult == true)
+ {
+ if (_isProcessing)
+ {
+ e.Cancel = true;
+ return;
+ }
+ var okButton = WindowXModalDialog.GetOKButton(this);
+ try
+ {
+ _isProcessing = true;
+ ButtonHelper.SetIsPending(okButton, true);
+ if (!ValidateForm())
+ {
+ e.Cancel = true;
+ return;
+ }
+
+ SaveOrUpdateData();
+ }
+ catch (Exception ex)
+ {
+ ToastHelper.Error(this, $"Error锛亄ex.Message}");
+ e.Cancel = true;
+ return;
+ }
+ finally
+ {
+ _isProcessing = false;
+ ButtonHelper.SetIsPending(okButton, false);
+ }
+ }
+ base.OnClosing(e);
+ }
+
+ private bool ValidateName(object value, out string err)
+ {
+ err = null;
+ //string group = TbGroup.Text;
+ //var temp = Datasource.FirstOrDefault(d => d.Group == group && d.Name == value.ToString());
+ //if (temp != null && temp != Data)
+ //{
+ // err = this.lang("App.MustBeUnique", $"{this.lang("doc.group")},{this.lang("doc.name")}");
+ // return false;
+ //}
+ return true;
+ }
+
+ private bool ValidateAddress(object value, out string err)
+ {
+ err = null;
+ //string group = TbGroup.Text;
+ //var temp = Datasource.FirstOrDefault(d => d.Address == value.ToString());
+ //if (temp != null && temp != Data)
+ //{
+ // err = this.lang("App.MustBeUnique", this.lang("doc.Address"));
+ // return false;
+ //}
+ return true;
+ }
+
+ private bool ValidateForm()
+ {
+ bool flag = FormGroupHelper.ValidateForm(formPanel);
+ if (flag)
+ {
+ Data.Name = TbName.Text;
+ Data.Address = TbAddress.Text;
+ Data.Dio = (DIOType)CbDio.SelectedItem;
+ Data.PressDownValue = TbPressDownValue.Text;
+ Data.PressUpValue = TbPressUpValue.Text;
+ Data.PressDownText = TbPressDownText.Text;
+ Data.PressUpText = TbPressUpText.Text;
+
+ Data.ControlType = (ControlType)CbControlType.SelectedItem;
+ if (Data.ControlType == ControlType.BOOL)
+ {
+ Data.PressDownValue = true.ToString();
+ Data.PressUpValue = false.ToString();
+ }
+ }
+ return flag;
+ }
+
+ public bool? Open(DIOData data, ObservableCollection<DIOData> datasource, string filePath)
+ {
+ this.filePath = filePath;
+ Datasource = datasource;
+ Data = data;
+
+ TbName.Text = Data.Name;
+ TbAddress.Text = Data.Address;
+ CbDio.SelectedItem = Data.Dio;
+ TbPressDownValue.Text = Data.PressDownValue;
+ TbPressUpValue.Text = Data.PressUpValue;
+ TbPressDownText.Text = Data.PressDownText;
+ TbPressUpText.Text = Data.PressUpText;
+
+ CbControlType.SelectedItem = Data.ControlType;
+ return this.ShowDialog();
+ }
+
+ private void SaveOrUpdateData()
+ {
+ int index = -1;
+ if (Datasource != null)
+ {
+ index = Datasource.IndexOf(Data);
+ }
+ if (index < 0)
+ {
+ InsertData(Data);
+ }
+ else
+ {
+ UpdateData(index, Data);
+ }
+ }
+
+ public void InsertData(DIOData data)
+ {
+ Datasource.Add(data);
+ XmlHelper.SerializeToXml(filePath, Datasource);
+ }
+
+ public void UpdateData(int index, DIOData data)
+ {
+ var temp = XmlHelper.DeepClone(Datasource);
+ temp[index] = data;
+ XmlHelper.SerializeToXml(filePath, temp);
+ }
+
+ private void CbControlType_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
+ {
+ if ((ControlType)e.AddedItems[0] == ControlType.BOOL)
+ {
+ FgPressDownValue.Visibility = System.Windows.Visibility.Collapsed;
+ FgPressUpValue.Visibility = System.Windows.Visibility.Collapsed;
+ }
+ else
+ {
+ FgPressDownValue.Visibility = System.Windows.Visibility.Visible;
+ FgPressUpValue.Visibility = System.Windows.Visibility.Visible;
+ }
+ }
+ }
+}
diff --git a/Plugin.DODriverControl/Entity/ConfigData.cs b/Plugin.DODriverControl/Entity/ConfigData.cs
new file mode 100644
index 0000000..c13572c
--- /dev/null
+++ b/Plugin.DODriverControl/Entity/ConfigData.cs
@@ -0,0 +1,17 @@
+锘縩amespace Plugin.DODriverControl.Entity
+{
+ public enum ConfigType
+ {
+ ModBusTcp = 0,
+ PCI_7432 = 1,
+ OPCServer = 2
+ }
+
+ public class ConfigData
+ {
+ public ConfigType Type { get; set; }
+ public string IP { get; set; }
+ public string Port { get; set; }
+ public string Name { get; set; }
+ }
+}
diff --git a/Plugin.DODriverControl/Entity/DIOData.cs b/Plugin.DODriverControl/Entity/DIOData.cs
new file mode 100644
index 0000000..caf9739
--- /dev/null
+++ b/Plugin.DODriverControl/Entity/DIOData.cs
@@ -0,0 +1,89 @@
+锘縰sing HMI.Core;
+using HMI.Core.Entity;
+
+namespace Plugin.DODriverControl.Entity
+{
+ public enum ControlType
+ {
+ BOOL = 0,
+ BYTE = 1,
+ INT = 2,
+ UINT = 3,
+ DINT = 4,
+ UDINT = 5,
+ REAL = 6,
+ LREAL = 7,
+ TIME = 8,
+ WORD = 9,
+ STRING = 10,
+ WSTRING = 11,
+ PULSE = 12
+ }
+
+ public enum DIOType
+ {
+ DI = 0,
+ DO = 1
+ }
+ public class DIOData : SelectBase
+ {
+ /// <summary>
+ /// 鎺у埗鐐瑰悕绉�
+ /// </summary>
+ [ExcelColumn("doc.name")]
+ public string Name { get; set; }
+
+ [ExcelColumn("DI/O")]
+ public DIOType Dio { get; set; }
+
+ /// <summary>
+ /// 鍦板潃
+ /// </summary>
+ [ExcelColumn("doc.address")]
+ public string Address { get; set; }
+
+ //[ExcelColumn("doc.readOnly")]
+ //public bool ReadOnly { get; set; }
+
+ /// <summary>
+ /// 鍒嗙粍鍚嶇О
+ /// </summary>
+ //[ExcelColumn("doc.group")]
+ public string Group { get; set; }
+
+ /// <summary>
+ /// 鎸変笅鍊�
+ /// </summary>
+ [ExcelColumn("doc.pressDownValue")]
+ public string PressDownValue { get; set; }
+
+ /// <summary>
+ /// 鎶捣鍊�
+ /// </summary>
+ [ExcelColumn("doc.pressUpValue")]
+ public string PressUpValue { get; set; }
+
+ /// <summary>
+ /// 鎸変笅鍊�
+ /// </summary>
+ [ExcelColumn("doc.pressDownText")]
+ public string PressDownText { get; set; }
+
+ /// <summary>
+ /// 鎶捣鍊�
+ /// </summary>
+ [ExcelColumn("doc.pressUpText")]
+ public string PressUpText { get; set; }
+
+ /// <summary>
+ /// 鏄惁鍚敤
+ /// </summary>
+ public bool Enable { get; set; }
+
+ /// <summary>
+ /// 鎺у埗绫诲瀷
+ /// </summary>
+ [ExcelColumn("doc.controlType")]
+ public ControlType ControlType { get; set; }
+ }
+}
diff --git a/Plugin.DODriverControl/Plugin.DODriverControl.csproj b/Plugin.DODriverControl/Plugin.DODriverControl.csproj
new file mode 100644
index 0000000..cb21245
--- /dev/null
+++ b/Plugin.DODriverControl/Plugin.DODriverControl.csproj
@@ -0,0 +1,28 @@
+锘�<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <OutputType>Library</OutputType>
+ <TargetFramework>net472</TargetFramework>
+ <Nullable>enable</Nullable>
+ <LangVersion>10.0</LangVersion>
+ <ImplicitUsings>enable</ImplicitUsings>
+ <UseWPF>true</UseWPF>
+ <Platforms>AnyCPU;x64</Platforms>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
+ <PackageReference Include="log4net" Version="3.0.4" />
+ <PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.135" />
+ <PackageReference Include="Panuon.WPF.UI" Version="1.3.0.2" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\..\hslCommunicationV12.0.3甯︽簮鐮乨emo\HslCommunication\HslCommunication.csproj" />
+ <ProjectReference Include="..\HMI.Base\HMI.Base.csproj" />
+ <ProjectReference Include="..\HMI.Core\HMI.Core.csproj" />
+ <ProjectReference Include="..\HMI.UI\HMI.UI.csproj" />
+ <ProjectReference Include="..\HMI.Util\HMI.Util.csproj" />
+ </ItemGroup>
+
+</Project>
diff --git a/Plugin.DODriverControl/SingleControl.xaml b/Plugin.DODriverControl/SingleControl.xaml
new file mode 100644
index 0000000..e04d895
--- /dev/null
+++ b/Plugin.DODriverControl/SingleControl.xaml
@@ -0,0 +1,365 @@
+锘�<hb:SimpleMaskControl x:Class="Plugin.DODriverControl.SingleControl"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:local="clr-namespace:Plugin.DODriverControl"
+ mc:Ignorable="d"
+ xmlns:hb="clr-namespace:HMI.Base;assembly=HMI.Base"
+ xmlns:uic="clr-namespace:HMI.UI.Converter;assembly=HMI.UI"
+ xmlns:ui="clr-namespace:HMI.UI;assembly=HMI.UI"
+ xmlns:mdi="clr-namespace:HMI.UI.MDI;assembly=HMI.UI"
+ xmlns:pw="https://opensource.panuon.com/wpf"
+ xmlns:pu="https://opensource.panuon.com/wpf-ui"
+ xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
+ Background="#FFF"
+ Loaded="UserControl_Loaded"
+ d:DesignHeight="450" d:DesignWidth="800">
+ <hb:SimpleMaskControl.Resources>
+ <ResourceDictionary>
+ <ResourceDictionary.MergedDictionaries>
+ <pu:StyleDictionary Includes="TabControl" />
+ <ResourceDictionary Source="/HMI.UI;component/Style/PanuonListView.xaml"/>
+ </ResourceDictionary.MergedDictionaries>
+ <Style TargetType="GroupBox">
+ <Setter Property="FontSize" Value="14"/>
+ <Setter Property="HeaderTemplate">
+ <Setter.Value>
+ <DataTemplate>
+ <TextBlock Text="{Binding }" FontSize="12" TextWrapping="Wrap"/>
+ </DataTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style>
+ </ResourceDictionary>
+ </hb:SimpleMaskControl.Resources>
+ <Grid dp:GridHelper.Space="8">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition/>
+ </Grid.RowDefinitions>
+
+ <DockPanel>
+ <StackPanel dp:StackPanelHelper.ChildSpace="10" DockPanel.Dock="Right" Orientation="Horizontal">
+ <Button Style="{StaticResource AddBtn}" x:Name="addBtn" Click="Button_Click"/>
+ <Button Style="{StaticResource RfhBtn}" x:Name="rfhBtn" Click="Button_Click"/>
+ <Button Style="{StaticResource ExportBtn}" x:Name="exportBtn" Click="Button_Click"/>
+ <Button Style="{StaticResource ImportBtn}" x:Name="importBtn" Click="Button_Click"/>
+ <!--<Button Style="{StaticResource DelBtn}"/>-->
+ </StackPanel>
+
+ <StackPanel Orientation="Horizontal" VerticalAlignment="Center" dp:StackPanelHelper.ChildSpace="10">
+ <pu:FormGroup FontSize="18" Header="鎺у埗鍣ㄧ姸鎬�" Orientation="Horizontal">
+ <ui:LightBall Size="20" Value="{Binding ConnectStatus}">
+ <ui:LightBall.Style>
+ <Style TargetType="ui:LightBall">
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding ConnectStatus}" Value="True">
+ <Setter Property="Content" Value="宸茶繛鎺�"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding ConnectStatus}" Value="False">
+ <Setter Property="Content" Value="鏈繛鎺�"/>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </ui:LightBall.Style>
+ </ui:LightBall>
+ </pu:FormGroup>
+ <Button Style="{StaticResource ResetBtn}"
+ x:Name="reConnectBtn" Click="Button_Click" Content="閲嶆柊杩炴帴"
+ IsEnabled="{Binding ConnectStatus,Converter={StaticResource reverseBool}}"/>
+ <Button Style="{StaticResource SettingBtn}" x:Name="configBtn" Click="Button_Click"/>
+ </StackPanel>
+ </DockPanel>
+
+ <TabControl Grid.Row="1"
+pu:TabControlHelper.HeaderPanelAlignment="Stretch"
+pu:TabControlHelper.ItemsBackground="{DynamicResource VerBar}"
+pu:TabControlHelper.ItemsForeground="#FFFFFF"
+pu:TabControlHelper.ItemsFontSize="14"
+pu:TabControlHelper.ItemsHeight="30"
+pu:TabControlHelper.ItemsHorizontalHeaderAlignment="Left"
+pu:TabControlHelper.ItemsHoverBackground="{DynamicResource SecondPrimaryColor}"
+pu:TabControlHelper.ItemsHoverForeground="#FFFFFF"
+pu:TabControlHelper.ItemsPadding="20,0,0,0"
+pu:TabControlHelper.ItemsRibbonLineCornerRadius="4"
+pu:TabControlHelper.ItemsRibbonLineMargin="0,5,0,5"
+pu:TabControlHelper.ItemsRibbonLineThickness="4"
+pu:TabControlHelper.ItemsRibbonLineVisibility="Visible"
+pu:TabControlHelper.ItemsSelectedBackground="#FFF"
+pu:TabControlHelper.ItemsSelectedRibbonLineBrush="#FFFFFF"
+pu:TabControlHelper.ItemsSelectedRibbonLineThickness="2"
+pu:TabControlHelper.ItemsWidth="100" >
+ <TabControl.Template>
+ <ControlTemplate TargetType="{x:Type TabControl}">
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="*"/>
+ </Grid.RowDefinitions>
+ <Border BorderThickness="1,1,1,0" BorderBrush="#acacac" Background="{DynamicResource VerBar}" Padding="2,2,10,0">
+ <TabPanel x:Name="HeaderPanel" Grid.Row="0" Panel.ZIndex="1" IsItemsHost="True"/>
+ </Border>
+
+ <Border Grid.Row="1" BorderBrush="{TemplateBinding BorderBrush}"
+ BorderThickness="1,0,1,1" Background="{TemplateBinding Background}">
+ <ContentPresenter x:Name="PART_SelectedContentHost" ContentSource="SelectedContent"/>
+ </Border>
+ </Grid>
+ </ControlTemplate>
+ </TabControl.Template>
+
+ <TabItem Header="DIO">
+ <Grid dp:GridHelper.Space="5" Background="#f7f7f7">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition/>
+ </Grid.RowDefinitions>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition/>
+ <ColumnDefinition/>
+ </Grid.ColumnDefinitions>
+ <Label Grid.Row="0" Grid.Column="0">DI</Label>
+ <Label Grid.Row="0" Grid.Column="1">DO</Label>
+
+ <ScrollViewer Grid.Row="1" Grid.Column="0"
+ Style="{StaticResource DefaultScrollViewer}"
+ VerticalScrollBarVisibility="Auto">
+ <WrapPanel Background="#FFF" x:Name="diWrap"/>
+ </ScrollViewer>
+ <ScrollViewer Grid.Row="1" Grid.Column="1"
+ Style="{StaticResource DefaultScrollViewer}"
+ VerticalScrollBarVisibility="Auto">
+ <WrapPanel Background="#FFF" x:Name="doWrap"/>
+ </ScrollViewer>
+ </Grid>
+ </TabItem>
+ <TabItem Header="鍒楄〃">
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition/>
+ </Grid.RowDefinitions>
+ <ListView Grid.Row="1" Style="{StaticResource DefaultListTable}" x:Name="table"
+ ItemsSource="{Binding Datasource}"
+ VirtualizingPanel.IsContainerVirtualizable="True"
+VirtualizingPanel.IsVirtualizing="True"
+VirtualizingPanel.VirtualizationMode="Standard">
+ <ListView.Resources>
+ <Style x:Key="RowLink" TargetType="Button" BasedOn="{StaticResource LinkButton}">
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding Path=IsMouseOver,
+ RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ListViewItem,AncestorLevel=1}}"
+ Value="True">
+ <Setter Property="Foreground" Value="#FFF"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding Path=IsSelected,
+ RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ListViewItem,AncestorLevel=1}}"
+Value="True">
+ <Setter Property="Foreground" Value="#FFF"/>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+
+ <Style x:Key="DeleteLink" TargetType="Button" BasedOn="{StaticResource DangerLinkButton}">
+ <Setter Property="Content" Value="{DynamicResource App.Delete}"/>
+ </Style>
+
+ <Style x:Key="EditLink" TargetType="Button" BasedOn="{StaticResource RowLink}">
+ <Setter Property="Content" Value="{DynamicResource App.Edit}"/>
+ </Style>
+ </ListView.Resources>
+ <ListView.View>
+ <GridView AllowsColumnReorder="False">
+ <GridViewColumn Width="60" Header="#">
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <TextBlock Text="{Binding Converter={StaticResource lvRowNumber},
+RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ListViewItem,AncestorLevel=1}}"/>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+
+ <GridViewColumn Width="700">
+ <GridViewColumn.Header>
+ <TextBlock Text="{DynamicResource doc.name}"/>
+ </GridViewColumn.Header>
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <Border Style="{StaticResource CellBorder}">
+ <TextBlock Style="{StaticResource ListTableTextBlock}"
+ Text="{Binding Name}"/>
+ </Border>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+ <GridViewColumn Width="100">
+ <GridViewColumn.Header>
+ <TextBlock Text="{DynamicResource doc.address}"/>
+ </GridViewColumn.Header>
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <Border Style="{StaticResource CellBorder}">
+ <TextBlock Style="{StaticResource ListTableTextBlock}"
+ Text="{Binding Address}"/>
+ </Border>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+ <GridViewColumn Width="120">
+ <GridViewColumn.Header>
+ <TextBlock Text="DIO"/>
+ </GridViewColumn.Header>
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <Border Style="{StaticResource CellBorder}">
+ <TextBlock Style="{StaticResource ListTableTextBlock}"
+ Text="{Binding Dio}"/>
+ </Border>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+ <GridViewColumn Width="200">
+ <GridViewColumn.Header>
+ <TextBlock Text="{DynamicResource doc.pressDownValue}"/>
+ </GridViewColumn.Header>
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <Border Style="{StaticResource CellBorder}">
+ <TextBlock Style="{StaticResource ListTableTextBlock}"
+ Text="{Binding PressDownValue}"/>
+ </Border>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+ <GridViewColumn Width="200">
+ <GridViewColumn.Header>
+ <TextBlock Text="{DynamicResource doc.pressDownText}"/>
+ </GridViewColumn.Header>
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <Border Style="{StaticResource CellBorder}">
+ <TextBlock Style="{StaticResource ListTableTextBlock}"
+ Text="{Binding PressDownText}"/>
+ </Border>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+ <GridViewColumn Width="200">
+ <GridViewColumn.Header>
+ <TextBlock Text="{DynamicResource doc.pressUpValue}"/>
+ </GridViewColumn.Header>
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <Border Style="{StaticResource CellBorder}">
+ <TextBlock Style="{StaticResource ListTableTextBlock}"
+ Text="{Binding PressUpValue}"/>
+ </Border>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+ <GridViewColumn Width="200">
+ <GridViewColumn.Header>
+ <TextBlock Text="{DynamicResource doc.pressUpText}"/>
+ </GridViewColumn.Header>
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <Border Style="{StaticResource CellBorder}">
+ <TextBlock Style="{StaticResource ListTableTextBlock}"
+ Text="{Binding PressUpText}"/>
+ </Border>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+ <GridViewColumn Width="120">
+ <GridViewColumn.Header>
+ <TextBlock Text="{DynamicResource App.Opt}"/>
+ </GridViewColumn.Header>
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <StackPanel Orientation="Horizontal" dp:StackPanelHelper.ChildSpace="10">
+ <Button x:Name="editBtn" Style="{StaticResource EditLink}"
+ Click="Button_Click" Tag="{Binding }"/>
+
+ <Button x:Name="delBtn" Style="{StaticResource DeleteLink}"
+ Click="Button_Click" Tag="{Binding }"/>
+ </StackPanel>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+ </GridView>
+ </ListView.View>
+ </ListView>
+ <!--<DataGrid Grid.Row="1" Style="{StaticResource DefaultDataGrid}" ItemsSource="{Binding Datasource}">
+ <DataGrid.Columns>
+ <DataGridTemplateColumn Header="#" CanUserResize="False">
+ <DataGridTemplateColumn.CellTemplate>
+ <DataTemplate>
+ <TextBlock Text="{Binding Converter={StaticResource rowNumber},
+RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGridRow},AncestorLevel=1}}"/>
+ </DataTemplate>
+ </DataGridTemplateColumn.CellTemplate>
+ </DataGridTemplateColumn>
+ <DataGridTextColumn Width="*" Binding="{Binding Name}">
+ <DataGridTextColumn.Header>
+ <TextBlock Text="{DynamicResource doc.name}"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>
+ <DataGridTextColumn Width="*" Binding="{Binding Address}">
+ <DataGridTextColumn.Header>
+ <TextBlock Text="{DynamicResource doc.address}"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>
+ <DataGridTextColumn Width="*" Binding="{Binding Dio}">
+ <DataGridTextColumn.Header>
+ <TextBlock Text="DIO"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>
+
+ <DataGridTextColumn Width="*" Binding="{Binding PressDownValue}">
+ <DataGridTextColumn.Header>
+ <TextBlock Text="{DynamicResource doc.pressDownValue}"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>
+
+ <DataGridTextColumn Width="*" Binding="{Binding PressDownText}">
+ <DataGridTextColumn.Header>
+ <TextBlock Text="{DynamicResource doc.pressDownText}"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>
+
+ <DataGridTextColumn Width="*" Binding="{Binding PressUpValue}">
+ <DataGridTextColumn.Header>
+ <TextBlock Text="{DynamicResource doc.pressUpValue}"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>
+
+ <DataGridTextColumn Width="*" Binding="{Binding PressUpText}">
+ <DataGridTextColumn.Header>
+ <TextBlock Text="{DynamicResource doc.pressUpText}"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>
+
+ <DataGridTemplateColumn Width="110" IsReadOnly="True" CanUserResize="False">
+ <DataGridTemplateColumn.Header>
+ <TextBlock Text="{DynamicResource App.Opt}"/>
+ </DataGridTemplateColumn.Header>
+ <DataGridTemplateColumn.CellTemplate>
+ <DataTemplate>
+ <StackPanel Orientation="Horizontal" dp:StackPanelHelper.ChildSpace="10">
+ <Button x:Name="editBtn" Style="{StaticResource EditLink}"
+ Click="Button_Click" DataContext="{Binding }"/>
+
+ <Button x:Name="delBtn" Style="{StaticResource DeleteLink}"
+ Click="Button_Click" DataContext="{Binding }"/>
+ </StackPanel>
+ </DataTemplate>
+ </DataGridTemplateColumn.CellTemplate>
+ </DataGridTemplateColumn>
+ </DataGrid.Columns>
+ </DataGrid>-->
+ </Grid>
+ </TabItem>
+ </TabControl>
+ </Grid>
+</hb:SimpleMaskControl>
diff --git a/Plugin.DODriverControl/SingleControl.xaml.cs b/Plugin.DODriverControl/SingleControl.xaml.cs
new file mode 100644
index 0000000..0767cb0
--- /dev/null
+++ b/Plugin.DODriverControl/SingleControl.xaml.cs
@@ -0,0 +1,568 @@
+锘縰sing CommunityToolkit.Mvvm.ComponentModel;
+using HMI.Base;
+using HMI.Core.Util;
+using HMI.UI;
+using HMI.UI.Util;
+using HMI.Util;
+using log4net;
+using Microsoft.Win32;
+using Plugin.DODriverControl.Api;
+using Plugin.DODriverControl.Entity;
+using System.Collections.ObjectModel;
+using System.IO;
+using System.Timers;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Media;
+
+namespace Plugin.DODriverControl
+{
+ /// <summary>
+ /// SingleControl.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ [ObservableObject]
+ public partial class SingleControl : SimpleMaskControl
+ {
+ public SingleControl(string name, string baseFolder)
+ {
+ this.name = name;
+ this.baseFolder = Path.Combine(baseFolder, name);
+ if (!Directory.Exists(this.baseFolder)) Directory.CreateDirectory(this.baseFolder);
+ this.dataFilePath = Path.Combine(this.baseFolder, "data.xml");
+ this.configFilePath = Path.Combine(this.baseFolder, "config.xml");
+ this.DataContext = this;
+
+ refreshTimer = new System.Timers.Timer();
+ refreshTimer.Interval = 200;
+ refreshTimer.AutoReset = false;
+ refreshTimer.Elapsed += RefreshTimer_Elapsed;
+
+ InitializeComponent();
+
+ commonColor = Application.Current.FindResource("VerBar") as Brush;
+ successColor = Application.Current.FindResource("GreenVerBar") as Brush;
+ errorColor = Application.Current.FindResource("DangerVerBar") as Brush;
+ }
+
+ [ObservableProperty]
+ private bool connectStatus = false;
+ [ObservableProperty]
+ private ObservableCollection<DIOData> datasource = new ObservableCollection<DIOData>();
+
+ public ILog log { get; set; }
+ public string name { get; private set; }
+ public string baseFolder { get; private set; }
+
+
+ private IDIOController controller;
+ private string dataFilePath;
+ private string configFilePath;
+ private System.Timers.Timer refreshTimer;
+
+ private ConfigData config;
+
+ private List<FrameworkElement> doControls = new List<FrameworkElement>();
+
+ private Brush successColor;
+ private Brush errorColor;
+ private Brush commonColor;
+
+ private CancellationTokenSource cts = new CancellationTokenSource();
+
+ public void Active()
+ {
+ if (refreshTimer != null) refreshTimer.Enabled = true;
+ }
+
+ public void DeActive()
+ {
+ if (refreshTimer != null) refreshTimer.Enabled = false;
+ }
+
+ public void Close()
+ {
+ cts.Cancel();
+ ConnectStatus = false;
+ if (refreshTimer != null)
+ {
+ refreshTimer.Enabled = false;
+ refreshTimer.Elapsed -= RefreshTimer_Elapsed;
+ refreshTimer = null;
+ }
+ controller?.Dispose();
+ controller = null;
+ }
+
+ private void Button_Click(object sender, RoutedEventArgs e)
+ {
+ var btn = sender as Button;
+ var data = btn?.Tag as DIOData;
+ switch (btn.Name)
+ {
+ case "addBtn":
+ DoAddData();
+ break;
+ case "editBtn":
+ DoEditData(data);
+ break;
+ case "exportBtn":
+ DoExportExcel();
+ break;
+ case "importBtn":
+ DoImportExcel();
+ break;
+ case "reConnectBtn":
+ DoReconnect();
+ break;
+ case "configBtn":
+ DoOpenConfig();
+ break;
+ case "rfhBtn":
+ Refresh();
+ break;
+ case "delBtn":
+ DoDeleteData(data);
+ break;
+ default:
+ break;
+ }
+ }
+
+ private void DoAddData()
+ {
+ var win = new DataModal
+ {
+ Owner = Window.GetWindow(this),
+ Title = "鏂板"
+ };
+ if (win.Open(new DIOData(), Datasource, dataFilePath) == true)
+ {
+ ToastHelper.Success("娣诲姞鎴愬姛");
+ Refresh();
+ }
+ }
+
+ private void DoEditData(DIOData data)
+ {
+ var win = new DataModal
+ {
+ Owner = Window.GetWindow(this),
+ Title = "缂栬緫"
+ };
+ if (win.Open(data, Datasource, dataFilePath) == true)
+ {
+ ToastHelper.Success("缂栬緫鎴愬姛");
+ Refresh();
+ }
+ }
+
+ private void DoExportExcel()
+ {
+ try
+ {
+ SaveFileDialog sfd = new SaveFileDialog();
+ sfd.Filter = "Excel|*.xls";
+ if (sfd.ShowDialog() != true)
+ {
+ return;
+ }
+ string fileName = sfd.FileName;
+ ExcelHelper.ExportExcel(fileName, Datasource);
+ ToastHelper.Success("瀵煎嚭鎴愬姛");
+ }
+ catch (Exception ex)
+ {
+ log.Error("Export Error.", ex);
+ ToastHelper.Error($"瀵煎嚭澶辫触: {ex.Message}");
+ }
+ }
+
+ private void DoImportExcel()
+ {
+ try
+ {
+ OpenFileDialog ofd = new OpenFileDialog();
+ ofd.Filter = "Excel|*.xls";
+ if (ofd.ShowDialog() != true)
+ {
+ return;
+ }
+ string fileName = ofd.FileName;
+ List<DIOData> datas = ExcelHelper.ReadFromExcel<DIOData>(fileName);
+ //foreach (var data in datas)
+ //{
+ // Datasource.Add(data);
+ //}
+ Datasource = new ObservableCollection<DIOData>(datas);
+ SaveDatasourceToXml();
+ ToastHelper.Success("瀵煎叆鎴愬姛");
+ RefreshDOControl();
+ }
+ catch (Exception ex)
+ {
+ log.Error("Export Error.", ex);
+ ToastHelper.Error($"瀵煎叆澶辫触: {ex.Message}");
+ }
+ }
+
+ private void DoReconnect()
+ {
+ ConnectStatus = false;
+ ShowMask(() =>
+ {
+ refreshTimer.Enabled = false;
+ controller?.Close();
+ controller = CreateController();
+ var res = controller.Start(out string msg);
+ if (!res)
+ {
+ throw new Exception($"{msg}");
+ }
+ refreshTimer.Enabled = true;
+ Dispatcher.BeginInvoke(new Action(() =>
+ {
+ ConnectStatus = true;
+ }));
+ }, (ex) =>
+ {
+ controller = null;
+ log.Error("Reconnect Error.", ex);
+ Dispatcher.BeginInvoke(new Action(() =>
+ {
+ MsgBoxHelper.Error(this, $"杩炴帴澶辫触锛歿ex.Message}");
+ }));
+ }, "璇风◢鍊�", "姝e湪閲嶈繛...");
+ }
+
+ private void DoOpenConfig()
+ {
+ ConfigModal modal = new ConfigModal
+ {
+ Title = "璁剧疆",
+ Owner = Window.GetWindow(this)
+ };
+ if (modal.Open(config) == true)
+ {
+ config = modal.config;
+ SaveConfigToXml();
+ DoReconnect();
+ }
+ }
+
+ private void DoDeleteData(DIOData data)
+ {
+ if (MsgBoxHelper.WarnMessage(Window.GetWindow(this), "纭畾瑕佸垹闄ら�変腑鐨勬暟鎹悧锛�") == MessageBoxResult.OK)
+ {
+ int index = Datasource.IndexOf(data);
+ if (index < 0) return;
+ Datasource.RemoveAt(index);
+ SaveDatasourceToXml();
+ ToastHelper.Success("鍒犻櫎鎴愬姛");
+ RefreshDOControl();
+ }
+ }
+
+ private void SaveConfigToXml()
+ {
+ XmlHelper.SerializeToXml(configFilePath, config);
+ }
+
+ private void SaveDatasourceToXml()
+ {
+ XmlHelper.SerializeToXml(dataFilePath, Datasource);
+ }
+
+ private void RefreshDOControl()
+ {
+ try
+ {
+ refreshTimer.Enabled = false;
+ diWrap.Children.Clear();
+ doWrap.Children.Clear();
+ doControls.Clear();
+ foreach (var data in Datasource)
+ {
+ var fg = new GroupBox
+ {
+ //Header = $"{data.Name} 鍦板潃:{data.Address}",
+ Header = string.IsNullOrEmpty(data.Name)?"棰勭暀":data.Name,// $"{data.Name}",
+ Content = CreateButton(data),
+ Height = 80,
+ Width = 180
+ };
+ doControls.Add((FrameworkElement)fg.Content);
+ if (data.Dio == DIOType.DI)
+ {
+ diWrap.Children.Add(fg);
+ }
+ else
+ {
+ doWrap.Children.Add(fg);
+ }
+ }
+ }
+ finally
+ {
+ refreshTimer.Enabled = true;
+ }
+ }
+
+ private FrameworkElement CreateButton(DIOData data)
+ {
+ if (data.Dio == DIOType.DI)
+ {
+ return new LightBall
+ {
+ Size = 40,
+ DataContext = data
+ };
+ }
+ Style btnStyle = this.FindResource("PrimaryButton") as Style;
+ var btn = new Button
+ {
+ DataContext = data,
+ Style = btnStyle,
+ MinWidth = 120,
+ MinHeight = 40
+ };
+ btn.Click += ControlButton_Click;
+ return btn;
+ }
+
+ private void ControlButton_Click(object sender, RoutedEventArgs args)
+ {
+ if (!ConnectStatus)
+ {
+ ToastHelper.Error("璇峰厛杩炴帴鎺у埗鍣�");
+ return;
+ }
+ Button btn = sender as Button;
+ DIOData data = btn.DataContext as DIOData;
+ try
+ {
+ refreshTimer.Enabled = false;
+ var value = btn.Content?.ToString();
+ string val = value == data.PressDownText ? data.PressUpValue : data.PressDownValue;
+ var res = controller.WriteBool(data.Address, bool.Parse(val), out string msg);
+ if (!res) throw new Exception(msg);
+ }
+ catch (Exception ex)
+ {
+ log.Error("ControlButton_Click", ex);
+ ToastHelper.Error($"{data.Name}: {ex.Message}");
+ }
+ finally
+ {
+ refreshTimer.Enabled = true;
+ }
+ }
+
+ private void Refresh()
+ {
+ try
+ {
+ if (!File.Exists(dataFilePath))
+ {
+ Datasource = new ObservableCollection<DIOData>();
+ }
+ else
+ {
+ Datasource = XmlHelper.DeserializeFromXml<ObservableCollection<DIOData>>(dataFilePath);
+ }
+ }
+ catch (Exception ex)
+ {
+ log.Error("Load Data Error.", ex);
+ Datasource = new ObservableCollection<DIOData>();
+ }
+ RefreshDOControl();
+ }
+
+ private void UserControl_Loaded(object sender, RoutedEventArgs e)
+ {
+ ShowMask(() =>
+ {
+ try
+ {
+ if (!File.Exists(configFilePath))
+ {
+ config = new ConfigData
+ {
+ Type = ConfigType.ModBusTcp,
+ IP = "127.0.0.1",
+ Port = "502"
+ };
+ }
+ else
+ {
+ config = XmlHelper.DeserializeFromXml<ConfigData>(configFilePath);
+ }
+ }
+ catch (Exception ex)
+ {
+ log.Error("Load Config Error.", ex);
+ config = new ConfigData
+ {
+ Type = ConfigType.ModBusTcp,
+ IP = "127.0.0.1",
+ Port = "502"
+ };
+ }
+ var datasource = new ObservableCollection<DIOData>();
+ var connectStatus = false;
+ try
+ {
+ if (File.Exists(dataFilePath))
+ {
+ datasource = XmlHelper.DeserializeFromXml<ObservableCollection<DIOData>>(dataFilePath);
+ }
+ }
+ catch (Exception ex)
+ {
+ log.Error("Load Data Error.", ex);
+ }
+
+ try
+ {
+ controller = CreateController();
+ var res = controller.Start(out string msg);
+ if (!res)
+ {
+ throw new Exception($"鎺у埗鍣ㄨ繛鎺ュけ璐�: {msg}");
+ }
+ connectStatus = true;
+ }
+ catch (Exception ex)
+ {
+ controller = null;
+ log.Error("Modbus Connect Error.", ex);
+ connectStatus = false;
+ }
+
+ Dispatcher.BeginInvoke(new Action(() =>
+ {
+ ConnectStatus = connectStatus;
+ Datasource = datasource;
+ RefreshDOControl();
+ refreshTimer.Enabled = true;
+ this.Loaded -= UserControl_Loaded;
+ }));
+ }, null, "璇风◢鍚�", "鍔犺浇涓�...");
+ }
+
+ public IDIOController CreateController()
+ {
+ switch (config.Type)
+ {
+ case ConfigType.ModBusTcp:
+ return new ModBusTcpController
+ {
+ Ip = config.IP,
+ Port = int.Parse(config.Port),
+ };
+ case ConfigType.PCI_7432:
+ return new PCIController
+ {
+ Name = "PCI_7432",
+ };
+ default:
+ return null;
+ }
+ }
+
+ private void RefreshTimer_Elapsed(object sender, ElapsedEventArgs e)
+ {
+ bool isConnected = ConnectStatus;
+ if (!isConnected) return;
+ try
+ {
+ refreshTimer.Enabled = false;
+ if (cts.IsCancellationRequested)
+ {
+ isConnected = false;
+ return;
+ }
+
+ for (int i = doControls.Count - 1; i >= 0; i--)
+ {
+ var ui = doControls[i];
+ ui.Dispatcher.Invoke(() =>
+ {
+ DIOData data = ui.DataContext as DIOData;
+ if (data == null) return;
+ isConnected = GetValueByModbusTcp(data, out string value);
+ if (!isConnected) return;
+ switch (data.ControlType)
+ {
+ case ControlType.BOOL:
+ if (data.Dio == DIOType.DI)
+ {
+ ((LightBall)ui).Value = value == data.PressDownValue;
+ ((LightBall)ui).Content = value == data.PressDownValue ? data.PressDownText : data.PressUpText;
+ }
+ else
+ {
+ var color = value == data.PressDownValue ? successColor : errorColor;
+ ((Button)ui).Background = color;
+ ((Button)ui).Content = value == data.PressDownValue ? data.PressDownText : data.PressUpText;
+ }
+ break;
+ case ControlType.INT:
+ case ControlType.WORD:
+ case ControlType.REAL:
+ case ControlType.LREAL:
+ case ControlType.STRING:
+ case ControlType.WSTRING:
+ ((Button)ui).Content = value;
+ break;
+ default:
+ break;
+ }
+ });
+ }
+ }
+ catch (TaskCanceledException ex)
+ {
+ isConnected = false;
+ }
+ finally
+ {
+ if (isConnected && ConnectStatus) refreshTimer.Enabled = true;
+ else ConnectStatus = false;
+ }
+ }
+
+ private bool GetValueByModbusTcp(DIOData data, out string value)
+ {
+ if (controller == null)
+ {
+ value = null;
+ return false;
+ }
+ switch (data.ControlType)
+ {
+ case ControlType.BOOL:
+ bool val = false;
+ bool res = false;
+ if (data.Dio == DIOType.DI)
+ {
+ res = controller.ReadDIBool(data.Address, out val, out string msg);
+ }
+ else
+ {
+ res = controller.ReadDOBool(data.Address, out val, out string msg);
+ }
+ if (res == true)
+ {
+ value = val.ToString();
+ return true;
+ }
+ value = null;
+ return false;
+ default:
+ value = null;
+ return true;
+ }
+ }
+ }
+}
diff --git a/Plugin.DataBoard/DataBoard.xaml.cs b/Plugin.DataBoard/DataBoard.xaml.cs
index d820e13..099edc3 100644
--- a/Plugin.DataBoard/DataBoard.xaml.cs
+++ b/Plugin.DataBoard/DataBoard.xaml.cs
@@ -197,7 +197,7 @@
}
else if (snStatusCache[data.sn] == "Passed" && data.status == "Passed")
{
- oneTimePass--;
+ if (oneTimePass > 0) oneTimePass--;
}
}
else
diff --git a/Plugin.JarUI/JarUI.xaml b/Plugin.JarUI/JarUI.xaml
index b0a870c..74be2e1 100644
--- a/Plugin.JarUI/JarUI.xaml
+++ b/Plugin.JarUI/JarUI.xaml
@@ -11,7 +11,7 @@
xmlns:pu="https://opensource.panuon.com/wpf-ui"
xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
Background="#FFF"
- Loaded="PluginControl_Loaded"
+ Loaded="PluginControl_Loaded"
d:DesignHeight="450" d:DesignWidth="800">
<Border Style="{StaticResource CardBoarder}" Padding="0">
<Grid dp:GridHelper.Space="5">
diff --git a/Plugin.JarUI/JarUI.xaml.cs b/Plugin.JarUI/JarUI.xaml.cs
index 4313b08..6ee24d7 100644
--- a/Plugin.JarUI/JarUI.xaml.cs
+++ b/Plugin.JarUI/JarUI.xaml.cs
@@ -14,7 +14,6 @@
using System.IO;
using System.IO.Ports;
using System.Linq;
-using System.Reflection;
using System.Windows;
using System.Windows.Controls;
@@ -592,7 +591,7 @@
try
{
- log.Info($"Event: {EventCase}, NumericData: {MethodCode}, StringData: {strData}");
+ //log.Info($"Event: {EventCase}, NumericData: {MethodCode}, StringData: {strData}");
}
catch
{
diff --git a/Plugin.MaterialOpt/AssemblyInfo.cs b/Plugin.MaterialOpt/AssemblyInfo.cs
new file mode 100644
index 0000000..cc29e7f
--- /dev/null
+++ b/Plugin.MaterialOpt/AssemblyInfo.cs
@@ -0,0 +1,10 @@
+using System.Windows;
+
+[assembly:ThemeInfo(
+ ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
+ //(used if a resource is not found in the page,
+ // or application resource dictionaries)
+ ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
+ //(used if a resource is not found in the page,
+ // app, or any theme specific resource dictionaries)
+)]
diff --git a/Plugin.MaterialOpt/MaterialOpt.xaml b/Plugin.MaterialOpt/MaterialOpt.xaml
new file mode 100644
index 0000000..4c7106b
--- /dev/null
+++ b/Plugin.MaterialOpt/MaterialOpt.xaml
@@ -0,0 +1,251 @@
+锘�<hb:SimpleControl x:Class="Plugin.MaterialOpt.MaterialOpt"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:local="clr-namespace:Plugin.MaterialOpt"
+ mc:Ignorable="d"
+ xmlns:hb="clr-namespace:HMI.Base;assembly=HMI.Base"
+ xmlns:uic="clr-namespace:HMI.UI.Converter;assembly=HMI.UI"
+ xmlns:ui="clr-namespace:HMI.UI;assembly=HMI.UI"
+ xmlns:pw="https://opensource.panuon.com/wpf"
+ xmlns:pu="https://opensource.panuon.com/wpf-ui"
+ xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
+ Loaded="SimpleControl_Loaded"
+ d:DesignHeight="450" d:DesignWidth="800">
+ <hb:SimpleControl.Resources>
+ <ResourceDictionary>
+ <ResourceDictionary.MergedDictionaries>
+ <ResourceDictionary Source="/HMI.UI;component/Style/PanuonDataGrid.xaml"/>
+ <pu:StyleDictionary Includes="TabControl" />
+ </ResourceDictionary.MergedDictionaries>
+ </ResourceDictionary>
+ </hb:SimpleControl.Resources>
+ <Grid>
+ <Border Style="{StaticResource CardBoarder}">
+ <Grid dp:GridHelper.Space="10" Cursor="">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition/>
+ </Grid.RowDefinitions>
+
+ <TextBlock FontSize="{StaticResource TitleFontSize}"
+VerticalAlignment="Center" HorizontalAlignment="Left" Text="鐗╂枡鎿嶄綔"/>
+ <TabControl Grid.Row="1"
+ pu:TabControlHelper.HeaderPanelAlignment="Stretch"
+ pu:TabControlHelper.ItemsBackground="{DynamicResource VerBar}"
+ pu:TabControlHelper.ItemsForeground="#FFFFFF"
+ pu:TabControlHelper.ItemsFontSize="14"
+ pu:TabControlHelper.ItemsHeight="30"
+ pu:TabControlHelper.ItemsHorizontalHeaderAlignment="Left"
+ pu:TabControlHelper.ItemsHoverBackground="{DynamicResource SecondPrimaryColor}"
+ pu:TabControlHelper.ItemsHoverForeground="#FFFFFF"
+ pu:TabControlHelper.ItemsPadding="20,0,0,0"
+ pu:TabControlHelper.ItemsRibbonLineCornerRadius="4"
+ pu:TabControlHelper.ItemsRibbonLineMargin="0,5,0,5"
+ pu:TabControlHelper.ItemsRibbonLineThickness="4"
+ pu:TabControlHelper.ItemsRibbonLineVisibility="Visible"
+ pu:TabControlHelper.ItemsSelectedBackground="#FFF"
+ pu:TabControlHelper.ItemsSelectedRibbonLineBrush="#FFFFFF"
+ pu:TabControlHelper.ItemsSelectedRibbonLineThickness="2"
+ pu:TabControlHelper.ItemsWidth="150" >
+ <TabControl.Template>
+ <ControlTemplate TargetType="{x:Type TabControl}">
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="*"/>
+ </Grid.RowDefinitions>
+ <Border BorderThickness="1,1,1,0" BorderBrush="#acacac" Background="{DynamicResource VerBar}" Padding="10,5,10,0">
+ <TabPanel x:Name="HeaderPanel" Grid.Row="0" Panel.ZIndex="1" IsItemsHost="True"/>
+ </Border>
+
+ <Border Grid.Row="1" BorderBrush="{TemplateBinding BorderBrush}"
+ BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
+ <ContentPresenter x:Name="PART_SelectedContentHost" ContentSource="SelectedContent"/>
+ </Border>
+ </Grid>
+ </ControlTemplate>
+ </TabControl.Template>
+ <TabItem Header="缁戝畾">
+ <Grid dp:GridHelper.Space="5">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition/>
+ </Grid.RowDefinitions>
+ <DockPanel Grid.Row="0" Cursor="">
+ <StackPanel DockPanel.Dock="Right" Style="{StaticResource ButtonGroup}">
+ <Button Style="{StaticResource RfhBtn}" Content="缁戝畾"
+ x:Name="bindBtn" Click="Button_Click"/>
+
+ <Button Style="{StaticResource EditBtn}"
+ pu:ButtonHelper.Icon="" Content="鏌ヨ"
+ x:Name="bindQryBtn" Click="Button_Click"/>
+
+ </StackPanel>
+
+ <StackPanel Style="{StaticResource ButtonGroup}" HorizontalAlignment="Left" dp:StackPanelHelper.ChildSpace="10">
+ <TextBlock Style="{StaticResource TitleBox}" FontSize="14" Text="浜у搧搴忓垪鍙�"/>
+ <TextBox Style="{StaticResource EditorTextBoxStyle}" Width="180"
+ Text="{Binding CurrentProductSN,UpdateSourceTrigger=PropertyChanged}" />
+
+
+ <TextBlock Style="{StaticResource TitleBox}" FontSize="14" Text="鐗╂枡鏉$爜"/>
+ <TextBox Style="{StaticResource EditorTextBoxStyle}" Width="180"
+ Text="{Binding CurrentMaterialSN,UpdateSourceTrigger=PropertyChanged}" />
+
+ <!--<TextBlock Style="{StaticResource TitleBox}" FontSize="14" Text="鐗╂枡鍚嶇О"/>
+ <TextBox Style="{StaticResource EditorTextBoxStyle}" Width="180"
+ Text="{Binding CurrentMaterialName,UpdateSourceTrigger=PropertyChanged}" />-->
+
+ <TextBlock Style="{StaticResource TitleBox}" FontSize="14" Text="宸ョ珯"/>
+ <ComboBox Style="{StaticResource FormComboxStyle}" Width="180"
+ ItemsSource="{Binding WorkstationSource}"
+ SelectedItem="{Binding CurrentWorkstation,Mode=TwoWay}"
+ SelectedValuePath="Content"/>
+ </StackPanel>
+ </DockPanel>
+
+ <DataGrid Grid.Row="1" x:Name="table"
+ SelectionChanged="table_SelectionChanged"
+ Style="{StaticResource DefaultDataGrid}">
+ <DataGrid.Columns>
+ <DataGridTemplateColumn Header="#" CanUserResize="False">
+ <DataGridTemplateColumn.CellTemplate>
+ <DataTemplate>
+ <TextBlock Text="{Binding Converter={StaticResource rowNumber},
+RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGridRow},AncestorLevel=1}}"/>
+ </DataTemplate>
+ </DataGridTemplateColumn.CellTemplate>
+ </DataGridTemplateColumn>
+ <DataGridTextColumn Width="*" Binding="{Binding ProductSN}">
+ <DataGridTextColumn.Header>
+ <TextBlock Text="浜у搧搴忓垪鍙�"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>
+ <DataGridTextColumn Width="*" Binding="{Binding MaterialSN}">
+ <DataGridTextColumn.Header>
+ <TextBlock Text="鐗╂枡鏉$爜"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>
+ <!--<DataGridTextColumn Width="*" Binding="{Binding MaterialName}">
+ <DataGridTextColumn.Header>
+ <TextBlock Text="鐗╂枡鍚嶇О"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>-->
+ <DataGridTextColumn Width="*" Binding="{Binding Workstation}">
+ <DataGridTextColumn.Header>
+ <TextBlock Text="{DynamicResource cm.workstation}"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>
+ <DataGridTextColumn Width="*" Binding="{Binding Time}">
+ <DataGridTextColumn.Header>
+ <TextBlock Text="鏃堕棿"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>
+ <!--<DataGridTemplateColumn Width="110" IsReadOnly="True" CanUserResize="False">
+ <DataGridTemplateColumn.Header>
+ <TextBlock Text="{DynamicResource App.Opt}"/>
+ </DataGridTemplateColumn.Header>
+ <DataGridTemplateColumn.CellTemplate>
+ <DataTemplate>
+ <StackPanel Orientation="Horizontal">
+ <Button x:Name="rowUnBindBtn" Style="{StaticResource EditLink}"
+ Content="瑙g粦" Click="Button_Click" DataContext="{Binding Row}"/>
+ </StackPanel>
+ </DataTemplate>
+ </DataGridTemplateColumn.CellTemplate>
+ </DataGridTemplateColumn>-->
+ </DataGrid.Columns>
+ </DataGrid>
+ </Grid>
+ </TabItem>
+ <TabItem Header="瑙g粦">
+ <Grid dp:GridHelper.Space="5">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition/>
+ </Grid.RowDefinitions>
+ <DockPanel Grid.Row="0" Cursor="">
+ <StackPanel DockPanel.Dock="Right" Style="{StaticResource ButtonGroup}">
+ <Button Style="{StaticResource EditBtn}" Content="瑙g粦" x:Name="unbindBtn" Click="Button_Click"/>
+
+ <Button Style="{StaticResource EditBtn}"
+ pu:ButtonHelper.Icon=""
+ Content="鏌ヨ" x:Name="unbindQryBtn" Click="Button_Click"/>
+
+ </StackPanel>
+
+ <StackPanel Style="{StaticResource ButtonGroup}" HorizontalAlignment="Left" dp:StackPanelHelper.ChildSpace="10">
+ <TextBlock Style="{StaticResource TitleBox}" FontSize="14" Text="浜у搧搴忓垪鍙�"/>
+ <TextBox Style="{StaticResource EditorTextBoxStyle}" Width="180"
+ Text="{Binding CurrentProductSN,UpdateSourceTrigger=PropertyChanged}" />
+
+
+ <TextBlock Style="{StaticResource TitleBox}" FontSize="14" Text="鐗╂枡鏉$爜"/>
+ <TextBox Style="{StaticResource EditorTextBoxStyle}" Width="180"
+ Text="{Binding CurrentMaterialSN,UpdateSourceTrigger=PropertyChanged}" />
+
+ <!--<TextBlock Style="{StaticResource TitleBox}" FontSize="14" Text="鐗╂枡鍚嶇О"/>
+ <TextBox Style="{StaticResource EditorTextBoxStyle}" Width="180" Text="{Binding CurrentMaterialName}" />-->
+ </StackPanel>
+ </DockPanel>
+
+ <DataGrid Grid.Row="1" x:Name="unbindTable" Style="{StaticResource DefaultDataGrid}">
+ <DataGrid.Columns>
+ <DataGridTemplateColumn Header="#" CanUserResize="False">
+ <DataGridTemplateColumn.CellTemplate>
+ <DataTemplate>
+ <TextBlock Text="{Binding Converter={StaticResource rowNumber},
+RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGridRow},AncestorLevel=1}}"/>
+ </DataTemplate>
+ </DataGridTemplateColumn.CellTemplate>
+ </DataGridTemplateColumn>
+ <DataGridTextColumn Width="*" Binding="{Binding ProductSN}">
+ <DataGridTextColumn.Header>
+ <TextBlock Text="浜у搧搴忓垪鍙�"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>
+ <DataGridTextColumn Width="*" Binding="{Binding MaterialSN}">
+ <DataGridTextColumn.Header>
+ <TextBlock Text="鐗╂枡鏉$爜"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>
+ <!--<DataGridTextColumn Width="*" Binding="{Binding MaterialName}">
+ <DataGridTextColumn.Header>
+ <TextBlock Text="鐗╂枡鍚嶇О"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>
+ <DataGridTextColumn Width="*" Binding="{Binding Workstation}">
+ <DataGridTextColumn.Header>
+ <TextBlock Text="{DynamicResource cm.workstation}"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>-->
+ <DataGridTextColumn Width="*" Binding="{Binding Time}">
+ <DataGridTextColumn.Header>
+ <TextBlock Text="鏃堕棿"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>
+ <!--<DataGridTemplateColumn Width="110" IsReadOnly="True" CanUserResize="False">
+ <DataGridTemplateColumn.Header>
+ <TextBlock Text="{DynamicResource App.Opt}"/>
+ </DataGridTemplateColumn.Header>
+ <DataGridTemplateColumn.CellTemplate>
+ <DataTemplate>
+ <StackPanel Orientation="Horizontal">
+ <Button x:Name="rowReBindBtn" Style="{StaticResource EditLink}"
+ Content="閲嶆柊缁戝畾" Click="Button_Click" DataContext="{Binding }"/>
+ </StackPanel>
+ </DataTemplate>
+ </DataGridTemplateColumn.CellTemplate>
+ </DataGridTemplateColumn>-->
+ </DataGrid.Columns>
+ </DataGrid>
+ </Grid>
+ </TabItem>
+ </TabControl>
+ </Grid>
+ </Border>
+ <ui:MaskControl x:Name="mask"/>
+ </Grid>
+</hb:SimpleControl>
diff --git a/Plugin.MaterialOpt/MaterialOpt.xaml.cs b/Plugin.MaterialOpt/MaterialOpt.xaml.cs
new file mode 100644
index 0000000..cc4c5f0
--- /dev/null
+++ b/Plugin.MaterialOpt/MaterialOpt.xaml.cs
@@ -0,0 +1,429 @@
+锘縰sing CommunityToolkit.Mvvm.ComponentModel;
+using HMI.Base;
+using HMI.Core.Entity;
+using HMI.Core.Manager;
+using HMI.Core.Util;
+using HMI.UI.Util;
+using LSMSInterface;
+using Newtonsoft.Json.Linq;
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Web.SessionState;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Data;
+using System.Windows.Media.Media3D;
+
+namespace Plugin.MaterialOpt
+{
+ /// <summary>
+ /// MaterialOpt.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ [ObservableObject]
+ public partial class MaterialOpt : SimpleControl
+ {
+ public MaterialOpt()
+ {
+ DataContext = this;
+ api = new LSMSApi();
+ InitializeComponent();
+ }
+
+ [ObservableProperty]
+ private string currentProductSN;
+ [ObservableProperty]
+ private string currentMaterialSN;
+ [ObservableProperty]
+ private string currentMaterialName;
+ [ObservableProperty]
+ private string currentWorkstation;
+ [ObservableProperty]
+ private ObservableCollection<string> workstationSource;
+
+ private string lineName;
+ private string mesIp;
+ private int mesPort;
+ private LSMSApi api;
+ private bool isMesConnected = false;
+ private SqliteHelper sqliteHelper;
+
+ public override void InitFinish()
+ {
+ base.InitFinish();
+ ParameterData parameter;
+ try
+ {
+ parameter = ParameterManager.GetCommonParameterByName("MesIp");
+ mesIp = parameter.Value;
+ }
+ catch
+ {
+ mesIp = "127.0.0.1";
+ }
+ try
+ {
+ parameter = ParameterManager.GetCommonParameterByName("MesPort");
+ mesPort = int.Parse(parameter.Value);
+ }
+ catch
+ {
+ mesPort = 9909;
+ }
+
+ try
+ {
+ parameter = ParameterManager.GetCommonParameterByName("LineName");
+ lineName = parameter.Value;
+ }
+ catch
+ {
+ lineName = string.Empty;
+ }
+
+ //try
+ //{
+ // parameter = ParameterManager.GetCommonParameterByName("ChangeModelByWorkOrder");
+ // var res = bool.Parse(parameter.Value);
+ // if (res) WorkOrderVisiable = Visibility.Visible;
+ //}
+ //catch
+ //{
+ // WorkOrderVisiable = Visibility.Collapsed;
+ //}
+
+ try
+ {
+ var dbPath = Path.Combine(BaseFolder, "MaterialOpt.db");
+ if (!File.Exists(dbPath))
+ {
+ SqliteHelper.CreateDatabase(dbPath);
+ }
+ sqliteHelper = new SqliteHelper(dbPath);
+ sqliteHelper.ExecuteSql(@"CREATE TABLE IF NOT EXISTS bind_record (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ ProductSN TEXT NOT NULL,
+ MaterialSN TEXT NOT NULL,
+ MaterialName TEXT ,
+ Workstation TEXT ,
+ Time TIME);");
+ sqliteHelper.ExecuteSql(@"CREATE TABLE IF NOT EXISTS unbind_record (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ ProductSN TEXT NOT NULL,
+ MaterialSN TEXT NOT NULL,
+ MaterialName TEXT ,
+ Workstation TEXT ,
+ Time TIME);");
+ }
+ catch (Exception ex)
+ {
+ log.Error("Init MaterialOpt DB Failed.", ex);
+ }
+ }
+
+ public override void Active()
+ {
+ base.Active();
+ //if (!isMesConnected)
+ //{
+ // ConnectMes();
+ // RefreshWorkstationSource();
+ //}
+ }
+
+ public void ConnectMes()
+ {
+ string msg = string.Empty;
+ try
+ {
+ if (api.Connect(this.mesIp, this.mesPort, ref msg))
+ {
+ isMesConnected = true;
+ }
+ else
+ {
+ throw new Exception(msg);
+ }
+ }
+ catch (Exception ex)
+ {
+ isMesConnected = false;
+ log.Error("ConnectMes Failed.", ex);
+ MsgBoxHelper.Error(Window.GetWindow(this), this.lang("cm.mesConnectFail", ex.Message));
+ }
+ }
+ private bool PingMes(out string errMsg)
+ {
+ errMsg = string.Empty;
+ if (!isMesConnected)
+ {
+ errMsg = "MES鏈繛鎺ワ紝璇峰厛杩炴帴MES";
+ return false;
+ }
+ try
+ {
+ if (!api.IsConnect(ref errMsg))
+ {
+ isMesConnected = false;
+ return false;
+ }
+ return true;
+ }
+ catch (Exception ex)
+ {
+ errMsg = ex.Message;
+ isMesConnected = false;
+ return false;
+ }
+ }
+
+ private void RefreshWorkstationSource()
+ {
+ string errMsg = string.Empty;
+ try
+ {
+ if (api.Connect(mesIp, mesPort, ref errMsg))
+ {
+ string lineStr = api.GetAllStationByCurrentLine(lineName, out errMsg);
+ JObject res = (JObject)JsonConvert.DeserializeObject(lineStr);
+ string stations = res["WorkStations"]?.ToString();
+ if (string.IsNullOrEmpty(stations))
+ {
+ WorkstationSource = new ObservableCollection<string>();
+ }
+ else
+ {
+ WorkstationSource = new ObservableCollection<string>(stations.Split(','));
+ }
+ }
+ else
+ {
+ MsgBoxHelper.ErrorMessage(this, $"杩炴帴鏈嶅姟鍣ㄥけ璐�: {errMsg}");
+ }
+ }
+ catch (Exception ex)
+ {
+ MsgBoxHelper.ErrorMessage(this, $"缁戝畾澶辫触: {errMsg}");
+ }
+ finally
+ {
+ api.DisConnect(ref errMsg);
+ }
+ }
+
+ private void Button_Click(object sender, RoutedEventArgs e)
+ {
+ var btn = sender as Button;
+ switch (btn.Name)
+ {
+ case "bindBtn":
+ BindMaterial();
+ break;
+ case "bindQryBtn":
+ mask.ShowMask(this, RefreshBindLog, null, "璇风◢鍚�", "姝e湪鏌ヨ...");
+ break;
+ case "unbindBtn":
+ UnBindMaterial();
+ break;
+ case "unbindQryBtn":
+ mask.ShowMask(this, RefreshUnBindLog, null, "璇风◢鍚�", "姝e湪鏌ヨ...");
+ break;
+ //case "rowUnBindBtn":
+ // UnBindMaterial(data.ItemArray[1].ToString(), data.ItemArray[2].ToString());
+ // break;
+ //case "rowReBindBtn":
+ // BindMaterial();
+ break;
+ default:
+ break;
+ }
+ }
+
+ private void BindMaterial()
+ {
+ if (string.IsNullOrEmpty(CurrentProductSN))
+ {
+ ToastHelper.Warning("璇疯緭鍏ヤ骇鍝佸簭鍒楀彿");
+ return;
+ }
+ if (string.IsNullOrEmpty(CurrentMaterialSN))
+ {
+ ToastHelper.Warning("璇疯緭鍏ョ墿鏂欐潯鐮�");
+ return;
+ }
+ //if (string.IsNullOrEmpty(CurrentMaterialName))
+ //{
+ // ToastHelper.Warning("璇疯緭鍏ョ墿鏂欏悕绉�");
+ // return;
+ //}
+ if (string.IsNullOrEmpty(CurrentWorkstation))
+ {
+ ToastHelper.Warning("璇烽�夋嫨宸ョ珯");
+ return;
+ }
+
+ if (MsgBoxHelper.WarnMessage(this, "纭畾缁戝畾璇ョ墿鏂欏悧?") != MessageBoxResult.OK)
+ {
+ return;
+ }
+ mask.ShowMask(this, () =>
+ {
+ string errMsg = string.Empty;
+ try
+ {
+ if (!api.Connect(mesIp, mesPort, ref errMsg))
+ {
+ throw new Exception($"杩炴帴鏈嶅姟鍣ㄥけ璐�: {errMsg}");
+ }
+ string text2 = api.CheckBoolMaterial_2163(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.FFF"),
+ CurrentProductSN, CurrentWorkstation, CurrentMaterialName, CurrentMaterialSN, out errMsg);
+ if (!string.IsNullOrEmpty(errMsg))
+ {
+ throw new Exception(errMsg);
+ }
+ sqliteHelper.ExecuteSql($@"INSERT INTO bind_record (ProductSN, MaterialSN, Workstation, Time)
+Values ('{CurrentProductSN}', '{CurrentMaterialSN}', '{CurrentWorkstation}','{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.FFF")}')");
+ ToastHelper.Success("缁戝畾鎴愬姛");
+ RefreshBindLog();
+ }
+ finally
+ {
+ api.DisConnect(ref errMsg);
+ }
+ },
+ (ex) =>
+ {
+ Dispatcher.BeginInvoke(new Action(() =>
+ {
+ MsgBoxHelper.Error(this, $"缁戝畾澶辫触: {ex.Message}");
+ }));
+ }, "璇风◢鍚�", "姝e湪缁戝畾...");
+ }
+
+ private void UnBindMaterial(string productSN = null, string materialSN = null)
+ {
+ if (productSN == null)
+ {
+ productSN = CurrentProductSN;
+ }
+ if (materialSN == null)
+ {
+ materialSN = CurrentMaterialSN;
+ }
+
+ if (string.IsNullOrEmpty(productSN))
+ {
+ ToastHelper.Warning("璇疯緭鍏ヤ骇鍝佸簭鍒楀彿");
+ return;
+ }
+ if (string.IsNullOrEmpty(materialSN))
+ {
+ ToastHelper.Warning("璇疯緭鍏ョ墿鏂欐潯鐮�");
+ return;
+ }
+ if (MsgBoxHelper.WarnMessage(this, "纭畾瑙g粦璇ョ墿鏂欏悧?") != MessageBoxResult.OK)
+ {
+ return;
+ }
+
+ mask.ShowMask(this, () =>
+ {
+ string errMsg = string.Empty;
+ try
+ {
+ if (!api.Connect(mesIp, mesPort, ref errMsg))
+ {
+ throw new Exception($"杩炴帴鏈嶅姟鍣ㄥけ璐�: {errMsg}");
+
+ }
+ string text2 = api.UnBookMaterial(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.FFF"),
+ productSN, materialSN, out errMsg);
+ if (!string.IsNullOrEmpty(errMsg))
+ {
+ throw new Exception(errMsg);
+ }
+ sqliteHelper.ExecuteSql($@"INSERT INTO unbind_record (ProductSN, MaterialSN, Workstation, Time)
+Values ('{productSN}', '{materialSN}', '', '{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.FFF")}')");
+ ToastHelper.Success("瑙g粦鎴愬姛");
+ RefreshUnBindLog();
+ }
+ finally
+ {
+ api.DisConnect(ref errMsg);
+ }
+ },
+ (ex) =>
+ {
+ Dispatcher.BeginInvoke(new Action(() =>
+ {
+ MsgBoxHelper.Error(this, $"瑙g粦澶辫触: {ex.Message}");
+ }));
+ }, "璇风◢鍚�", "姝e湪瑙g粦...");
+ }
+
+ private void RefreshBindLog()
+ {
+ var dt = sqliteHelper.GetDataTable("SELECT * FROM bind_record ORDER BY Time DESC LIMIT 100");
+ this.Dispatcher.BeginInvoke(new Action(() =>
+ {
+ table.ItemsSource = dt.DefaultView;
+ }));
+ }
+
+ private void RefreshUnBindLog()
+ {
+ var dt = sqliteHelper.GetDataTable("SELECT * FROM unbind_record ORDER BY Time DESC LIMIT 100");
+ this.Dispatcher.BeginInvoke(new Action(() =>
+ {
+ unbindTable.ItemsSource = dt.DefaultView;
+ }));
+ }
+
+ private void SimpleControl_Loaded(object sender, RoutedEventArgs e)
+ {
+ RefreshWorkstationSource();
+ RefreshBindLog();
+ RefreshUnBindLog();
+ //try
+ //{
+ // ConnectMes();
+ // RefreshWorkstationSource();
+ //}
+ //catch (Exception ex)
+ //{
+ // log.Error("MaterialOpt Load Failed.", ex);
+ //}
+ }
+
+ private void table_SelectionChanged(object sender, SelectionChangedEventArgs e)
+ {
+ if (e.AddedItems == null || e.AddedItems.Count <= 0)
+ {
+ return;
+ }
+ var data = (e.AddedItems[0] as DataRowView).Row;
+ if (sender == table)
+ {
+ CurrentProductSN = data.ItemArray[1].ToString();
+ CurrentMaterialSN = data.ItemArray[2].ToString();
+ CurrentWorkstation = data.ItemArray[4].ToString();
+ }
+ else if (sender == unbindTable)
+ {
+ CurrentProductSN = data.ItemArray[1].ToString();
+ CurrentMaterialSN = data.ItemArray[2].ToString();
+ }
+ }
+ }
+}
diff --git a/Plugin.MaterialOpt/Plugin.MaterialOpt.csproj b/Plugin.MaterialOpt/Plugin.MaterialOpt.csproj
new file mode 100644
index 0000000..c85ac8f
--- /dev/null
+++ b/Plugin.MaterialOpt/Plugin.MaterialOpt.csproj
@@ -0,0 +1,27 @@
+锘�<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <OutputType>Library</OutputType>
+ <TargetFramework>net472</TargetFramework>
+ <Nullable>enable</Nullable>
+ <LangVersion>10.0</LangVersion>
+ <ImplicitUsings>enable</ImplicitUsings>
+ <UseWPF>true</UseWPF>
+ <Platforms>AnyCPU;x64</Platforms>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
+ <PackageReference Include="log4net" Version="3.0.4" />
+ <PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.135" />
+ <PackageReference Include="Panuon.WPF.UI" Version="1.3.0.2" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\..\MesApi\lmes.csproj" />
+ <ProjectReference Include="..\HMI.Base\HMI.Base.csproj" />
+ <ProjectReference Include="..\HMI.Core\HMI.Core.csproj" />
+ <ProjectReference Include="..\HMI.UI\HMI.UI.csproj" />
+ </ItemGroup>
+
+</Project>
diff --git a/Plugin.ModelManage/AssemblyInfo.cs b/Plugin.ModelManage/AssemblyInfo.cs
new file mode 100644
index 0000000..cc29e7f
--- /dev/null
+++ b/Plugin.ModelManage/AssemblyInfo.cs
@@ -0,0 +1,10 @@
+using System.Windows;
+
+[assembly:ThemeInfo(
+ ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
+ //(used if a resource is not found in the page,
+ // or application resource dictionaries)
+ ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
+ //(used if a resource is not found in the page,
+ // app, or any theme specific resource dictionaries)
+)]
diff --git a/Plugin.ModelManage/DataModal.xaml b/Plugin.ModelManage/DataModal.xaml
new file mode 100644
index 0000000..a90cd95
--- /dev/null
+++ b/Plugin.ModelManage/DataModal.xaml
@@ -0,0 +1,77 @@
+锘�<pu:WindowX x:Class="Plugin.ModelManage.DataModal"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:local="clr-namespace:Plugin.ModelManage"
+ xmlns:pw="https://opensource.panuon.com/wpf"
+ xmlns:pu="https://opensource.panuon.com/wpf-ui"
+ xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
+ xmlns:pde="clr-namespace:Plugin.ModelManage.Entity"
+ xmlns:sys="clr-namespace:System;assembly=mscorlib"
+ mc:Ignorable="d"
+ Title="Form"
+ SizeToContent="Height"
+ Width="600"
+ WindowStartupLocation="CenterOwner"
+ Style="{StaticResource ModalWindow}">
+ <Window.Resources>
+ <!--<ObjectDataProvider x:Key="enumValues"
+ MethodName="GetValues"
+ ObjectType="{x:Type sys:Enum}">
+ <ObjectDataProvider.MethodParameters>
+ <x:Type TypeName="pde:ControlType"/>
+ </ObjectDataProvider.MethodParameters>
+ </ObjectDataProvider>
+
+ <ObjectDataProvider x:Key="dioType"
+ MethodName="GetValues"
+ ObjectType="{x:Type sys:Enum}">
+ <ObjectDataProvider.MethodParameters>
+ <x:Type TypeName="pde:DIOType"/>
+ </ObjectDataProvider.MethodParameters>
+ </ObjectDataProvider>-->
+ </Window.Resources>
+ <Grid Margin="10">
+ <StackPanel x:Name="formPanel">
+ <pu:FormGroup x:Name="FgModel"
+ Header="鍨嬪彿"
+ Style="{StaticResource InputFormGroupStyle}"
+ dp:FormGroupHelper.IsRequired="True"
+ dp:FormGroupHelper.ValidateMethod="ValidateModel"
+ GroupName="MyFormGroup">
+ <TextBox x:Name="TbModel" Style="{StaticResource EditorTextBoxStyle}" />
+ </pu:FormGroup>
+
+ <pu:FormGroup x:Name="FgCodeLength" Header="鏉$爜闀垮害"
+ Style="{StaticResource InputFormGroupStyle}"
+ dp:FormGroupHelper.IsRequired="True"
+ GroupName="MyFormGroup">
+ <pu:NumberInput x:Name="NiCodeLength" Style="{StaticResource FormNumberInput}" />
+ </pu:FormGroup>
+
+ <pu:FormGroup x:Name="FgStartIndex" Header="璧峰涓嬫爣"
+Style="{StaticResource InputFormGroupStyle}"
+dp:FormGroupHelper.IsRequired="True"
+GroupName="MyFormGroup">
+ <pu:NumberInput x:Name="NiStartIndex" Style="{StaticResource FormNumberInput}" />
+ </pu:FormGroup>
+
+ <!--<pu:FormGroup x:Name="FgLength" Header="鎴彇闀垮害"
+Style="{StaticResource InputFormGroupStyle}"
+dp:FormGroupHelper.IsRequired="True"
+GroupName="MyFormGroup">
+ <pu:NumberInput x:Name="NiLength" Style="{StaticResource FormNumberInput}" />
+ </pu:FormGroup>-->
+
+ <pu:FormGroup x:Name="FgFixcode"
+Header="鍥哄畾鐮�"
+Style="{StaticResource InputFormGroupStyle}"
+dp:FormGroupHelper.IsRequired="True"
+ dp:FormGroupHelper.ValidateMethod="ValidateFixcode"
+GroupName="MyFormGroup">
+ <TextBox x:Name="TbFixcode" Style="{StaticResource EditorTextBoxStyle}" />
+ </pu:FormGroup>
+ </StackPanel>
+ </Grid>
+</pu:WindowX>
diff --git a/Plugin.ModelManage/DataModal.xaml.cs b/Plugin.ModelManage/DataModal.xaml.cs
new file mode 100644
index 0000000..3bf2936
--- /dev/null
+++ b/Plugin.ModelManage/DataModal.xaml.cs
@@ -0,0 +1,142 @@
+锘縰sing HMI.Core.Util;
+using HMI.UI.DpUtil;
+using HMI.UI.Util;
+using Panuon.WPF.UI;
+using Plugin.ModelManage.Entity;
+using System.ComponentModel;
+
+namespace Plugin.ModelManage
+{
+ /// <summary>
+ /// ModalWindow.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ public partial class DataModal : WindowX
+ {
+ public DataModal()
+ {
+ this.DataContext = this;
+ InitializeComponent();
+ }
+ public ModelData Data { get; set; }
+
+ private SqliteHelper sqliteHelper;
+ private bool _isProcessing;
+
+ protected override void OnClosing(CancelEventArgs e)
+ {
+ //Press Continue Button
+ if (DialogResult == true)
+ {
+ if (_isProcessing)
+ {
+ e.Cancel = true;
+ return;
+ }
+ var okButton = WindowXModalDialog.GetOKButton(this);
+ try
+ {
+ _isProcessing = true;
+ ButtonHelper.SetIsPending(okButton, true);
+ if (!ValidateForm())
+ {
+ e.Cancel = true;
+ return;
+ }
+
+ SaveOrUpdateData();
+ }
+ catch (Exception ex)
+ {
+ ToastHelper.Error(this, $"Error锛亄ex.Message}");
+ e.Cancel = true;
+ return;
+ }
+ finally
+ {
+ _isProcessing = false;
+ ButtonHelper.SetIsPending(okButton, false);
+ }
+ }
+ base.OnClosing(e);
+ }
+
+ private bool ValidateModel(object value, out string err)
+ {
+ err = null;
+ string segment = string.IsNullOrEmpty(Data.Id) ? ";" : $"AND Id != {Data.Id};";
+ var sql = $"SELECT 1 FROM ModelData WHERE Model = '{value}' {segment}";
+ if (sqliteHelper.HasData(sql))
+ {
+ err = "鍨嬪彿涓嶈兘閲嶅";
+ return false;
+ }
+ return true;
+ }
+
+ private bool ValidateFixcode(object value, out string err)
+ {
+ err = null;
+ string segment = string.IsNullOrEmpty(Data.Id) ? ";" : $"AND Id != {Data.Id};";
+ var sql = $"SELECT 1 FROM ModelData WHERE Fixcode = '{value}' {segment}";
+ if (sqliteHelper.HasData(sql))
+ {
+ err = "鍥哄畾鐮佷笉鑳介噸澶�";
+ return false;
+ }
+ return true;
+ }
+
+ private bool ValidateForm()
+ {
+ bool flag = FormGroupHelper.ValidateForm(formPanel);
+ if (flag)
+ {
+ Data.Model = TbModel.Text;
+ Data.CodeLength = (int)NiCodeLength.Value;
+ Data.StartIndex = (int)NiStartIndex.Value;
+ //Data.Length = (int)NiLength.Value;
+ Data.Fixcode = TbFixcode.Text;
+ }
+ return flag;
+ }
+
+ public bool? Open(ModelData data, SqliteHelper sqliteHelper)
+ {
+ Data = data;
+ this.sqliteHelper = sqliteHelper;
+
+ TbModel.Text = Data.Model;
+ NiCodeLength.Value = Data.CodeLength;
+ NiStartIndex.Value = Data.StartIndex;
+ //NiLength.Value = Data.Length;
+ TbFixcode.Text = Data.Fixcode;
+ return this.ShowDialog();
+ }
+
+ private void SaveOrUpdateData()
+ {
+ if (string.IsNullOrEmpty(Data.Id))
+ {
+ InsertData(Data);
+ }
+ else
+ {
+ UpdateData(Data);
+ }
+ }
+
+ public void InsertData(ModelData data)
+ {
+ var sql = $@"INSERT INTO ModelData (Model, CodeLength, StartIndex, Length, Fixcode)
+VALUES ('{data.Model}', {data.CodeLength}, {data.StartIndex}, {data.Length}, '{data.Fixcode}');";
+ sqliteHelper.ExecuteSql(sql);
+ }
+
+ public void UpdateData(ModelData data)
+ {
+ var sql = $@"UPDATE ModelData SET Model='{data.Model}', CodeLength={data.CodeLength}, StartIndex={data.StartIndex},
+Length={data.Length}, Fixcode='{data.Fixcode}' WHERE Id={data.Id}";
+ sqliteHelper.ExecuteSql(sql);
+ }
+ }
+}
diff --git a/Plugin.ModelManage/Entity/ModelData.cs b/Plugin.ModelManage/Entity/ModelData.cs
new file mode 100644
index 0000000..85d565b
--- /dev/null
+++ b/Plugin.ModelManage/Entity/ModelData.cs
@@ -0,0 +1,19 @@
+锘縰sing HMI.Core;
+using HMI.Core.Entity;
+
+namespace Plugin.ModelManage.Entity
+{
+ public class ModelData : SelectBase
+ {
+ public string Id { get; set; }
+ [ExcelColumn("鍨嬪彿")]
+ public string Model { get; set; }
+ [ExcelColumn("鏉$爜闀垮害")]
+ public int CodeLength { get; set; }
+ [ExcelColumn("璧峰涓嬫爣")]
+ public int StartIndex { get; set; }
+ public int Length { get; set; }
+ [ExcelColumn("鍥哄畾鐮�")]
+ public string Fixcode { get; set; }
+ }
+}
diff --git a/Plugin.ModelManage/ModelManage.xaml b/Plugin.ModelManage/ModelManage.xaml
new file mode 100644
index 0000000..61f34bc
--- /dev/null
+++ b/Plugin.ModelManage/ModelManage.xaml
@@ -0,0 +1,169 @@
+锘�<hb:SimpleMaskControl x:Class="Plugin.ModelManage.ModelManage"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:local="clr-namespace:Plugin.ModelManage"
+ mc:Ignorable="d"
+ xmlns:hb="clr-namespace:HMI.Base;assembly=HMI.Base"
+ xmlns:uic="clr-namespace:HMI.UI.Converter;assembly=HMI.UI"
+ xmlns:ui="clr-namespace:HMI.UI;assembly=HMI.UI"
+ xmlns:mdi="clr-namespace:HMI.UI.MDI;assembly=HMI.UI"
+ xmlns:pw="https://opensource.panuon.com/wpf"
+ xmlns:pu="https://opensource.panuon.com/wpf-ui"
+ xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
+ Loaded="SimpleMaskControl_Loaded"
+ d:DesignHeight="450" d:DesignWidth="800">
+ <hb:SimpleMaskControl.Resources>
+ <ResourceDictionary>
+ <ResourceDictionary.MergedDictionaries>
+ <ResourceDictionary Source="/HMI.UI;component/Style/PanuonListView.xaml"/>
+ </ResourceDictionary.MergedDictionaries>
+ </ResourceDictionary>
+ </hb:SimpleMaskControl.Resources>
+
+ <Grid dp:GridHelper.Space="8">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition/>
+ <RowDefinition Height="Auto"/>
+ </Grid.RowDefinitions>
+
+ <DockPanel>
+ <StackPanel dp:StackPanelHelper.ChildSpace="10" DockPanel.Dock="Right" Orientation="Horizontal">
+ <Button Style="{StaticResource AddBtn}" x:Name="addBtn" Click="Button_Click"/>
+ <Button Style="{StaticResource RfhBtn}" x:Name="rfhBtn" Click="Button_Click"/>
+ <Button Style="{StaticResource ExportBtn}" x:Name="exportBtn" Click="Button_Click"/>
+ <Button Style="{StaticResource ImportBtn}" x:Name="importBtn" Click="Button_Click"/>
+ <Button Style="{StaticResource DelBtn}" x:Name="delBatchBtn" Click="Button_Click"/>
+ <!--<Button Style="{StaticResource DelBtn}"/>-->
+ </StackPanel>
+ <TextBlock Style="{StaticResource TitleBox}" Text="鍨嬪彿绠$悊"/>
+ </DockPanel>
+ <ListView Grid.Row="1" Style="{StaticResource DefaultListTable}" x:Name="table"
+ ItemsSource="{Binding Datasource}"
+ VirtualizingPanel.IsContainerVirtualizable="True"
+VirtualizingPanel.IsVirtualizing="True"
+VirtualizingPanel.VirtualizationMode="Standard">
+ <ListView.View>
+ <GridView AllowsColumnReorder="False">
+
+ <GridViewColumn Width="30">
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <CheckBox VerticalAlignment="Center"
+IsChecked="{Binding IsSelected,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+
+ <GridViewColumn Width="60" Header="#">
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <Border Style="{StaticResource CellBorder}">
+ <TextBlock Style="{StaticResource ListTableTextBlock}" Text="{Binding Converter={StaticResource lvRowNumber},
+RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ListViewItem,AncestorLevel=1}}"/>
+ </Border>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+
+ <GridViewColumn Width="700">
+ <GridViewColumn.Header>
+ <TextBlock Text="鍨嬪彿"/>
+ </GridViewColumn.Header>
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <Border Style="{StaticResource CellBorder}">
+ <TextBlock Style="{StaticResource ListTableTextBlock}"
+ Text="{Binding Model}"/>
+ </Border>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+ <GridViewColumn Width="200">
+ <GridViewColumn.Header>
+ <TextBlock Text="鏉$爜闀垮害"/>
+ </GridViewColumn.Header>
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <Border Style="{StaticResource CellBorder}">
+ <TextBlock Style="{StaticResource ListTableTextBlock}"
+ Text="{Binding CodeLength}"/>
+ </Border>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+ <GridViewColumn Width="200">
+ <GridViewColumn.Header>
+ <TextBlock Text="璧峰涓嬫爣"/>
+ </GridViewColumn.Header>
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <Border Style="{StaticResource CellBorder}">
+ <TextBlock Style="{StaticResource ListTableTextBlock}"
+ Text="{Binding StartIndex}"/>
+ </Border>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+ <!--<GridViewColumn Width="200">
+ <GridViewColumn.Header>
+ <TextBlock Text="鎴彇闀垮害"/>
+ </GridViewColumn.Header>
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <Border Style="{StaticResource CellBorder}">
+ <TextBlock Style="{StaticResource ListTableTextBlock}"
+ Text="{Binding Length}"/>
+ </Border>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>-->
+ <GridViewColumn Width="500">
+ <GridViewColumn.Header>
+ <TextBlock Text="鍥哄畾鐮�"/>
+ </GridViewColumn.Header>
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <Border Style="{StaticResource CellBorder}">
+ <TextBlock Style="{StaticResource ListTableTextBlock}"
+ Text="{Binding Fixcode}"/>
+ </Border>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+ <GridViewColumn Width="120">
+ <GridViewColumn.Header>
+ <TextBlock Text="{DynamicResource App.Opt}"/>
+ </GridViewColumn.Header>
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <StackPanel Orientation="Horizontal" dp:StackPanelHelper.ChildSpace="10">
+ <Button x:Name="editBtn" Style="{StaticResource EditLink}"
+ Click="Button_Click" Tag="{Binding }"/>
+
+ <Button x:Name="delBtn" Style="{StaticResource DeleteLink}"
+ Click="Button_Click" Tag="{Binding }"/>
+ </StackPanel>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+ </GridView>
+ </ListView.View>
+ </ListView>
+ <StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Right">
+ <pu:Pagination Height="36" Margin="10"
+HorizontalAlignment="Left"
+Foreground="Black"
+ FontSize="16"
+ FontWeight="UltraBold"
+ ItemsSelectedForeground="#FFF"
+ItemsBackground="Transparent"
+ItemsCornerRadius="12"
+ItemsSelectedBackground="{DynamicResource SecondPrimaryColor}" x:Name="page"
+ CurrentPage="{Binding CurrentPage}"
+ MaxPage="{Binding MaxPage}"/>
+ </StackPanel>
+ </Grid>
+</hb:SimpleMaskControl>
diff --git a/Plugin.ModelManage/ModelManage.xaml.cs b/Plugin.ModelManage/ModelManage.xaml.cs
new file mode 100644
index 0000000..e5f0bd7
--- /dev/null
+++ b/Plugin.ModelManage/ModelManage.xaml.cs
@@ -0,0 +1,300 @@
+锘縰sing CommunityToolkit.Mvvm.ComponentModel;
+using HMI.Base;
+using HMI.Core.Util;
+using HMI.UI.Util;
+using HMI.Util;
+using Microsoft.Win32;
+using Plugin.ModelManage.Entity;
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Data;
+using System.Drawing;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+
+namespace Plugin.ModelManage
+{
+ /// <summary>
+ /// ModelManage.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ [ObservableObject]
+ public partial class ModelManage : SimpleMaskControl
+ {
+ private string dataFilePath;
+ private SqliteHelper sqliteHelper;
+ private double size = 30;
+
+ [ObservableProperty]
+ private ObservableCollection<ModelData> datasource;
+
+ [ObservableProperty]
+ private int currentPage;
+ [ObservableProperty]
+ private int maxPage;
+
+ public ModelManage()
+ {
+ DataContext = this;
+ InitializeComponent();
+ }
+
+ public override void InitFinish()
+ {
+ base.InitFinish();
+ dataFilePath = Path.Combine(BaseFolder, "data.db");
+ if (!File.Exists(dataFilePath))
+ {
+ SqliteHelper.CreateDatabase(dataFilePath);
+ }
+ sqliteHelper = new SqliteHelper(dataFilePath);
+ sqliteHelper.ExecuteSql(@"CREATE TABLE IF NOT EXISTS ModelData (
+ Id INTEGER PRIMARY KEY AUTOINCREMENT,
+ Model TEXT NOT NULL,
+ CodeLength INT,
+ StartIndex INT,
+ Length INT,
+ Fixcode TEXT,
+ UNIQUE(Model),
+ UNIQUE(Fixcode));");
+ }
+
+ private void Button_Click(object sender, RoutedEventArgs e)
+ {
+ Button btn = sender as Button;
+ ModelData data;
+ switch (btn.Name)
+ {
+ case "addBtn":
+ OpenDataModal(new ModelData());
+ break;
+ case "rfhBtn":
+ RefreshPage(CurrentPage);
+ break;
+ case "exportBtn":
+ ExportExcel();
+ break;
+ case "importBtn":
+ ImportExcel();
+ break;
+ case "editBtn":
+ data = btn.Tag as ModelData;
+ OpenDataModal(data);
+ break;
+ case "delBtn":
+ data = btn.Tag as ModelData;
+ DeleteData(data);
+ break;
+ case "delBatchBtn":
+ DeleteBatchData();
+ break;
+ default:
+ break;
+ }
+ }
+
+ private void RefreshPage(int? page = null)
+ {
+ try
+ {
+ var sql = "SELECT COUNT (*) as num FROM ModelData;";
+ var dt = sqliteHelper.GetDataTable(sql);
+ if (dt.Rows.Count <= 0)
+ {
+ CurrentPage = 1;
+ MaxPage = 1;
+ return;
+ }
+ int count = int.Parse(dt.Rows[0]["num"].ToString());
+ MaxPage = (int)Math.Ceiling(count / size);
+
+ if (page != null)
+ {
+ CurrentPage = page.Value;
+ }
+
+ if (CurrentPage > MaxPage)
+ {
+ CurrentPage = MaxPage;
+ }
+
+ if (page == CurrentPage)
+ {
+ RefreshData();
+ }
+ }
+ catch (Exception ex)
+ {
+ log.Error("RefreshPage Error.", ex);
+ ToastHelper.Error($"鍒锋柊鏁版嵁澶辫触: {ex.Message}");
+ }
+ }
+
+ private void RefreshData()
+ {
+ try
+ {
+ var list = new ObservableCollection<ModelData>();
+ var sql = $"SELECT Id, Model, CodeLength, StartIndex, Length, Fixcode FROM ModelData ORDER BY Id DESC LIMIT ({CurrentPage - 1} * {size}), {size};";
+ var dt = sqliteHelper.GetDataTable(sql);
+ if (dt.Rows.Count > 0)
+ {
+ foreach (DataRow dr in dt.Rows)
+ {
+ var at = new ModelData
+ {
+ Id = dr["Id"].ToString(),
+ Model = dr["Model"].ToString(),
+ CodeLength = int.Parse(dr["CodeLength"].ToString()),
+ StartIndex = int.Parse(dr["StartIndex"].ToString()),
+ //Length = int.Parse(dr["Length"].ToString()),
+ Fixcode = dr["Fixcode"].ToString()
+ };
+ list.Add(at);
+ }
+ }
+ Datasource = list;
+ }
+ catch (Exception ex)
+ {
+ log.Error("RefreshData Error.", ex);
+ ToastHelper.Error($"鍒锋柊鏁版嵁澶辫触: {ex.Message}");
+ }
+ }
+
+ private void ExportExcel()
+ {
+ try
+ {
+ SaveFileDialog sfd = new SaveFileDialog
+ {
+ FileName = "鍨嬪彿绠$悊",
+ Filter = "Excel|*.xls"
+ };
+ if (sfd.ShowDialog() == true)
+ {
+ ExcelHelper.ExportExcel(sfd.FileName, Datasource);
+ ToastHelper.Success("瀵煎嚭鎴愬姛");
+ }
+ }
+ catch (Exception ex)
+ {
+ log.Error("ExportExcel Error.", ex);
+ ToastHelper.Error($"瀵煎嚭澶辫触: {ex.Message}");
+ }
+ }
+
+ private void ImportExcel()
+ {
+ try
+ {
+ OpenFileDialog ofd = new OpenFileDialog
+ {
+ Filter = "Excel|*.xls;*.xlsx"
+ };
+ if (ofd.ShowDialog() == true)
+ {
+ List<ModelData> list = ExcelHelper.ReadFromExcel<ModelData>(ofd.FileName);
+ List<string> sqls = new List<string> {
+ "DELETE FROM ModelData;"
+ };
+ foreach (ModelData at in list)
+ {
+ sqls.Add($"INSERT INTO ModelData (Model,CodeLength,StartIndex,Fixcode) VALUES ('{at.Model}',{at.CodeLength},{at.StartIndex},'{at.Fixcode}');");
+ }
+
+ sqliteHelper.ExecuteBatchSql(sqls);
+ ToastHelper.Success("瀵煎叆鎴愬姛");
+ RefreshPage(CurrentPage);
+ }
+ }
+ catch (Exception ex)
+ {
+ log.Error("ImportExcel Error.", ex);
+ ToastHelper.Error($"瀵煎叆澶辫触: {ex.Message}");
+ }
+ }
+
+ private void DeleteData(ModelData data)
+ {
+ try
+ {
+ if (MsgBoxHelper.WarnMessage(Window.GetWindow(this), "纭畾瑕佸垹闄よ鏁版嵁鍚楋紵") == MessageBoxResult.OK)
+ {
+ string sql = $"DELETE FROM ModelData WHERE Id = {data.Id}";
+ sqliteHelper.ExecuteSql(sql);
+ ToastHelper.Success("鍒犻櫎鎴愬姛");
+ RefreshPage(CurrentPage);
+ }
+ }
+ catch (Exception ex)
+ {
+ log.Error("DeleteData Error.", ex);
+ ToastHelper.Error($"鍒犻櫎澶辫触: {ex.Message}");
+ }
+ }
+
+ private void DeleteBatchData()
+ {
+ try
+ {
+ var datas = Datasource.Where(e => e.IsSelected).Select(e => e.Id).ToList();
+ if (datas.Count <= 0) return;
+ if (MsgBoxHelper.WarnMessage(Window.GetWindow(this), "纭畾瑕佸垹闄ら�変腑鐨勬暟鎹悧锛�") == MessageBoxResult.OK)
+ {
+ var ids = string.Join("','", datas);
+ string sql = $"DELETE FROM ModelData WHERE Id IN ('{ids}')";
+ sqliteHelper.ExecuteSql(sql);
+ ToastHelper.Success("鍒犻櫎鎴愬姛");
+ RefreshPage(CurrentPage);
+ }
+ }
+ catch (Exception ex)
+ {
+ log.Error("DeleteData Error.", ex);
+ ToastHelper.Error($"鍒犻櫎澶辫触: {ex.Message}");
+ }
+ }
+
+ private void OpenDataModal(ModelData data)
+ {
+ try
+ {
+ var win = new DataModal
+ {
+ Title = string.IsNullOrEmpty(data.Id) ? "鏂板" : "缂栬緫",
+ Owner = Window.GetWindow(this)
+ };
+ if (win.Open(data, sqliteHelper) == true)
+ {
+ RefreshPage(CurrentPage);
+ }
+ }
+ catch (Exception ex)
+ {
+ log.Error("OpenDataModal Error.", ex);
+ }
+ }
+
+ partial void OnCurrentPageChanged(int value)
+ {
+ RefreshData();
+ }
+
+ private void SimpleMaskControl_Loaded(object sender, RoutedEventArgs e)
+ {
+ RefreshPage(1);
+ Loaded -= SimpleMaskControl_Loaded;
+ }
+ }
+}
diff --git a/Plugin.ModelManage/Plugin.ModelManage.csproj b/Plugin.ModelManage/Plugin.ModelManage.csproj
new file mode 100644
index 0000000..8807b70
--- /dev/null
+++ b/Plugin.ModelManage/Plugin.ModelManage.csproj
@@ -0,0 +1,27 @@
+锘�<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <OutputType>Library</OutputType>
+ <TargetFramework>net472</TargetFramework>
+ <Nullable>enable</Nullable>
+ <LangVersion>10.0</LangVersion>
+ <ImplicitUsings>enable</ImplicitUsings>
+ <UseWPF>true</UseWPF>
+ <AutoGenerateBindingRedirects>True</AutoGenerateBindingRedirects>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
+ <PackageReference Include="log4net" Version="3.0.4" />
+ <PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.135" />
+ <PackageReference Include="Panuon.WPF.UI" Version="1.3.0.2" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\HMI.Base\HMI.Base.csproj" />
+ <ProjectReference Include="..\HMI.Core\HMI.Core.csproj" />
+ <ProjectReference Include="..\HMI.UI\HMI.UI.csproj" />
+ <ProjectReference Include="..\HMI.Util\HMI.Util.csproj" />
+ </ItemGroup>
+
+</Project>
diff --git a/Plugin.SeqEditor/Entity/EditablePO/NumValTestEPO.cs b/Plugin.SeqEditor/Entity/EditablePO/NumValTestEPO.cs
index 69d3272..ee71906 100644
--- a/Plugin.SeqEditor/Entity/EditablePO/NumValTestEPO.cs
+++ b/Plugin.SeqEditor/Entity/EditablePO/NumValTestEPO.cs
@@ -1,5 +1,4 @@
-锘縰sing CommunityToolkit.Mvvm.ComponentModel;
-using NationalInstruments.TestStand.Interop.API;
+锘縰sing NationalInstruments.TestStand.Interop.API;
namespace Plugin.SeqEditor.Entity.EditablePO
{
@@ -11,8 +10,26 @@
public NumValTestEPO(StepUI stepUI)
{
StepUI = stepUI;
+ StepUI.PropertyChanged += StepUI_PropertyChanged;
+
Step = stepUI?.step;
PropertyObject = Step?.AsPropertyObject();
+ }
+
+ private void StepUI_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
+ {
+ if (e.PropertyName == "Low" || e.PropertyName == "High")
+ {
+ OnPropertyChanged(e.PropertyName);
+ }
+ }
+
+ ~NumValTestEPO()
+ {
+ if (StepUI != null)
+ {
+ StepUI.PropertyChanged -= StepUI_PropertyChanged;
+ }
}
public string ComparisonType
@@ -28,29 +45,23 @@
}
}
- public double? Low
+ public string Low
{
- get => PropertyObject?.GetValNumber("Limits.Low", 0);
+ get => StepUI?.Low?.ToString();
set
{
- if (PropertyObject != null)
- {
- PropertyObject.SetValNumber("Limits.Low", 0, value ?? 0);
- CustomPropertyChanged(nameof(Low));
- }
+ double.TryParse(value, out var dob);
+ StepUI.Low = value;
}
}
- public double? High
+ public string High
{
- get => PropertyObject?.GetValNumber("Limits.High", 0);
+ get => StepUI?.High?.ToString();
set
{
- if (PropertyObject != null)
- {
- PropertyObject.SetValNumber("Limits.High", 0, value ?? 0);
- CustomPropertyChanged(nameof(Low));
- }
+ double.TryParse(value, out var dob);
+ StepUI.High = dob;
}
}
}
diff --git a/Plugin.SeqEditor/Entity/EditablePO/StringValTestEPO.cs b/Plugin.SeqEditor/Entity/EditablePO/StringValTestEPO.cs
index 352448b..1772d48 100644
--- a/Plugin.SeqEditor/Entity/EditablePO/StringValTestEPO.cs
+++ b/Plugin.SeqEditor/Entity/EditablePO/StringValTestEPO.cs
@@ -12,10 +12,19 @@
public StringValTestEPO(StepUI stepUI)
{
StepUI = stepUI;
+ stepUI.PropertyChanged += StepUI_PropertyChanged;
Step = StepUI?.step;
PropertyObject = Step?.AsPropertyObject();
}
+ private void StepUI_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
+ {
+ if (e.PropertyName == "Low")
+ {
+ OnPropertyChanged("StringValue");
+ }
+ }
+
public string ComparisonType
{
get => PropertyObject?.GetValString("Comp", 0);
diff --git a/Plugin.SeqEditor/Entity/StepUI.cs b/Plugin.SeqEditor/Entity/StepUI.cs
index 91f5baf..c3cd66e 100644
--- a/Plugin.SeqEditor/Entity/StepUI.cs
+++ b/Plugin.SeqEditor/Entity/StepUI.cs
@@ -1,5 +1,6 @@
锘縰sing CommunityToolkit.Mvvm.ComponentModel;
using NationalInstruments.TestStand.Interop.API;
+using Plugin.SeqEditor.Constant;
using System.Collections.ObjectModel;
using System.Runtime.InteropServices;
@@ -21,10 +22,17 @@
public event EventHandler<string> SettingChanged;
- public int IndexInSequence {
- get {
- return sequence.GetStepIndex(Name, StepGroup);
- }
+ public int IndexInSequence
+ {
+ get
+ {
+ return step.StepIndex;
+ }
+ }
+
+ public int? CustomIndex
+ {
+ get; set;
}
public StepUI(Step step, Sequence sequence)
@@ -57,6 +65,11 @@
}
}
+ public string Id
+ {
+ get => step?.UniqueStepId;
+ }
+
public string Description
{
get => step?.Description;
@@ -64,7 +77,11 @@
public string RunMode
{
- get => step?.GetRunModeEx();
+ get
+ {
+ var t = step?.GetRunModeEx();
+ return t;
+ }
set
{
if (step != null)
@@ -98,6 +115,63 @@
}
}
+ public bool HasLow => Type == StepTypeStr.NumericLimitTest || Type == StepTypeStr.StringValueTest;
+ public bool HasHigh => Type == StepTypeStr.NumericLimitTest;
+
+ public string Low
+ {
+ get
+ {
+ if (Type == StepTypeStr.NumericLimitTest)
+ {
+ return step?.AsPropertyObject()?.GetValNumber("Limits.Low", 0).ToString();
+ }
+ else if (Type == StepTypeStr.StringValueTest)
+ {
+ var value = step?.AsPropertyObject()?.GetValString("Limits.String", 0);
+ if (string.IsNullOrEmpty(value))
+ {
+ value = step?.AsPropertyObject()?.GetValString("Limits.StringExpr", 0);
+ }
+ return value;
+ }
+ return null;
+ }
+ set
+ {
+ if (step != null && HasLow)
+ {
+ if (Type == StepTypeStr.NumericLimitTest)
+ {
+ double.TryParse(value, out double tmp);
+ step?.AsPropertyObject().SetValNumber("Limits.Low", 0, tmp);
+ }
+ else if (Type == StepTypeStr.StringValueTest)
+ {
+ step?.AsPropertyObject()?.SetValString("Limits.String", 0, value);
+ step?.AsPropertyObject()?.SetValString("Limits.StringExpr", 0, null);
+ step?.AsPropertyObject()?.SetValBoolean("Limits.UseStringExpr", 0, false);
+ }
+ UpdatePropertyChanged("Low");
+ UpdatePropertyChanged("Description");
+ }
+ }
+ }
+
+ public double? High
+ {
+ get => HasHigh ? step?.AsPropertyObject()?.GetValNumber("Limits.High", 0) : null;
+ set
+ {
+ if (step != null && HasHigh)
+ {
+ step?.AsPropertyObject().SetValNumber("Limits.High", 0, value ?? 0);
+ UpdatePropertyChanged("High");
+ UpdatePropertyChanged("Description");
+ }
+ }
+ }
+
public StepGroups StepGroup
{
get
@@ -112,6 +186,191 @@
[ObservableProperty]
public ObservableCollection<StepUI> children = new();
+ public string LoopType
+ {
+ get => step?.AsPropertyObject()?.GetValString("TS.LoopType", 0);
+ set
+ {
+ if (step != null)
+ {
+ if (value == "FixedNumLoops")
+ {
+ step.AsPropertyObject().SetValString("TS.LoopType", 0, value);
+ step.AsPropertyObject().SetValString("TS.LoopWhile", 0, "RunState.LoopIndex < 10");
+ step.AsPropertyObject().SetValString("TS.LoopStatus", 0, "RunState.LoopNumPassed / RunState.LoopNumIterations < 1 ? \"Failed\" : \"Passed\"");
+ }
+ else if (value == "PassFailCount")
+ {
+ step.AsPropertyObject().SetValString("TS.LoopType", 0, value);
+ step.AsPropertyObject().SetValString("TS.LoopWhile", 0, "RunState.LoopIndex < 100 && RunState.LoopNumFailed < 10");
+ step.AsPropertyObject().SetValString("TS.LoopStatus", 0, "RunState.LoopNumFailed >= 10 ? \"Failed\" : \"Passed\"");
+ }
+ UpdatePropertyChanged("LoopType");
+ UpdatePropertyChanged("LoopCount");
+ UpdatePropertyChanged("LoopCondition");
+ UpdatePropertyChanged("LoopMax");
+ UpdatePropertyChanged("LoopDescription");
+ }
+ }
+ }
+
+ public string LoopCount
+ {
+ get
+ {
+ if (step == null || step?.AsPropertyObject() == null) return null;
+ string type = step.AsPropertyObject().GetValString("TS.LoopType", 0);
+ string loopWhile;
+ switch (type)
+ {
+ case "FixedNumLoops":
+ loopWhile = step.AsPropertyObject().GetValString("TS.LoopWhile", 0);
+ return loopWhile.Replace($"RunState.LoopIndex < ", "");
+ case "PassFailCount":
+ loopWhile = step.AsPropertyObject().GetValString("TS.LoopWhile", 0);
+ return loopWhile.Split(' ')[2];
+ default:
+ return null;
+ }
+ }
+ set
+ {
+ if (step != null)
+ {
+ string type = step.AsPropertyObject().GetValString("TS.LoopType", 0);
+ switch (type)
+ {
+ case "FixedNumLoops":
+ step.AsPropertyObject().SetValString("TS.LoopWhile", 0, $"RunState.LoopIndex < {value}");
+ UpdatePropertyChanged("LoopDescription");
+ return;
+ case "PassFailCount":
+ var field = LoopCondition == "pass" ? "LoopNumPassed" : "LoopNumFailed";
+ step.AsPropertyObject().SetValString("TS.LoopWhile", 0,
+ $"RunState.LoopIndex < {value} && RunState.{field} < {LoopMax}");
+ UpdatePropertyChanged("LoopDescription");
+ return;
+ default:
+ return;
+ }
+ }
+ }
+ }
+
+ public string LoopCondition
+ {
+ get
+ {
+ if (step == null || step?.AsPropertyObject() == null) return null;
+ string type = step.AsPropertyObject().GetValString("TS.LoopType", 0);
+ string loopStatus;
+ switch (type)
+ {
+ case "FixedNumLoops":
+ loopStatus = step.AsPropertyObject().GetValString("TS.LoopStatus", 0);
+ return loopStatus.Split(' ')[3];
+ case "PassFailCount":
+ loopStatus = step.AsPropertyObject().GetValString("TS.LoopStatus", 0);
+ return loopStatus.Split(' ')[0] == "RunState.LoopNumPassed" ? "pass" : "fail";
+ default:
+ return null;
+ }
+ }
+ set
+ {
+ if (step != null)
+ {
+ string type = step.AsPropertyObject().GetValString("TS.LoopType", 0);
+ switch (type)
+ {
+ case "FixedNumLoops":
+ step.AsPropertyObject().SetValString("TS.LoopStatus", 0,
+ $"RunState.LoopNumPassed / RunState.LoopNumIterations {value} {double.Parse(LoopMax) / 100} ? \"Failed\" : \"Passed\"");
+ UpdatePropertyChanged("LoopDescription");
+ return;
+ case "PassFailCount":
+ var field = value == "pass" ? "LoopNumPassed" : "LoopNumFailed";
+ var sb = value == "pass" ? "\"Passed\" : \"Failed\"" : "\"Failed\" : \"Passed\"";
+ step.AsPropertyObject().SetValString("TS.LoopWhile", 0,
+ $"RunState.LoopIndex < {LoopCount} && RunState.{field} < {LoopMax}");
+ step.AsPropertyObject().SetValString("TS.LoopStatus", 0,
+ $"RunState.{field} >= {LoopMax} ? {sb}");
+ UpdatePropertyChanged("LoopDescription");
+ return;
+ default:
+ return;
+ }
+
+ }
+ }
+ }
+
+ public string LoopMax
+ {
+ get
+ {
+ if (step == null || step?.AsPropertyObject() == null) return null;
+ string type = step.AsPropertyObject().GetValString("TS.LoopType", 0);
+ string data;
+ switch (type)
+ {
+ case "FixedNumLoops":
+ data = step.AsPropertyObject().GetValString("TS.LoopStatus", 0);
+ return (double.Parse(data.Split(' ')[4]) * 100).ToString();
+ case "PassFailCount":
+ data = step.AsPropertyObject().GetValString("TS.LoopWhile", 0);
+ return data.Split(' ')[6];
+ default:
+ return null;
+ }
+ }
+ set
+ {
+ if (step != null)
+ {
+ string type = step.AsPropertyObject().GetValString("TS.LoopType", 0);
+ switch (type)
+ {
+ case "FixedNumLoops":
+ step.AsPropertyObject().SetValString("TS.LoopStatus", 0,
+ $"RunState.LoopNumPassed / RunState.LoopNumIterations {LoopCondition} {double.Parse(value) / 100} ? \"Failed\" : \"Passed\"");
+ UpdatePropertyChanged("LoopDescription");
+ return;
+ case "PassFailCount":
+ var field = LoopCondition == "pass" ? "LoopNumPassed" : "LoopNumFailed";
+ step.AsPropertyObject().SetValString("TS.LoopWhile", 0,
+ $"RunState.LoopIndex < {LoopCount} && RunState.{field} < {value}");
+ UpdatePropertyChanged("LoopDescription");
+ return;
+ default:
+ return;
+ }
+
+ }
+ }
+ }
+
+ public string LoopDescription
+ {
+ get
+ {
+ if (step == null || step?.AsPropertyObject() == null) return null;
+ string type = step.AsPropertyObject().GetValString("TS.LoopType", 0);
+ switch (type)
+ {
+ case "FixedNumLoops":
+ return $"寰幆{LoopCount}娆★紝閫氳繃鐜噞LoopCondition}{LoopMax}%鏃剁粨鏋滀负PASS";
+ case "PassFailCount":
+ return $"寰幆{LoopCount}娆★紝{LoopCondition} {LoopMax}娆′互涓婄粨鏋滀负{LoopCondition}";
+ default:
+ return null;
+ }
+ }
+ set
+ {
+ }
+ }
+
public override string ToString()
{
return Name;
diff --git a/Plugin.SeqEditor/SeqEditor.xaml b/Plugin.SeqEditor/SeqEditor.xaml
index 0867528..0120dad 100644
--- a/Plugin.SeqEditor/SeqEditor.xaml
+++ b/Plugin.SeqEditor/SeqEditor.xaml
@@ -4,6 +4,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Plugin.SeqEditor"
+ xmlns:sp="clr-namespace:Plugin.SeqEditor.SettingPanel"
mc:Ignorable="d"
xmlns:hcu="clr-namespace:HMI.Core.Util;assembly=HMI.Core"
xmlns:hb="clr-namespace:HMI.Base;assembly=HMI.Base"
@@ -30,6 +31,8 @@
<ResourceDictionary Source="/HMI.UI;component/Controls/TreeGrid/Themes/TreeItemContentControl.xaml"/>
<ResourceDictionary Source="/HMI.UI;component/Controls/TreeGrid/Themes/TreeGrid.xaml"/>
</ResourceDictionary.MergedDictionaries>
+
+ <x:Static x:Key="runModeResource" Member="util:RunModeData.ItemSource"/>
<uic:IndentConverter x:Key="IndentConverter"/>
@@ -156,8 +159,8 @@
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0"/>
- <ColumnDefinition Width="8*"/>
- <ColumnDefinition Width="2*"/>
+ <ColumnDefinition Width="8.5*"/>
+ <ColumnDefinition Width="1.5*"/>
</Grid.ColumnDefinitions>
<DockPanel Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3" Margin="0,0,0,10">
@@ -379,6 +382,8 @@
<ui:TreeListView Grid.Row="1" Grid.Column="1" ItemsSource="{Binding AllSteps}"
dd:DragDrop.IsDragSource="True"
+ FontSize="14"
+ pu:TreeViewHelper.ItemsHeight="{DynamicResource nanD}"
dd:DragDrop.IsDropTarget="True"
dd:DragDrop.DropTargetAdornerBrush="Red"
dd:DragDrop.DropHandler="{Binding StepDropHandler}"
@@ -393,11 +398,12 @@
</i:Interaction.Triggers>
<ui:TreeListView.Resources>
<Style x:Key="CellBorder" TargetType="Border">
- <Setter Property="Padding" Value="5"/>
+ <Setter Property="Padding" Value="2"/>
<Setter Property="BorderBrush" Value="{DynamicResource CommonBoarder}"/>
<Setter Property="BorderThickness" Value="1,0,0,1"/>
<Setter Property="Margin" Value="-6,0"/>
</Style>
+ <Style TargetType="ScrollBar" BasedOn="{StaticResource ScrollStyle_Mobile}"/>
</ui:TreeListView.Resources>
<ui:TreeListView.Style>
@@ -405,6 +411,7 @@
<Setter Property="pu:TreeViewHelper.ToggleArrowToggleButtonStyle" Value="{StaticResource TreeTogg}"/>
<Setter Property="pu:TreeViewHelper.ItemsPadding" Value="0"/>
<Setter Property="Background" Value="#FFF"/>
+ <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="ColumnHeaderContainerStyle" Value="{StaticResource gvh}"/>
<Setter Property="Template">
<Setter.Value>
@@ -437,19 +444,20 @@
</ui:TreeListView.Style>
<ui:TreeListView.Columns>
- <GridViewColumn Header="鍚嶇О" HeaderContainerStyle="{StaticResource gvh}"
+ <GridViewColumn Header="搴忓彿" HeaderContainerStyle="{StaticResource gvh}"
+ Width="80"
HeaderTemplate="{StaticResource gvht}">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Border Style="{StaticResource CellBorder}">
- <StackPanel Orientation="Horizontal">
+ <StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
<ToggleButton x:Name="Expander"
Style="{StaticResource ExpandCollapseToggleStyle}"
Margin="{Binding level,Converter={StaticResource IndentConverter},RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ui:TreeListViewItem,AncestorLevel=1}}"
Grid.Column="0"
IsChecked="{Binding IsExpanded, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ui:TreeListViewItem,AncestorLevel=1}}"
ClickMode="Press"/>
- <TextBlock Margin="5,0,0,0" Padding="6,0" Text="{Binding Name}"/>
+ <TextBlock Margin="5,0,0,0" Padding="6,0" Text="{Binding CustomIndex}"/>
</StackPanel>
</Border>
@@ -465,8 +473,62 @@
</GridViewColumn.CellTemplate>
</GridViewColumn>
- <GridViewColumn Header="绫诲瀷" HeaderContainerStyle="{StaticResource gvh}"
+ <GridViewColumn Header="鍚嶇О" HeaderContainerStyle="{StaticResource gvh}"
+ Width="200"
HeaderTemplate="{StaticResource gvht}">
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <Border Style="{StaticResource CellBorder}">
+ <TextBlock Margin="5,0,0,0" Padding="6,0" Text="{Binding Name}"/>
+ </Border>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+
+ <GridViewColumn Header="{DynamicResource se.runMode}"
+ Width="100"
+ HeaderContainerStyle="{StaticResource gvh}"
+ HeaderTemplate="{StaticResource gvht}">
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <Border Style="{StaticResource CellBorder}">
+ <!--<TextBlock Padding="6,0" Text="{Binding RunMode}"/>-->
+ <ui:TableComboBox CanEdit="True"
+ DisplayMemberPath="DisplayName" SelectedValuePath="DataValue"
+ ItemsSource="{StaticResource runModeResource}"
+ Value="{Binding RunMode,Mode=TwoWay}"/>
+ </Border>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+
+ <GridViewColumn Header="Low" HeaderContainerStyle="{StaticResource gvh}"
+ Width="300"
+ HeaderTemplate="{StaticResource gvht}">
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <Border Style="{StaticResource CellBorder}">
+ <ui:EditBox Value="{Binding Low,Mode=TwoWay}" CanEdit="{Binding HasLow}"/>
+ </Border>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+
+ <GridViewColumn Header="High" HeaderContainerStyle="{StaticResource gvh}"
+ Width="300"
+HeaderTemplate="{StaticResource gvht}">
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <Border Style="{StaticResource CellBorder}">
+ <ui:EditBox Value="{Binding High,Mode=TwoWay}" CanEdit="{Binding HasHigh}"/>
+ </Border>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+
+ <GridViewColumn Header="绫诲瀷" HeaderContainerStyle="{StaticResource gvh}"
+ Width="120"
+ HeaderTemplate="{StaticResource gvht}">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Border Style="{StaticResource CellBorder}">
@@ -477,24 +539,12 @@
</GridViewColumn>
<GridViewColumn Header="鎻忚堪" HeaderContainerStyle="{StaticResource gvh}"
- HeaderTemplate="{StaticResource gvht}">
- <GridViewColumn.CellTemplate>
- <DataTemplate>
- <Border Style="{StaticResource CellBorder}">
- <TextBlock Padding="6,0" Text="{Binding Description}"/>
- </Border>
- </DataTemplate>
- </GridViewColumn.CellTemplate>
- </GridViewColumn>
-
- <GridViewColumn Header="{DynamicResource se.runMode}"
- Width="80"
- HeaderContainerStyle="{StaticResource gvh}"
- HeaderTemplate="{StaticResource gvht}">
+ Width="400"
+ HeaderTemplate="{StaticResource gvht}">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Border Style="{StaticResource CellBorder}" BorderThickness="1,0,1,1">
- <TextBlock Padding="6,0" Text="{Binding RunMode}"/>
+ <TextBlock Padding="6,0" Text="{Binding Description}"/>
</Border>
</DataTemplate>
</GridViewColumn.CellTemplate>
@@ -513,11 +563,14 @@
</pu:FormGroup>
- <pu:FormGroup Header="{DynamicResource se.propertySetting}" Orientation="Vertical"
- Grid.Row="2" Padding="0,10" Grid.Column="2">
- <Border x:Name="editPanelContainer" Background="#FFF">
- </Border>
- </pu:FormGroup>
+ <StackPanel Grid.Row="2" Grid.Column="2">
+ <pu:FormGroup Header="{DynamicResource se.propertySetting}" Orientation="Vertical"
+ Padding="0,10" >
+ <Border x:Name="editPanelContainer" Background="#FFF">
+ </Border>
+ </pu:FormGroup>
+ <sp:LoopPanel x:Name="loopPanel" DataContext="{Binding CurrentStepUI}"/>
+ </StackPanel>
</Grid>
</Border>
</hb:PluginControl>
diff --git a/Plugin.SeqEditor/SeqEditor.xaml.cs b/Plugin.SeqEditor/SeqEditor.xaml.cs
index a6d4213..3d95679 100644
--- a/Plugin.SeqEditor/SeqEditor.xaml.cs
+++ b/Plugin.SeqEditor/SeqEditor.xaml.cs
@@ -74,11 +74,12 @@
private void TreeListView_SizeChanged(object sender, SizeChangedEventArgs e)
{
- var treeListView = sender as TreeListView;
- var columns = treeListView.Columns;
- var width = treeListView.ActualWidth;
+ //var treeListView = sender as TreeListView;
+ //var columns = treeListView.Columns;
+ //var width = treeListView.ActualWidth;
- columns[0].Width = columns[0].Width + (width - columns[0].Width - columns[1].Width - columns[2].Width - columns[3].Width);
+ //columns[0].Width = columns[0].Width + (width - columns[0].Width - columns[1].Width - columns[2].Width - columns[3].Width);
+
//foreach (var col in columns) {
// col.Width =
//}
diff --git a/Plugin.SeqEditor/SettingPanel/ActionPanel.xaml b/Plugin.SeqEditor/SettingPanel/ActionPanel.xaml
index 0d51042..8d8edf2 100644
--- a/Plugin.SeqEditor/SettingPanel/ActionPanel.xaml
+++ b/Plugin.SeqEditor/SettingPanel/ActionPanel.xaml
@@ -30,6 +30,7 @@
<ComboBox x:Name="CbRunMode" Style="{StaticResource FormComboxStyle}"
VirtualizingPanel.IsVirtualizing="True"
+ pu:ComboBoxHelper.ClearButtonVisibility="Collapsed"
SelectedValue="{Binding RunMode}"
DisplayMemberPath="DisplayName" SelectedValuePath="DataValue"/>
</pu:FormGroup>
diff --git a/Plugin.SeqEditor/SettingPanel/LoopPanel.xaml b/Plugin.SeqEditor/SettingPanel/LoopPanel.xaml
new file mode 100644
index 0000000..741ccbd
--- /dev/null
+++ b/Plugin.SeqEditor/SettingPanel/LoopPanel.xaml
@@ -0,0 +1,104 @@
+锘�<UserControl x:Class="Plugin.SeqEditor.SettingPanel.LoopPanel"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:local="clr-namespace:Plugin.SeqEditor.SettingPanel"
+ mc:Ignorable="d"
+ xmlns:hb="clr-namespace:HMI.Base;assembly=HMI.Base"
+ xmlns:uic="clr-namespace:HMI.UI.Converter;assembly=HMI.UI"
+ xmlns:ui="clr-namespace:HMI.UI;assembly=HMI.UI"
+ xmlns:pw="https://opensource.panuon.com/wpf"
+ xmlns:pu="https://opensource.panuon.com/wpf-ui"
+ xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
+ Padding="5"
+ Background="#FFF"
+ d:DesignHeight="450" d:DesignWidth="800">
+ <Grid>
+ <StackPanel>
+ <pu:FormGroup Header="寰幆" Orientation="Vertical"
+ Style="{StaticResource InputFormGroupStyle}">
+ <ComboBox x:Name="CbLoopType" Style="{StaticResource FormComboxStyle}" SelectedValue="{Binding LoopType}"
+ DisplayMemberPath="DisplayName" SelectedValuePath="DataValue"/>
+ </pu:FormGroup>
+
+ <pu:FormGroup Header="寰幆娆℃暟" Orientation="Vertical"
+ Style="{StaticResource InputFormGroupStyle}">
+ <ui:NumberInput Style="{StaticResource EditorTextBoxStyle}" Text="{Binding LoopCount}" />
+ </pu:FormGroup>
+
+ <pu:FormGroup Header="缁撴灉鍒ゆ柇" Orientation="Vertical">
+ <pu:FormGroup.Style>
+ <Style TargetType="pu:FormGroup" BasedOn="{StaticResource InputFormGroupStyle}">
+ <Setter Property="Visibility" Value="Collapsed"/>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding LoopType}" Value="FixedNumLoops">
+ <Setter Property="Visibility" Value="Visible"/>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </pu:FormGroup.Style>
+ <Border Padding="2" BorderThickness="1" BorderBrush="Gray" Background="#e8e8e8">
+ <Grid>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="Auto"/>
+ <ColumnDefinition/>
+ <ColumnDefinition/>
+ <ColumnDefinition Width="Auto"/>
+ </Grid.ColumnDefinitions>
+ <TextBlock Grid.Column="0" Text="澶辫触鐜�" Margin="0,0,5,0" VerticalAlignment="Center"/>
+ <ComboBox Grid.Column="1" x:Name="CBLoopCondition"
+ pu:ComboBoxHelper.ClearButtonVisibility="Collapsed"
+ Style="{StaticResource FormComboxStyle}" SelectedValue="{Binding LoopCondition}"
+DisplayMemberPath="DisplayName" SelectedValuePath="DataValue"/>
+ <ui:NumberInput Grid.Column="2" Style="{StaticResource EditorTextBoxStyle}" Text="{Binding LoopMax}" />
+ <TextBlock Grid.Column="3" Text="%娴嬭瘯PASS" VerticalAlignment="Center"/>
+ </Grid>
+ </Border>
+ </pu:FormGroup>
+
+ <pu:FormGroup Header="缁撴灉鍒ゆ柇" Orientation="Vertical">
+ <pu:FormGroup.Style>
+ <Style TargetType="pu:FormGroup" BasedOn="{StaticResource InputFormGroupStyle}">
+ <Setter Property="Visibility" Value="Collapsed"/>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding LoopType}" Value="PassFailCount">
+ <Setter Property="Visibility" Value="Visible"/>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </pu:FormGroup.Style>
+ <Border Padding="2" BorderThickness="1" BorderBrush="Gray" Background="#e8e8e8">
+ <Grid>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition/>
+ <ColumnDefinition/>
+ <ColumnDefinition Width="Auto"/>
+ </Grid.ColumnDefinitions>
+ <ComboBox Grid.Column="0" x:Name="CBLoopCondition2"
+ pu:ComboBoxHelper.ClearButtonVisibility="Collapsed"
+ Style="{StaticResource FormComboxStyle}" SelectedValue="{Binding LoopCondition}"
+DisplayMemberPath="DisplayName" SelectedValuePath="DataValue"/>
+ <ui:NumberInput Grid.Column="1" Style="{StaticResource EditorTextBoxStyle}" Text="{Binding LoopMax}" />
+ <TextBlock Grid.Column="2" Text="娆′箣鍚庣粨鏉熷惊鐜�" VerticalAlignment="Center"/>
+ </Grid>
+ </Border>
+ </pu:FormGroup>
+
+ <pu:FormGroup Header="璇存槑" Orientation="Vertical"
+ Style="{StaticResource InputFormGroupStyle}">
+
+ <TextBox x:Name="TbRemark" IsReadOnly="True"
+ Style="{StaticResource EditorTextBoxStyle}"
+ Text="{Binding LoopDescription,Mode=OneWay}"/>
+ </pu:FormGroup>
+
+ <!--<pu:FormGroup Header="{DynamicResource se.adapter}"
+ Orientation="Vertical"
+ Style="{StaticResource InputFormGroupStyle}">
+ <ComboBox x:Name="CbAdapter" Style="{StaticResource FormComboxStyle}" IsEnabled="False" SelectedValue="{Binding Adapter}"
+ DisplayMemberPath="DisplayName" SelectedValuePath="DataValue"/>
+ </pu:FormGroup>-->
+ </StackPanel>
+ </Grid>
+</UserControl>
diff --git a/Plugin.SeqEditor/SettingPanel/LoopPanel.xaml.cs b/Plugin.SeqEditor/SettingPanel/LoopPanel.xaml.cs
new file mode 100644
index 0000000..95c660f
--- /dev/null
+++ b/Plugin.SeqEditor/SettingPanel/LoopPanel.xaml.cs
@@ -0,0 +1,60 @@
+锘縰sing CommunityToolkit.Mvvm.ComponentModel;
+using NationalInstruments.TestStand.Interop.API;
+using Plugin.SeqEditor.Entity;
+using Plugin.SeqEditor.Util;
+using System.ComponentModel;
+using System.Windows.Controls;
+
+namespace Plugin.SeqEditor.SettingPanel
+{
+ /// <summary>
+ /// CommonProperty.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ [INotifyPropertyChanged]
+ public partial class LoopPanel : UserControl
+ {
+ public event EventHandler SettingChanged;
+
+ private StepUI stepUI;
+ public StepUI StepUI
+ {
+ get => stepUI;
+ set
+ {
+ this.stepUI = stepUI;
+ this.step = stepUI.step;
+ propertyObject = this.step?.AsPropertyObject();
+ this.DataContext = stepUI;
+ }
+ }
+
+ public Step step;
+ public PropertyObject propertyObject;
+
+ protected void CustomPropertyChanged(string name)
+ {
+ OnPropertyChanged(name);
+ SettingChanged?.Invoke(this, EventArgs.Empty);
+ }
+
+ public LoopPanel()
+ {
+ InitializeComponent();
+ CbLoopType.ItemsSource = LoopTypeData.ItemSource;
+ CBLoopCondition.ItemsSource = LoopConditionData.ItemSource;
+ CBLoopCondition2.ItemsSource = LoopCondition2Data.ItemSource;
+ }
+
+ public LoopPanel(StepUI stepUI)
+ {
+ this.stepUI = stepUI;
+ this.step = stepUI.step;
+ propertyObject = this.step?.AsPropertyObject();
+ this.DataContext = stepUI;
+ InitializeComponent();
+ CbLoopType.ItemsSource = LoopTypeData.ItemSource;
+ CBLoopCondition.ItemsSource = LoopConditionData.ItemSource;
+ CBLoopCondition2.ItemsSource = LoopCondition2Data.ItemSource;
+ }
+ }
+}
diff --git a/Plugin.SeqEditor/SettingPanel/StringValTestPanel.xaml b/Plugin.SeqEditor/SettingPanel/StringValTestPanel.xaml
index 7a8c260..61fdd55 100644
--- a/Plugin.SeqEditor/SettingPanel/StringValTestPanel.xaml
+++ b/Plugin.SeqEditor/SettingPanel/StringValTestPanel.xaml
@@ -51,7 +51,8 @@
Orientation="Vertical"
Style="{StaticResource InputFormGroupStyle}">
- <TextBox IsReadOnly="{Binding IsReadOnly}" Style="{StaticResource EditorTextBoxStyle}" Text="{Binding StringValue}"/>
+ <TextBox IsReadOnly="{Binding IsReadOnly}" Style="{StaticResource EditorTextBoxStyle}"
+ Text="{Binding StringValue,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
</pu:FormGroup>
</StackPanel>
</UserControl>
diff --git a/Plugin.SeqEditor/Util/ItemData.cs b/Plugin.SeqEditor/Util/ItemData.cs
index 2ca8896..29c5b7b 100644
--- a/Plugin.SeqEditor/Util/ItemData.cs
+++ b/Plugin.SeqEditor/Util/ItemData.cs
@@ -107,17 +107,18 @@
public abstract class RunModeData
{
+ //LangUtil.Get("se.normal")
public static readonly ItemData Normal =
- new(LangUtil.Get("se.normal"), "Normal");
+ new("Normal", "Normal");
public static readonly ItemData Skip =
- new(LangUtil.Get("se.skip"), "Skip");
+ new("Skip", "Skip");
public static readonly ItemData ForcePass =
- new(LangUtil.Get("se.pass"), "Pass");
+ new("Pass", "Pass");
public static readonly ItemData ForceFail =
- new(LangUtil.Get("se.fail"), "Fail");
+ new("Fail", "Fail");
public static readonly List<ItemData> ItemSource =
new List<ItemData> {
@@ -144,4 +145,52 @@
LabView,LabWindows,CCPlus,DotNet,ActiveX,None,LabViewNGX,Python,SequenceCall
};
}
+
+ public abstract class LoopTypeData
+ {
+ public static readonly ItemData None =
+ new("鏃�", "NoLooping");
+ public static readonly ItemData Fixed =
+ new("鍥哄畾娆℃暟寰幆", "FixedNumLoops");
+ public static readonly ItemData PassFailCount =
+ new("PassFailCount", "PassFailCount");
+
+ public static readonly ItemData Custom =
+ new("鑷畾涔�", "Custom");
+
+ public static readonly List<ItemData> ItemSource =
+ new List<ItemData> {
+ None,Fixed,PassFailCount
+ };
+ }
+
+ public abstract class LoopConditionData
+ {
+ public static readonly ItemData LT =
+ new("<", "<");
+ public static readonly ItemData LE =
+ new("<=", "<=");
+ public static readonly ItemData GT =
+ new(">", ">");
+
+ public static readonly ItemData GE =
+ new(">=", ">=");
+
+ public static readonly List<ItemData> ItemSource =
+ new List<ItemData> {
+ LT,LE, GT, GE
+ };
+ }
+
+ public abstract class LoopCondition2Data
+ {
+ public static readonly ItemData PASS =
+ new("pass", "pass");
+ public static readonly ItemData FAIL =
+ new("fail", "fail");
+ public static readonly List<ItemData> ItemSource =
+ new List<ItemData> {
+ PASS,FAIL
+ };
+ }
}
diff --git a/Plugin.SeqEditor/ViewModel/SeqEditorViewModel.cs b/Plugin.SeqEditor/ViewModel/SeqEditorViewModel.cs
index 70fcd05..69b5ee8 100644
--- a/Plugin.SeqEditor/ViewModel/SeqEditorViewModel.cs
+++ b/Plugin.SeqEditor/ViewModel/SeqEditorViewModel.cs
@@ -185,6 +185,8 @@
return steps;
}
+ private int indexCache = 0;
+
private StepUI Convert2StepUI(int index, Step step, Sequence sequence, string group)
{
var ui = new StepUI(step, sequence);
@@ -229,6 +231,10 @@
}
ui.Children = LoadSteps(sunSequence, group);
}
+ }
+ else
+ {
+ ui.CustomIndex = ++indexCache;
}
if (CurrentSeqUI != null)
{
@@ -468,7 +474,7 @@
}
var newUI = new StepUI(newStep, targetSequence);
-
+
targetSequence.InsertStep(newStep, index + 1, group);
ObservableCollection<StepUI> datasource = sequenceCache[targetSequence];
int uiIndex = datasource.IndexOf(CurrentStepUI);
@@ -488,7 +494,7 @@
// var items = parentItem.Items;
// int innerIndex = items.IndexOf(TreeItemData);
-
+
// items.Insert(innerIndex + 1, newItem);
// TreeItemDataCollection.ResetSubItems(items);
//}
@@ -544,6 +550,7 @@
public void RefreshData()
{
+ indexCache = 0;
sequenceCache.Clear();
AllSteps = LoadSteps(CurrentSeqUI.sequence);
}
diff --git a/Plugin.TestBuilder/Plugin.TestBuilder.csproj b/Plugin.TestBuilder/Plugin.TestBuilder.csproj
index c8962ac..be3e7b1 100644
--- a/Plugin.TestBuilder/Plugin.TestBuilder.csproj
+++ b/Plugin.TestBuilder/Plugin.TestBuilder.csproj
@@ -129,7 +129,6 @@
<Compile Include="UI\BottomBar.xaml.cs">
<DependentUpon>BottomBar.xaml</DependentUpon>
</Compile>
- <Compile Include="UI\CanvasHelper.cs" />
<Compile Include="Container\FunctionSetting.xaml.cs">
<DependentUpon>FunctionSetting.xaml</DependentUpon>
</Compile>
diff --git a/Plugin.TestBuilder/UI/InnerWindow.xaml b/Plugin.TestBuilder/UI/InnerWindow.xaml
index 9163890..79c530b 100644
--- a/Plugin.TestBuilder/UI/InnerWindow.xaml
+++ b/Plugin.TestBuilder/UI/InnerWindow.xaml
@@ -1,9 +1,9 @@
-锘�<UserControl x:Class="Plugin.TestBuilder.UI.InnerWindow"
+锘�<UserControl x:Class="HMI.UI.InnerWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:local="clr-namespace:Plugin.TestBuilder.UI"
+ xmlns:local="clr-namespace:HMI.UI"
mc:Ignorable="d"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
@@ -31,7 +31,7 @@
</UserControl.Resources>
<UserControl.Template>
- <ControlTemplate TargetType="UserControl">
+ <ControlTemplate TargetType="local:InnerWindow">
<AdornerDecorator x:Name="PART_Adorner" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" >
<Grid GotFocus="Grid_GotFocus">
<Grid.RowDefinitions>
diff --git a/Plugin.TestBuilder/UI/InnerWindow.xaml.cs b/Plugin.TestBuilder/UI/InnerWindow.xaml.cs
index 5242c2b..54edb24 100644
--- a/Plugin.TestBuilder/UI/InnerWindow.xaml.cs
+++ b/Plugin.TestBuilder/UI/InnerWindow.xaml.cs
@@ -8,7 +8,7 @@
using System.Windows.Input;
using System.Windows.Media;
-namespace Plugin.TestBuilder.UI
+namespace HMI.UI
{
/// <summary>
/// InnerWindow.xaml 鐨勪氦浜掗�昏緫
diff --git a/Plugin.TestBuilder/UI/Resize.cs b/Plugin.TestBuilder/UI/Resize.cs
index 400e69e..de8812a 100644
--- a/Plugin.TestBuilder/UI/Resize.cs
+++ b/Plugin.TestBuilder/UI/Resize.cs
@@ -1,4 +1,5 @@
-锘縰sing System;
+锘縰sing HMI.UI.DpUtil;
+using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
@@ -7,7 +8,7 @@
using System.Windows.Media;
using System.Windows.Shapes;
-namespace Plugin.TestBuilder.UI
+namespace HMI.UI
{
public class Resize
{
diff --git a/Plugin.TestResult/DataTable.xaml b/Plugin.TestResult/DataTable.xaml
index 473cac1..501ee89 100644
--- a/Plugin.TestResult/DataTable.xaml
+++ b/Plugin.TestResult/DataTable.xaml
@@ -82,24 +82,28 @@
</StatusBarItem>
<StatusBarItem DockPanel.Dock="Right">
- <StackPanel Orientation="Horizontal">
- <Ellipse Width="10" Height="10">
- <Ellipse.Style>
- <Style TargetType="Ellipse">
- <Setter Property="Fill" Value="LightGray"/>
- <Style.Triggers>
- <DataTrigger Binding="{Binding TcpServerStatus,ElementName=control}" Value="ERROR">
- <Setter Property="Fill" Value="Red"/>
- </DataTrigger>
- <DataTrigger Binding="{Binding TcpServerStatus,ElementName=control}" Value="RUNNING">
- <Setter Property="Fill" Value="Green"/>
- </DataTrigger>
- </Style.Triggers>
- </Style>
- </Ellipse.Style>
- </Ellipse>
- <TextBlock Text="{Binding TcpServerInfo}"/>
- <Button Padding="0" Margin="0" BorderThickness="0" Click="Button_Click">馃攧</Button>
+ <StackPanel Orientation="Horizontal" dp:StackPanelHelper.ChildSpace="8">
+ <Button Style="{StaticResource DeleteLink}" Click="Button_Click_2" Content="鍋滄娴嬭瘯"/>
+
+ <StackPanel Orientation="Horizontal">
+ <Ellipse Width="10" Height="10">
+ <Ellipse.Style>
+ <Style TargetType="Ellipse">
+ <Setter Property="Fill" Value="LightGray"/>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding TcpServerStatus,ElementName=control}" Value="ERROR">
+ <Setter Property="Fill" Value="Red"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding TcpServerStatus,ElementName=control}" Value="RUNNING">
+ <Setter Property="Fill" Value="Green"/>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Ellipse.Style>
+ </Ellipse>
+ <TextBlock Text="{Binding TcpServerInfo}"/>
+ <Button Padding="0" Margin="0" BorderThickness="0" Click="Button_Click">馃攧</Button>
+ </StackPanel>
</StackPanel>
</StatusBarItem>
diff --git a/Plugin.TestResult/DataTable.xaml.cs b/Plugin.TestResult/DataTable.xaml.cs
index 54364f4..84911cd 100644
--- a/Plugin.TestResult/DataTable.xaml.cs
+++ b/Plugin.TestResult/DataTable.xaml.cs
@@ -6,7 +6,6 @@
using Plugin.TestResult_WPF.Util;
using SuperSocket.SocketBase.Protocol;
using System;
-using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
@@ -222,6 +221,12 @@
private void ScanWindow_Click(object sender, RoutedEventArgs e)
{
+ if (!parent.IsRunning)
+ {
+ MsgBoxHelper.WarnMessage(this, "璇峰厛鐐瑰嚮鍙充晶鍚姩鎸夐挳鍚姩娴嬭瘯绋嬪簭锛�", null, MessageBoxButton.OK);
+ return;
+ }
+
if (scanner != null)
{
scanner.Activate();
@@ -371,7 +376,7 @@
private void TcpServer_NewRequestReceived(TcpSession session, StringRequestInfo requestInfo)
{
string msg = requestInfo.Body;
- ViewControl.Logger.Info($"TCP Data From {session.RemoteEndPoint}: {msg}.");
+ //ViewControl.Logger.Info($"TCP Data From {session.RemoteEndPoint}: {msg}.");
string[] datas_10015 = msg.Split(';');
int cellIndex = int.Parse(datas_10015[1]);
@@ -524,6 +529,13 @@
private void ClearAllSnr_Click(object sender, RoutedEventArgs e)
{
+ var str = $"StationState.Start_{title}";
+ if (parent.engine.Globals.GetValBoolean(str, 0) == true)
+ {
+ MsgBoxHelper.Error(Window.GetWindow(this), "绋嬪簭杩愯涓紝涓嶈兘娓呯┖鏉$爜");
+ return;
+ }
+
if (MsgBoxHelper.WarnMessage(Window.GetWindow(this), LangUtil.Get("Tr.MakeSureClearAllSNR")) == MessageBoxResult.OK)
{
try
@@ -544,5 +556,13 @@
}
}
}
+
+ private void Button_Click_2(object sender, RoutedEventArgs e)
+ {
+ if (MsgBoxHelper.WarnMessage(Window.GetWindow(this), "纭畾瑕佸仠姝㈣鐐変綅鐨勮�佸寲娴嬭瘯鍚楋紵") == MessageBoxResult.OK)
+ {
+ parent.SetStartFlag(this.index, false);
+ }
+ }
}
}
diff --git a/Plugin.TestResult/Plugin.TestResult.csproj b/Plugin.TestResult/Plugin.TestResult.csproj
index eaf6682..f24e6c6 100644
--- a/Plugin.TestResult/Plugin.TestResult.csproj
+++ b/Plugin.TestResult/Plugin.TestResult.csproj
@@ -277,7 +277,6 @@
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
- <None Include="app.config" />
<None Include="Config\log4net.config" />
<None Include="Config\log4net.unix.config" />
<None Include="packages.config" />
@@ -326,6 +325,10 @@
<Project>{AFEA100A-9223-448D-AB10-3015D93DD98C}</Project>
<Name>HMI.Util</Name>
</ProjectReference>
+ <ProjectReference Include="..\Plugin.TsSupport\Plugin.TsSupport.csproj">
+ <Project>{3068124e-f12b-473e-99a0-2da5a0385d05}</Project>
+ <Name>Plugin.TsSupport</Name>
+ </ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\WPFProject\packages\HarfBuzzSharp.NativeAssets.macOS.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.macOS.targets" Condition="Exists('..\WPFProject\packages\HarfBuzzSharp.NativeAssets.macOS.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.macOS.targets')" />
diff --git a/Plugin.TestResult/TestResultView.xaml.cs b/Plugin.TestResult/TestResultView.xaml.cs
index 4f73cfe..f2f148d 100644
--- a/Plugin.TestResult/TestResultView.xaml.cs
+++ b/Plugin.TestResult/TestResultView.xaml.cs
@@ -5,6 +5,7 @@
using NationalInstruments.TestStand.Utility;
using Plugin.TestResult_WPF.Constant;
using Plugin.TestResult_WPF.Model;
+using Plugin.TsSupport;
using System;
using System.Collections.Generic;
using System.Windows;
@@ -46,6 +47,8 @@
}
+ public bool IsRunning { get; set; } = false;
+
public TestResultView(BaseConfig config)
{
this.rowCount = config.Row;
@@ -63,10 +66,10 @@
InitializeComponent();
- testApp = new AxApplicationMgr();
- testApp.ExitApplication += new EventHandler(this.axApplicationMgr_ExitApplication);
- testApp.UIMessageEvent += new _ApplicationMgrEvents_UIMessageEventEventHandler(this.axApplicationMgr_UIMessageEvent);
- testApp.ExecutionClosed += new _ApplicationMgrEvents_ExecutionClosedEventHandler(this.axApplicationMgr_ExecutionClosed);
+ testApp = TestAppManager.GetAxApplicationMgr();
+ testApp.ExitApplication += this.axApplicationMgr_ExitApplication;
+ testApp.UIMessageEvent += this.axApplicationMgr_UIMessageEvent;
+ testApp.ExecutionClosed += this.axApplicationMgr_ExecutionClosed;
((System.ComponentModel.ISupportInitialize)(this.testApp)).BeginInit();//myClient涓虹涓夋柟鎺т欢鍚�
@@ -385,7 +388,6 @@
if (MethodCode == 12)
{
/// 淇濆瓨娓╁害鏂囦欢
- ///
strData = e.uiMsg.StringData;
string[] datas = strData.Split(';');
int ovenIndex = int.Parse(datas[0]);
@@ -435,14 +437,17 @@
if (this.SequenceContext == null) return;
string name = tables[index].title;
string key = $"StationState.Start_{name}";
- this.engine.Globals.SetValBoolean(key, 0, data);
- bool val = this.engine.Globals.GetValBoolean(key, 0);
+ this.engine.Globals.SetValBoolean(key, 1, data);
+ //bool val = this.engine.Globals.GetValBoolean(key, 0);
//this.SequenceContext.StationGlobals.SetValBoolean(key, 0, data);
//bool val = this.SequenceContext.StationGlobals.GetValBoolean(key, 0);
}
public void ReleaseResource()
{
+ testApp.ExitApplication -= this.axApplicationMgr_ExitApplication;
+ testApp.UIMessageEvent -= this.axApplicationMgr_UIMessageEvent;
+ testApp.ExecutionClosed -= this.axApplicationMgr_ExecutionClosed;
foreach (var table in tables)
{
table.RelaseResource();
diff --git a/Plugin.TestResult/ViewControl.xaml b/Plugin.TestResult/ViewControl.xaml
index 56db280..48d2036 100644
--- a/Plugin.TestResult/ViewControl.xaml
+++ b/Plugin.TestResult/ViewControl.xaml
@@ -1,4 +1,4 @@
-锘�<hb:PluginControl x:Class="Plugin.TestResult_WPF.ViewControl"
+锘�<hb:PluginMaskControl x:Class="Plugin.TestResult_WPF.ViewControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
@@ -11,6 +11,7 @@
xmlns:pu="https://opensource.panuon.com/wpf-ui"
xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
mc:Ignorable="d"
+ Style="{StaticResource pluginMaskControl}"
Loaded="UserControl_Loaded"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
@@ -42,7 +43,7 @@
<GroupBox Header="{DynamicResource Tr.ProductInfo}">
<ComboBox x:Name="modelSelect" Style="{StaticResource FormComboxStyle}"
pu:ComboBoxHelper.ClearButtonVisibility="Collapsed"
- SelectionChanged="modelSelect_SelectionChanged"></ComboBox>
+ SelectionChanged="modelSelect_SelectionChanged"/>
</GroupBox>
<GroupBox Header="{DynamicResource Tr.Status}">
<StackPanel>
@@ -116,4 +117,4 @@
</GroupBox>
</StackPanel>
</Grid>
-</hb:PluginControl>
+</hb:PluginMaskControl>
diff --git a/Plugin.TestResult/ViewControl.xaml.cs b/Plugin.TestResult/ViewControl.xaml.cs
index f072a88..9c023ab 100644
--- a/Plugin.TestResult/ViewControl.xaml.cs
+++ b/Plugin.TestResult/ViewControl.xaml.cs
@@ -7,7 +7,6 @@
using log4net;
using NationalInstruments.TestStand.Interop.API;
using NationalInstruments.TestStand.Interop.UI.Ax;
-using Plugin.TestResult;
using Plugin.TestResult_WPF.Model;
using Plugin.TestResult_WPF.Util;
using System;
@@ -22,7 +21,7 @@
/// <summary>
/// ViewControl.xaml 鐨勪氦浜掗�昏緫
/// </summary>
- public partial class ViewControl : PluginControl
+ public partial class ViewControl : PluginMaskControl
{
private CommonCodeParser codeParser = new CommonCodeParser();
private double TestTemperature = 60;
@@ -64,6 +63,20 @@
Logger = logger;
}
+ private bool isRunning = false;
+ public bool IsRunning
+ {
+ get => isRunning;
+ set
+ {
+ Set(ref isRunning, value);
+ testResultView.IsRunning = value;
+ this.modelSelect.IsEnabled = !value;
+ this.btnStart.IsEnabled = !value;
+ this.btnStop.IsEnabled = value;
+ }
+ }
+
public ViewControl()
{
DataContext = this;
@@ -98,7 +111,13 @@
public override void DoClose(object sender, EventArgs e)
{
- testResultView.ReleaseResource();
+ try
+ {
+ testResultView.ReleaseResource();
+ }
+ catch
+ {
+ }
}
private void axApplicationMgr_ExitApplication(object sender, EventArgs e)
@@ -118,6 +137,15 @@
string strData;
if (EventCase != 10014) return;
+
+ try
+ {
+ log.Info($"EventCase: {EventCase}, MethodCode: {MethodCode}, StrData: {e.uiMsg.StringData}");
+ }
+ catch
+ {
+
+ }
if (MethodCode == 0)
{
@@ -150,22 +178,41 @@
private bool isLoaded;
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
- new MaskWindow(Window.GetWindow(this),
- (win) =>
+ new MaskWindow(Window.GetWindow(this), (win) =>
+ {
+ try
+ {
+ Dispatcher.BeginInvoke(new Action(() =>
+ {
+ Start_Click(null, null);
+ Loaded -= UserControl_Loaded;
+ }));
+ }
+ finally
{
Dispatcher.Invoke(() =>
{
- try
- {
- Start_Click(null, null);
- Loaded -= UserControl_Loaded;
- }
- finally
- {
- win.Close();
- }
+ win.Close();
});
- }).Info(LangUtil.Get("Ts.SequenceIsStarting"));
+ }
+ }).Info(LangUtil.Get("Ts.SequenceIsStarting"), 100);
+
+ //ShowMask(() =>
+ //{
+ // Dispatcher.BeginInvoke(new Action(() =>
+ // {
+ // System.Threading.Thread.Sleep(100);
+ // Start_Click(null, null);
+ // Loaded -= UserControl_Loaded;
+ // }));
+ //}, (ex) =>
+ //{
+ // log.Error("Loaded Error.", ex);
+ // Dispatcher.BeginInvoke(new Action(() =>
+ // {
+ // MsgBoxHelper.Error(Window.GetWindow(this), ex.Message);
+ // }));
+ //}, "璇风◢鍚�", LangUtil.Get("Ts.SequenceIsStarting"));
}
public void LoadProduct()
@@ -223,9 +270,7 @@
try
{
testResultView.StartTestSequence();
- this.modelSelect.IsEnabled = false;
- this.btnStart.IsEnabled = false;
- this.btnStop.IsEnabled = true;
+ IsRunning = true;
}
catch (Exception ex)
{
@@ -240,9 +285,7 @@
try
{
testResultView.StopTest();
- this.modelSelect.IsEnabled = true;
- this.btnStart.IsEnabled = true;
- this.btnStop.IsEnabled = false;
+ IsRunning = false;
}
catch (Exception ex)
{
@@ -342,10 +385,11 @@
private void ScannerSetting_Click(object sender, RoutedEventArgs e)
{
- Plugin.TestResult.ScannerSetting setting = new Plugin.TestResult.ScannerSetting() {
+ Plugin.TestResult.ScannerSetting setting = new Plugin.TestResult.ScannerSetting()
+ {
Owner = Window.GetWindow(this)
};
- setting.Open(false,"Config");
+ setting.Open(false, "Config");
}
}
}
diff --git a/Plugin.TestResult/app.config b/Plugin.TestResult/app.config
deleted file mode 100644
index 907b804..0000000
--- a/Plugin.TestResult/app.config
+++ /dev/null
@@ -1,15 +0,0 @@
-锘�<?xml version="1.0" encoding="utf-8"?>
-<configuration>
- <runtime>
- <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
- <dependentAssembly>
- <assemblyIdentity name="log4net" publicKeyToken="669e0ddf0bb1aa2a" culture="neutral" />
- <bindingRedirect oldVersion="0.0.0.0-3.0.4.0" newVersion="3.0.4.0" />
- </dependentAssembly>
- <dependentAssembly>
- <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
- <bindingRedirect oldVersion="0.0.0.0-13.0.0.0" newVersion="13.0.0.0" />
- </dependentAssembly>
- </assemblyBinding>
- </runtime>
-</configuration>
\ No newline at end of file
diff --git a/Plugin.TsExecution/Entity/TestStep.cs b/Plugin.TsExecution/Entity/TestStep.cs
index 72962e8..2a768c6 100644
--- a/Plugin.TsExecution/Entity/TestStep.cs
+++ b/Plugin.TsExecution/Entity/TestStep.cs
@@ -8,6 +8,7 @@
public string LimitUp { get; set; }
public string LimitDown { get; set; }
public string Unit { get; set; }
+ public string ConsumeTime { get; set; }
public string Result { get; set; }
}
}
diff --git a/Plugin.TsExecution/Plugin.TsExecution.csproj b/Plugin.TsExecution/Plugin.TsExecution.csproj
index cc21afc..eb60ee6 100644
--- a/Plugin.TsExecution/Plugin.TsExecution.csproj
+++ b/Plugin.TsExecution/Plugin.TsExecution.csproj
@@ -180,7 +180,6 @@
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
- <None Include="app.config" />
<None Include="OpenTK.dll.config" />
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
@@ -209,6 +208,10 @@
<Project>{AFEA100A-9223-448D-AB10-3015D93DD98C}</Project>
<Name>HMI.Util</Name>
</ProjectReference>
+ <ProjectReference Include="..\SimpleUtil\HMI.MQUtil\HMI.MQUtil.csproj">
+ <Project>{f8b8b6b6-821b-4ff6-b556-9cab840ea57a}</Project>
+ <Name>HMI.MQUtil</Name>
+ </ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
diff --git a/Plugin.TsExecution/SingleControl.xaml b/Plugin.TsExecution/SingleControl.xaml
index 6d87ceb..11d834d 100644
--- a/Plugin.TsExecution/SingleControl.xaml
+++ b/Plugin.TsExecution/SingleControl.xaml
@@ -7,6 +7,7 @@
xmlns:pw="https://opensource.panuon.com/wpf"
xmlns:pu="https://opensource.panuon.com/wpf-ui"
xmlns:local="clr-namespace:Plugin.TsExecution"
+ xmlns:cdp="clr-namespace:HMI.Core.DpUtil;assembly=HMI.Core"
mc:Ignorable="d"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Loaded="UserControl_Loaded"
@@ -18,6 +19,7 @@
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
+ <ResourceDictionary Source="/HMI.UI;component/Style/PanuonListView.xaml"/>
<ResourceDictionary Source="/HMI.UI;component/Style/PanuonDataGrid.xaml"/>
</ResourceDictionary.MergedDictionaries>
<sys:Double x:Key="nanD">NaN</sys:Double>
@@ -202,6 +204,139 @@
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
+ <!--<ListView Grid.Row="0" Style="{StaticResource DefaultListTable}" x:Name="table"
+ ItemsSource="{Binding Datasource}"
+ VirtualizingPanel.IsContainerVirtualizable="True"
+VirtualizingPanel.IsVirtualizing="True"
+VirtualizingPanel.VirtualizationMode="Recycling"
+ pu:ListViewHelper.ItemsHeight="{StaticResource nanD}"
+ pu:ListViewHelper.ColumnHeaderFontSize="{Binding ActualWidth,
+ ElementName=control,
+Converter={StaticResource fc}, ConverterParameter='15,1093,15,22'}"
+ FontSize="{Binding ActualWidth,
+ ElementName=control,
+Converter={StaticResource fc}, ConverterParameter='15,1093,15,20'}"
+ pu:ListViewHelper.ColumnHeaderHeight="{Binding ActualWidth,ElementName=control,
+Converter={StaticResource fc}, ConverterParameter='30,1093,-1,45'}">
+ <ListView.View>
+ <GridView AllowsColumnReorder="False">
+ <GridViewColumn Width="60" Header="#">
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <TextBlock Text="{Binding Converter={StaticResource lvRowNumber},
+RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ListViewItem,AncestorLevel=1}}"/>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+
+ <GridViewColumn Width="200">
+ <GridViewColumn.Header>
+ <TextBlock Text="{DynamicResource Test.Name}"/>
+ </GridViewColumn.Header>
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <DockPanel>
+ <Border Style="{StaticResource CellBorder}">
+ <TextBlock Style="{StaticResource ListTableTextBlock}"
+ Text="{Binding Name}"/>
+ </Border>
+ </DockPanel>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+ <GridViewColumn Width="100">
+ <GridViewColumn.Header>
+ <TextBlock Text="{DynamicResource Test.Unit}"/>
+ </GridViewColumn.Header>
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <Grid HorizontalAlignment="Stretch" VerticalAlignment="Center">
+ <Border Style="{StaticResource CellBorder}" MouseDown="TextBlock_MouseDown">
+ <TextBlock Style="{StaticResource ListTableTextBlock}"
+ Text="{Binding Unit}"/>
+ </Border>
+ </Grid>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+ <GridViewColumn Width="120">
+ <GridViewColumn.Header>
+ <TextBlock Text="{DynamicResource Test.Value}"/>
+ </GridViewColumn.Header>
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <Border Style="{StaticResource CellBorder}">
+ <TextBlock Style="{StaticResource ListTableTextBlock}"
+ Text="{Binding Value}"/>
+ </Border>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+ <GridViewColumn Width="120">
+ <GridViewColumn.Header>
+ <TextBlock Text="{DynamicResource Test.LimitDown}"/>
+ </GridViewColumn.Header>
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <Border Style="{StaticResource CellBorder}">
+ <TextBlock Style="{StaticResource ListTableTextBlock}"
+ Text="{Binding LimitDown}"/>
+ </Border>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+ <GridViewColumn Width="120">
+ <GridViewColumn.Header>
+ <TextBlock Text="{DynamicResource Test.LimitUp}"/>
+ </GridViewColumn.Header>
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <Border Style="{StaticResource CellBorder}">
+ <TextBlock Style="{StaticResource ListTableTextBlock}"
+ Text="{Binding LimitUp}"/>
+ </Border>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+ <GridViewColumn Width="180">
+ <GridViewColumn.Header>
+ <TextBlock Text="{DynamicResource Test.ConsumeTime}"/>
+ </GridViewColumn.Header>
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <Border Style="{StaticResource CellBorder}">
+ <TextBlock Style="{StaticResource ListTableTextBlock}"
+ Text="{Binding ConsumeTime}"/>
+ </Border>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+ <GridViewColumn Width="120">
+ <GridViewColumn.Header>
+ <TextBlock Text="{DynamicResource Test.Result}"/>
+ </GridViewColumn.Header>
+ <GridViewColumn.CellTemplate>
+ <DataTemplate>
+ <Grid x:Name="border" Margin="0">
+ <TextBlock x:Name="text" Margin="-1" Padding="0" VerticalAlignment="Center" Text="{Binding Result}"/>
+ </Grid>
+ <DataTemplate.Triggers>
+ <DataTrigger Binding="{Binding Result}" Value="Passed">
+ <Setter TargetName="border" Property="Background" Value="{StaticResource passedColor}"/>
+ <Setter TargetName="text" Property="Foreground" Value="#000"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding Result}" Value="Failed">
+ <Setter TargetName="border" Property="Background" Value="{StaticResource DangerColor}"/>
+ <Setter TargetName="text" Property="Foreground" Value="#000"/>
+ </DataTrigger>
+ </DataTemplate.Triggers>
+ </DataTemplate>
+ </GridViewColumn.CellTemplate>
+ </GridViewColumn>
+ </GridView>
+ </ListView.View>
+ </ListView>-->
+
<DataGrid Grid.Row="0" Style="{StaticResource DefaultDataGrid}"
Margin="5,0,5,5"
pu:DataGridHelper.ColumnHeaderFontSize="{Binding ActualWidth,
@@ -237,15 +372,6 @@
</DataGrid.Resources>
<DataGrid.Columns>
- <!--<DataGridTemplateColumn Header="#" CanUserResize="False">
- <DataGridTemplateColumn.CellTemplate>
- <DataTemplate>
- <TextBlock Text="{Binding Converter={StaticResource rowNumber},
-RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGridRow},AncestorLevel=1}}"/>
- </DataTemplate>
- </DataGridTemplateColumn.CellTemplate>
- </DataGridTemplateColumn>-->
-
<DataGridTextColumn Header="#"
ElementStyle="{StaticResource TableTextBlock}"
Binding="{Binding Header, RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}, Mode=FindAncestor}}"
@@ -278,6 +404,12 @@
ElementStyle="{StaticResource TableTextBlock}">
<DataGridTextColumn.Header>
<TextBlock Text="{DynamicResource Test.LimitUp}"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>
+ <DataGridTextColumn Width="180" Binding="{Binding ConsumeTime}"
+ ElementStyle="{StaticResource TableTextBlock}">
+ <DataGridTextColumn.Header>
+ <TextBlock Text="{DynamicResource Test.ConsumeTime}"/>
</DataGridTextColumn.Header>
</DataGridTextColumn>
<DataGridTemplateColumn Width="120">
@@ -346,8 +478,10 @@
VerticalContentAlignment="Center" Content="{Binding ProbeWarn}"/>
</StackPanel>
- <Button FontSize="12" Style="{StaticResource LinkButton}" x:Name="clear" Margin="10,0,0,0" Click="Button_Click"
- Content="{DynamicResource App.Clear}"/>
+ <Button FontSize="12" Style="{StaticResource LinkButton}"
+ cdp:PermissionHelper.RequiredPermission="Permission:ClearProbeCount"
+ x:Name="clear" Margin="10,0,0,0" Click="Button_Click"
+ Content="{DynamicResource App.Clear}" Cursor=""/>
</StackPanel>
<Label x:Name="probeCountAlarm" Visibility="Collapsed" DockPanel.Dock="Left" Padding="30,0" FontSize="12" Foreground="Red"
@@ -358,6 +492,8 @@
</Grid>
<Canvas Grid.Row="0" Grid.RowSpan="5" Visibility="Collapsed"
+ VirtualizingPanel.IsVirtualizing="False"
+ VirtualizingPanel.VirtualizationMode="Standard"
Background="#AAFFFFFF" x:Name="pausePanel" SizeChanged="pausePanel_Loaded">
<Border BorderBrush="#000" Background="#FFF" BorderThickness="0.5"
CornerRadius="5"
@@ -379,10 +515,8 @@
<TextBlock Margin="20,20,20,0" Grid.Row="1"
FontSize="40"
- FontFamily="/Panuon.WPF.UI;component/Resources/Fonts/#PanuonIcon"
- Foreground="#F9D01A"
- Text=""
- />
+ FontFamily="/Panuon.WPF.UI;component/Resources/Fonts/#PanuonIcon"
+ Foreground="#F9D01A" Text=""/>
<Label Margin="0,20,20,0" Grid.Row="1" Grid.Column="1" Content="{DynamicResource Ts.PauseMsg}"/>
<StackPanel Margin="10" Grid.Row="2" Grid.ColumnSpan="2" Orientation="Horizontal" HorizontalAlignment="Right">
@@ -399,7 +533,7 @@
</Border>
</Canvas>
- <Canvas Grid.Row="0" Grid.RowSpan="5" Visibility="Collapsed"
+ <!--<Canvas Grid.Row="0" Grid.RowSpan="5" Visibility="Collapsed"
Background="#AAFFFFFF" x:Name="scannerPanel" SizeChanged="pausePanel_Loaded">
<Border BorderBrush="#000" Background="#FFF" BorderThickness="0.5" CornerRadius="5" x:Name="scannerVisualModal">
<Grid>
@@ -435,7 +569,7 @@
</StackPanel>
</Grid>
</Border>
- </Canvas>
+ </Canvas>-->
<!--<DockPanel Grid.Row="4">
diff --git a/Plugin.TsExecution/SingleControl.xaml.cs b/Plugin.TsExecution/SingleControl.xaml.cs
index 33afb58..293f3f6 100644
--- a/Plugin.TsExecution/SingleControl.xaml.cs
+++ b/Plugin.TsExecution/SingleControl.xaml.cs
@@ -1,7 +1,5 @@
锘縰sing HMI.Core.Manager;
using HMI.Core.Util;
-using HMI.UI;
-using HMI.UI.Util;
using HMI.Util;
using NationalInstruments.TestStand.Interop.API;
using Plugin.TsExecution.Entity;
@@ -10,10 +8,10 @@
using System.ComponentModel;
using System.IO;
using System.Runtime.CompilerServices;
-using System.Threading;
using System.Timers;
using System.Windows;
using System.Windows.Controls;
+using System.Windows.Media;
namespace Plugin.TsExecution
{
@@ -112,7 +110,8 @@
if (value == "Start Timing")
{
this.refreshTimer.Enabled = true;
- TimeNow = DateTime.Now;
+ TestStartTime = DateTime.Now;
+ StepStartTime = DateTime.Now;
}
else
{
@@ -136,7 +135,8 @@
}
}
- private DateTime TimeNow = new DateTime();
+ private DateTime TestStartTime = new DateTime();
+ private DateTime StepStartTime = new DateTime();
private TimeSpan TimeCount = new TimeSpan();
private System.Timers.Timer refreshTimer;
@@ -266,7 +266,7 @@
//AddTestData("1", "1", "1", "1", "1", "1", "1");
- TimeCount = DateTime.Now - TimeNow;
+ TimeCount = DateTime.Now - TestStartTime;
elapseTime = string.Format("{0:00}:{1:00}:{2:00}", TimeCount.Hours, TimeCount.Minutes, TimeCount.Seconds);
Set("ElapseTime");
Set("TestInfo");
@@ -297,8 +297,12 @@
Unit = unit,
Result = Status
};
- Dispatcher.BeginInvoke(new Action(() =>
+ table.Dispatcher.Invoke(new Action(() =>
{
+ var now = DateTime.Now;
+ var span = now - StepStartTime;
+ StepStartTime = now;
+ data.ConsumeTime = $"{span.Seconds}s";
Datasource.Add(data);
table.ScrollIntoView(data);
}));
@@ -506,22 +510,22 @@
}
public void ShowScannerPanel()
{
- scannerPanel.Visibility = Visibility.Visible;
+ //scannerPanel.Visibility = Visibility.Visible;
}
private void SendSnr2Ts()
{
- try
- {
- string snr = TbManualSnr.Text;
- SequenceFileContext?.StationGlobals.SetValString($"StationState.SN[{index}]", 1, snr);
- scannerPanel.Visibility = Visibility.Collapsed;
- TbManualSnr.Text = string.Empty;
- }
- catch (Exception ex)
- {
- ToastHelper.Error(ex.Message);
- }
+ //try
+ //{
+ // string snr = TbManualSnr.Text;
+ // SequenceFileContext?.StationGlobals.SetValString($"StationState.SN[{index}]", 1, snr);
+ // scannerPanel.Visibility = Visibility.Collapsed;
+ // TbManualSnr.Text = string.Empty;
+ //}
+ //catch (Exception ex)
+ //{
+ // ToastHelper.Error(ex.Message);
+ //}
}
private void pausePanel_Loaded(object sender, RoutedEventArgs e)
@@ -535,10 +539,18 @@
}
else
{
- var can = scannerPanel;
- var modal = scannerVisualModal;
- Canvas.SetLeft(modal, (scannerPanel.ActualWidth - scannerVisualModal.ActualWidth) / 2);
- Canvas.SetTop(modal, (scannerPanel.ActualHeight - scannerVisualModal.ActualHeight) / 2);
+ //var can = scannerPanel;
+ //var modal = scannerVisualModal;
+ //Canvas.SetLeft(modal, (scannerPanel.ActualWidth - scannerVisualModal.ActualWidth) / 2);
+ //Canvas.SetTop(modal, (scannerPanel.ActualHeight - scannerVisualModal.ActualHeight) / 2);
+ }
+ }
+
+ private void TextBlock_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
+ {
+ DependencyObject parent = VisualTreeHelper.GetParent((DependencyObject)sender);
+ while (parent != null) {
+ parent = VisualTreeHelper.GetParent(parent);
}
}
}
diff --git a/Plugin.TsExecution/TsExecution.xaml b/Plugin.TsExecution/TsExecution.xaml
index e2dbdfe..07384b6 100644
--- a/Plugin.TsExecution/TsExecution.xaml
+++ b/Plugin.TsExecution/TsExecution.xaml
@@ -11,127 +11,142 @@
xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
xmlns:ScottPlot="clr-namespace:ScottPlot.WPF;assembly=ScottPlot.WPF"
mc:Ignorable="d"
+ xmlns:ui="clr-namespace:HMI.UI;assembly=HMI.UI"
Padding="10"
Loaded="PluginControl_Loaded"
SizeChanged="PluginControl_SizeChanged"
Background="{StaticResource WorkspaceBackground}"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
- <Grid.ColumnDefinitions>
- <ColumnDefinition />
- <ColumnDefinition Width="Auto"/>
- </Grid.ColumnDefinitions>
+ <Grid>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition />
+ <ColumnDefinition Width="Auto"/>
+ </Grid.ColumnDefinitions>
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto"/>
- <RowDefinition/>
- </Grid.RowDefinitions>
- <WindowsFormsHost x:Name="host" Visibility="Collapsed"></WindowsFormsHost>
-
- <DockPanel Grid.Row="0" Grid.ColumnSpan="2" LastChildFill="False">
- <DockPanel.Resources>
- <Style TargetType="CheckBox">
- <Setter Property="FontSize" Value="20"/>
- <Setter Property="VerticalContentAlignment" Value="Center"/>
- </Style>
- </DockPanel.Resources>
-
- <StackPanel Orientation="Horizontal" VerticalAlignment="Center" dp:StackPanelHelper.ChildSpace="20">
- <pu:FormGroup HeaderHeight="Auto" HeaderPadding="0">
- <pu:FormGroup.Header>
- <TextBlock FontSize="20" Foreground="#000" Text="{DynamicResource Ts.SelectProductModel}"/>
- </pu:FormGroup.Header>
- <ComboBox Style="{StaticResource FormComboxStyle}" MinWidth="180" ItemsSource="{Binding Products}"
-DisplayMemberPath="Name" SelectedValuePath="Name"
-SelectedItem="{Binding SelectedProduct}" x:Name="CbProduct"/>
- </pu:FormGroup>
-
- <CheckBox Grid.Column="1"
- IsChecked="{Binding EnableMes,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
- Content="{DynamicResource Ts.EnableMes}"
- />
- <CheckBox Grid.Column="2"
- IsChecked="{Binding EnableNGPause,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
- Content="{DynamicResource Ts.EnableNGPause}"
- />
- <CheckBox Grid.Column="3"
- IsChecked="{Binding EnableDebugMode,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
- Content="{DynamicResource Ts.DebugMode}"/>
- <CheckBox Grid.Column="4"
-IsChecked="{Binding EnableSimpleMode,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
-Content="{DynamicResource Ts.EnableSimpleMode}"/>
-
- <CheckBox Grid.Column="4"
-IsChecked="{Binding UI_ShowInfoDock,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
-Content="{DynamicResource Ts.UI_ShowInfoDock}"/>
-
- <Label FontSize="20" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Padding="0"
- Content="{DynamicResource HMI.User.Code}"
- />
- <Label FontSize="20" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Padding="0"
- Content="{Binding CurrentUserCode}" />
- </StackPanel>
-
-
-
- <StackPanel DockPanel.Dock="Right" Orientation="Horizontal" dp:StackPanelHelper.ChildSpace="20">
- <Button Style="{StaticResource SuccessButton}"
-x:Name="BtnStartSeq" Click="Button_Click"
-Content="{DynamicResource Ts.BtnStartSeq}"/>
- <Button Grid.Row="1" Style="{StaticResource DangerButton}" IsEnabled="False"
-x:Name="BtnStopSeq" Click="Button_Click"
-Content="{DynamicResource Ts.BtnStopSeq}"/>
- <Button Grid.Row="2" Style="{StaticResource PrimaryButton}"
-x:Name="BtnClearNum" Click="Button_Click"
-Content="{DynamicResource Ts.BtnClearNum}"/>
- <Button Grid.Row="3"
-x:Name="BtnSample" Click="Button_Click">
- <Button.Style>
- <Style TargetType="Button" BasedOn="{StaticResource PrimaryButton}">
- <Style.Triggers>
- <DataTrigger Binding="{Binding SampleStatus}" Value="True">
- <Setter Property="Content" Value="{DynamicResource Ts.BtnIsSample}"/>
- </DataTrigger>
- <DataTrigger Binding="{Binding SampleStatus}" Value="False">
- <Setter Property="Content" Value="{DynamicResource Ts.BtnNotSample}"/>
- </DataTrigger>
- </Style.Triggers>
- </Style>
- </Button.Style>
- </Button>
- </StackPanel>
- </DockPanel>
-
- <Grid dp:GridHelper.Space="5" Grid.Row="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
- <RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
+ <WindowsFormsHost x:Name="host" Visibility="Collapsed"></WindowsFormsHost>
+
+ <DockPanel Grid.Row="0" Grid.ColumnSpan="2" LastChildFill="False">
+ <DockPanel.Resources>
+ <Style TargetType="CheckBox">
+ <Setter Property="FontSize" Value="20"/>
+ <Setter Property="VerticalContentAlignment" Value="Center"/>
+ </Style>
+ </DockPanel.Resources>
+
+ <StackPanel Orientation="Horizontal" VerticalAlignment="Center" dp:StackPanelHelper.ChildSpace="20">
+ <pu:FormGroup HeaderHeight="Auto" HeaderPadding="0">
+ <pu:FormGroup.Header>
+ <TextBlock FontSize="20" Foreground="#000" Text="{DynamicResource Ts.SelectProductModel}"/>
+ </pu:FormGroup.Header>
+ <ComboBox Style="{StaticResource FormComboxStyle}" MinWidth="180" ItemsSource="{Binding Products}"
+DisplayMemberPath="Name" SelectedValuePath="Name"
+SelectedItem="{Binding SelectedProduct}" x:Name="CbProduct"/>
+ </pu:FormGroup>
+
+ <CheckBox Grid.Column="1"
+ IsChecked="{Binding EnableMes,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
+ Content="{DynamicResource Ts.EnableMes}"
+ />
+ <CheckBox Grid.Column="2"
+ IsChecked="{Binding EnableNGPause,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
+ Content="{DynamicResource Ts.EnableNGPause}"
+ />
+ <CheckBox Grid.Column="3"
+ IsChecked="{Binding EnableDebugMode,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
+ Content="{DynamicResource Ts.DebugMode}"/>
+ <CheckBox Grid.Column="4"
+IsChecked="{Binding EnableSimpleMode,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
+Content="{DynamicResource Ts.EnableSimpleMode}"/>
+
+ <CheckBox Grid.Column="4"
+IsChecked="{Binding UI_ShowInfoDock,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
+Content="{DynamicResource Ts.UI_ShowInfoDock}"/>
+
+ <StackPanel Orientation="Horizontal" dp:StackPanelHelper.ChildSpace="5">
+ <Label FontSize="20" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Padding="0"
+ Content="{DynamicResource HMI.User.Code}" />
+ <Label FontSize="20" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Padding="0"
+ Content="{Binding CurrentUserCode}" />
+ </StackPanel>
- <UniformGrid x:Name="panel" Grid.Row="1" Columns="2" dp:UniformGridHelper.InnerBorder="1"
+ <StackPanel x:Name="workorderPanel" Visibility="Collapsed" Orientation="Horizontal" dp:StackPanelHelper.ChildSpace="5">
+ <Label FontSize="20" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Padding="0"
+Content="宸ュ崟鍙�"
+/>
+ <ui:EditBox FontSize="20" x:Name="workOrderEditor" MinWidth="50"
+ CanEdit="True"
+ ShowEmpty="True"
+ PreEditing="RequirePassword"
+ Value="{Binding CurrentWorkorder,Mode=TwoWay}"/>
+ </StackPanel>
+ </StackPanel>
+
+
+
+ <StackPanel DockPanel.Dock="Right" Orientation="Horizontal" dp:StackPanelHelper.ChildSpace="20">
+ <Button Style="{StaticResource SuccessButton}"
+x:Name="BtnStartSeq" Click="Button_Click"
+Content="{DynamicResource Ts.BtnStartSeq}"/>
+ <Button Grid.Row="1" Style="{StaticResource DangerButton}" IsEnabled="False"
+x:Name="BtnStopSeq" Click="Button_Click"
+Content="{DynamicResource Ts.BtnStopSeq}"/>
+ <Button Grid.Row="2" Style="{StaticResource PrimaryButton}"
+x:Name="BtnClearNum" Click="Button_Click"
+Content="{DynamicResource Ts.BtnClearNum}"/>
+ <Button Grid.Row="3"
+x:Name="BtnSample" Click="Button_Click">
+ <Button.Style>
+ <Style TargetType="Button" BasedOn="{StaticResource PrimaryButton}">
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding SampleStatus}" Value="True">
+ <Setter Property="Content" Value="{DynamicResource Ts.BtnIsSample}"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding SampleStatus}" Value="False">
+ <Setter Property="Content" Value="{DynamicResource Ts.BtnNotSample}"/>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Button.Style>
+ </Button>
+ </StackPanel>
+ </DockPanel>
+
+ <Grid dp:GridHelper.Space="5" Grid.Row="1">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition/>
+ <RowDefinition Height="Auto"/>
+ </Grid.RowDefinitions>
+
+
+ <UniformGrid x:Name="panel" Grid.Row="1" Columns="2" dp:UniformGridHelper.InnerBorder="1"
dp:UniformGridHelper.InnerBorderBrush="#3a3a3a">
- </UniformGrid>
- <Border x:Name="alarmPanel" VerticalAlignment="Bottom" Visibility="Visible" Background="Red"/>
- <!--<Border Grid.Row="1" x:Name="alarmPanel" Visibility="{Binding AlarmVisiable,Converter={StaticResource vbConverter}}"
+ </UniformGrid>
+ <!--<Border x:Name="alarmPanel" Height="80" VerticalAlignment="Bottom" Visibility="Visible" Background="Red"/>
+ <Border Grid.Row="1" x:Name="alarmPanel" Visibility="{Binding AlarmVisiable,Converter={StaticResource vbConverter}}"
Height="50" Background="Red"/>-->
- </Grid>
+ </Grid>
- <Grid Grid.Row="1" Grid.Column="1" x:Name="detailPanel">
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto"/>
- <RowDefinition Height="Auto"/>
- <RowDefinition Height="Auto"/>
- <RowDefinition />
- <RowDefinition Height="Auto"/>
- </Grid.RowDefinitions>
+ <Grid Grid.Row="1" Grid.Column="1" x:Name="detailPanel">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition />
+ <RowDefinition Height="Auto"/>
+ </Grid.RowDefinitions>
- <!--<GroupBox>
+ <!--<GroupBox>
<pu:FormGroup Orientation="Vertical"
HeaderHeight="Auto"
HeaderPadding="0" Header="{DynamicResource Ts.SelectProductModel}">
@@ -143,57 +158,57 @@
</pu:FormGroup>
</GroupBox>-->
- <GroupBox Grid.Row="2">
- <StackPanel>
- <pu:FormGroup Header="{DynamicResource Ts.MesStatus}" GroupName="Number">
- <Label Grid.Row="1">
- <Label.Style>
- <Style TargetType="Label">
- <Setter Property="Foreground" Value="#FFF"/>
- <Setter Property="HorizontalContentAlignment" Value="Center"/>
- <Setter Property="FontSize" Value="16"/>
- <Setter Property="FontWeight" Value="Bold"/>
- <Style.Triggers>
- <DataTrigger Binding="{Binding EnableMes}" Value="True">
- <Setter Property="Background" Value="Green"/>
- <Setter Property="Content" Value="{DynamicResource Ts.MesStatus.Enable}"/>
- </DataTrigger>
- <DataTrigger Binding="{Binding EnableMes}" Value="False">
- <Setter Property="Background" Value="Red"/>
- <Setter Property="Content" Value="{DynamicResource Ts.MesStatus.Disable}"/>
- </DataTrigger>
- </Style.Triggers>
- </Style>
- </Label.Style>
- </Label>
- </pu:FormGroup>
- <pu:FormGroup Header="{DynamicResource Ts.Total}" GroupName="Number">
- <TextBox Style="{StaticResource EditorTextBoxStyle}" IsReadOnly="True"
+ <GroupBox Grid.Row="2">
+ <StackPanel>
+ <pu:FormGroup Header="{DynamicResource Ts.MesStatus}" GroupName="Number">
+ <Label Grid.Row="1">
+ <Label.Style>
+ <Style TargetType="Label">
+ <Setter Property="Foreground" Value="#FFF"/>
+ <Setter Property="HorizontalContentAlignment" Value="Center"/>
+ <Setter Property="FontSize" Value="16"/>
+ <Setter Property="FontWeight" Value="Bold"/>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding EnableMes}" Value="True">
+ <Setter Property="Background" Value="Green"/>
+ <Setter Property="Content" Value="{DynamicResource Ts.MesStatus.Enable}"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding EnableMes}" Value="False">
+ <Setter Property="Background" Value="Red"/>
+ <Setter Property="Content" Value="{DynamicResource Ts.MesStatus.Disable}"/>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Label.Style>
+ </Label>
+ </pu:FormGroup>
+ <pu:FormGroup Header="{DynamicResource Ts.Total}" GroupName="Number">
+ <TextBox Style="{StaticResource EditorTextBoxStyle}" IsReadOnly="True"
x:Name="TbTotal"/>
- </pu:FormGroup>
- <pu:FormGroup Header="{DynamicResource Ts.Pass}" GroupName="Number">
- <TextBox Style="{StaticResource EditorTextBoxStyle}" IsReadOnly="True"
+ </pu:FormGroup>
+ <pu:FormGroup Header="{DynamicResource Ts.Pass}" GroupName="Number">
+ <TextBox Style="{StaticResource EditorTextBoxStyle}" IsReadOnly="True"
x:Name="TbPass"/>
- </pu:FormGroup>
- <pu:FormGroup Header="{DynamicResource Ts.Fail}" GroupName="Number">
- <TextBox Style="{StaticResource EditorTextBoxStyle}" IsReadOnly="True"
+ </pu:FormGroup>
+ <pu:FormGroup Header="{DynamicResource Ts.Fail}" GroupName="Number">
+ <TextBox Style="{StaticResource EditorTextBoxStyle}" IsReadOnly="True"
x:Name="TbFail"/>
- </pu:FormGroup>
- <pu:FormGroup Header="{DynamicResource Ts.PassRate}" GroupName="Number">
- <TextBox Style="{StaticResource EditorTextBoxStyle}" IsReadOnly="True"
+ </pu:FormGroup>
+ <pu:FormGroup Header="{DynamicResource Ts.PassRate}" GroupName="Number">
+ <TextBox Style="{StaticResource EditorTextBoxStyle}" IsReadOnly="True"
x:Name="TbPassRate"/>
- </pu:FormGroup>
- </StackPanel>
- </GroupBox>
+ </pu:FormGroup>
+ </StackPanel>
+ </GroupBox>
- <GroupBox Grid.Row="3">
- <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
- <ScottPlot:WpfPlot Background="Transparent" x:Name="pieChart" MinWidth="300" MinHeight="300"
+ <GroupBox Grid.Row="3">
+ <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
+ <ScottPlot:WpfPlot Background="Transparent" x:Name="pieChart" MinWidth="300" MinHeight="300"
SizeChanged="PluginControl_SizeChanged"/>
- </ScrollViewer>
- </GroupBox>
+ </ScrollViewer>
+ </GroupBox>
- <!-- <GroupBox Grid.Row="4">
+ <!-- <GroupBox Grid.Row="4">
<Grid dp:GridHelper.Space="20">
<Grid.RowDefinitions>
<RowDefinition/>
@@ -255,7 +270,7 @@
</pu:Switch>
</Grid>
</GroupBox> -->
+ </Grid>
</Grid>
-
</Grid>
</hb:PluginControl>
diff --git a/Plugin.TsExecution/TsExecution.xaml.cs b/Plugin.TsExecution/TsExecution.xaml.cs
index 89c3ac3..724fe97 100644
--- a/Plugin.TsExecution/TsExecution.xaml.cs
+++ b/Plugin.TsExecution/TsExecution.xaml.cs
@@ -1,9 +1,12 @@
锘縰sing HMI.Base;
using HMI.Core;
+using HMI.Core.Api;
using HMI.Core.Entity;
using HMI.Core.Manager;
using HMI.Core.Util;
+using HMI.MQUtil;
using HMI.UI;
+using HMI.UI.Controls;
using HMI.UI.Util;
using HMI.Util;
using log4net;
@@ -22,6 +25,7 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Forms.DataVisualization.Charting;
+using System.Windows.Media;
namespace Plugin.TsExecution
{
@@ -90,6 +94,8 @@
private ProductData selectedProduct;
+ private MSMQHelper mSMQHelper = new MSMQHelper("HMI_Alarm");
+
public ProductData SelectedProduct
{
get { return selectedProduct; }
@@ -119,6 +125,7 @@
private Pie pie;
private string CountIniPath;
+ private bool IsOptRequirePassword;
private bool alarmVisiable;
public bool AlarmVisiable
@@ -136,9 +143,12 @@
get => _enableMes;
set
{
- if (WriteConfig("EnableMes", value))
+ if (RequirePassword() == true)
{
- Set(ref _enableMes, value);
+ if (WriteConfig("EnableMes", value))
+ {
+ Set(ref _enableMes, value);
+ }
}
}
}
@@ -162,9 +172,12 @@
get => _enableDebugMode;
set
{
- if (WriteConfig("EnableDebugMode", value))
+ if (RequirePassword() == true)
{
- Set(ref _enableDebugMode, value);
+ if (WriteConfig("EnableDebugMode", value))
+ {
+ Set(ref _enableDebugMode, value);
+ }
}
}
}
@@ -175,9 +188,12 @@
get => _enableNGPause;
set
{
- if (WriteConfig("EnableNGPause", value))
+ if (RequirePassword() == true)
{
- Set(ref _enableNGPause, value);
+ if (WriteConfig("EnableNGPause", value))
+ {
+ Set(ref _enableNGPause, value);
+ }
}
}
}
@@ -210,6 +226,34 @@
}
}
+ private bool autoExecuteSeq;
+ public bool AutoExecuteSeq
+ {
+ get => autoExecuteSeq;
+ set
+ {
+ Set(ref autoExecuteSeq, value);
+ }
+ }
+
+ private string currentWorkorder;
+ public string CurrentWorkorder
+ {
+ get => currentWorkorder;
+ set
+ {
+ if (WriteIni("UI_CurrentWorkorder", value))
+ {
+ Set(ref currentWorkorder, value);
+ }
+ }
+ }
+
+ private string dataLogPath;
+ private SqliteHelper sqliteHelper;
+
+ private MQConnector mqConnector;
+
public TsExecution()
{
DataContext = this;
@@ -220,7 +264,6 @@
//鍒濆鍖朤estStand寮曟搸
this.InitTestStandEngine();
}
-
public override void SetBaseFolder(string folder)
{
CountIniPath = Path.Combine(folder, "Count.ini");
@@ -232,7 +275,70 @@
this.ReadCount(out int pass, out int fail);
this.DisplayCount(pass, fail);
InitProducts();
+ ReadConfig();
+ if (!File.Exists(dataLogPath))
+ {
+ SqliteHelper.CreateDatabase(dataLogPath);
+ }
+ sqliteHelper = new SqliteHelper(dataLogPath);
+ sqliteHelper.ExecuteSql(@"CREATE TABLE IF NOT EXISTS serialData (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ sn TEXT NOT NULL,
+ station TEXT NOT NULL,
+ step TEXT NOT NULL,
+ limitDown TEXT,
+ limitUp TEXT,
+ unit TEXT,
+ offset TEXT,
+ value TEXT,
+ status TEXT,
+ finalStatus TEXT,
+ consumeTime TEXT,
+ totalConsumeTime TEXT,
+ time DATETIME NOT NULL);");
base.InitFinish();
+ }
+
+ private void InitMQ()
+ {
+ mqConnector = new MQConnector("UI");
+ mqConnector.BeginReceive(HandleMQUI);
+ }
+
+ void HandleMQUI(string msg)
+ {
+ string[] arr = msg.Split('|');
+ int eventCode = int.Parse(arr[0]);
+ int index = int.Parse(arr[1]);
+ string strData = arr[2];
+ Dispatcher.BeginInvoke(new Action(() =>
+ {
+ HandleUIMessage(eventCode, index, strData);
+ }));
+ }
+
+ void createChildInNewThread(int index, string configFile, int probeWarn)
+ {
+ HostVisual hostVisual = new HostVisual();
+
+ UIElement content = new VisualHost(hostVisual);
+
+ System.Threading.Thread thread = new System.Threading.Thread(new System.Threading.ThreadStart(() =>
+ {
+ VisualTarget visualTarget = new VisualTarget(hostVisual);
+
+ var control = new SingleControl(index, configFile, probeWarn);
+ control.Arrange(new Rect(new Point(), content.RenderSize));
+
+ visualTarget.RootVisual = control;
+ tsSockets.Add(control);
+ System.Windows.Threading.Dispatcher.Run();
+ }));
+ //panel.Children.Add(content);
+
+ thread.SetApartmentState(System.Threading.ApartmentState.STA);
+ thread.IsBackground = true;
+ thread.Start();
}
/// <summary>
@@ -242,7 +348,7 @@
{
pieChart.Plot.Axes.Frameless();
pieChart.Plot.HideGrid();
- pieChart.Plot.DataBackground.Color = Colors.Transparent;
+ pieChart.Plot.DataBackground.Color = ScottPlot.Colors.Transparent;
var legend = pieChart.Plot.ShowLegend(Alignment.UpperRight);
legend.Alignment = Alignment.UpperRight;
@@ -252,15 +358,25 @@
pieChart.Plot.Font.Automatic();
List<PieSlice> slices = new List<PieSlice> {
- new PieSlice() { Value = 5, FillColor = Colors.Green,
+ new PieSlice() { Value = 5, FillColor = ScottPlot.Colors.Green,
LabelFontSize = (float)WidthSizeConverter.CountFontSize(20,300,300),
Label = "Pass",LegendText="Pass" },
- new PieSlice() { Value = 2, FillColor = Colors.Red,
+ new PieSlice() { Value = 2, FillColor = ScottPlot.Colors.Red,
LabelFontSize = (float)WidthSizeConverter.CountFontSize(20,300,300),
Label = "Fail",LegendText="Fail" } };
pie = pieChart.Plot.Add.Pie(slices);
+ }
+
+ private bool? RequirePassword()
+ {
+ if (!IsOptRequirePassword) return true;
+ var win = new RequirePasswordWindow
+ {
+ Owner = Window.GetWindow(this)
+ };
+ return win.ShowDialog();
}
private void InitProducts()
@@ -315,6 +431,7 @@
private void InitTsEngine()
{
AxApplicationMgr = new AxApplicationMgr();
+ AxApplicationMgr.EndExecution += AxApplicationMgr_EndExecution;
AxApplicationMgr.ExitApplication += new EventHandler(this.AxApplicationMgr_ExitApplication);
AxApplicationMgr.UIMessageEvent +=
new _ApplicationMgrEvents_UIMessageEventEventHandler(this.AxApplicationMgr_UIMessageEvent);
@@ -323,6 +440,11 @@
((System.ComponentModel.ISupportInitialize)(AxApplicationMgr)).BeginInit();
host.Child = AxApplicationMgr;
((System.ComponentModel.ISupportInitialize)(AxApplicationMgr)).EndInit();
+ }
+
+ private void AxApplicationMgr_EndExecution(object sender, _ApplicationMgrEvents_EndExecutionEvent e)
+ {
+ ReleaseSequenceFile();
}
private void PluginControl_Loaded(object sender, RoutedEventArgs e)
@@ -343,10 +465,9 @@
{
log.Warn("Get Login User Failed.", ex);
}
- ReadConfig();
});
isLoadOK = true;
- StartSequence();
+ if (AutoExecuteSeq) StartSequence();
}
catch (Exception ex)
{
@@ -369,25 +490,6 @@
{
if (isLoadOK) Loaded -= PluginControl_Loaded;
});
-
- //Dispatcher.Invoke(() =>
- //{
- // try
- // {
- // ReadConfig();
- // //杩炴帴OPChandle
- // //this.OpcHandle.Connect2("127.0.0.1", 6543, 18081, out string ErrMsg, null);
- // isLoadOK = true;
- // //鍚姩娴嬭瘯杩涚▼
- // StartSequence();
- // }
- // catch (Exception ex)
- // {
- // log.Error("TsExecution Loaded Failed.", ex);
- // MsgBoxHelper.Error(this, $"{LangUtil.Get("Ts.UserControlLoadFailed")}: {ex.Message}");
- // }
-
- //});
}
).Info(LangUtil.Get("App.UsercontrolIsLoading"));
}
@@ -415,6 +517,8 @@
SingleControl control = new SingleControl(i, CountIniPath, ProbeWarn);
panel.Children.Add(control);
tsSockets.Add(control);
+
+ //createChildInNewThread(i, CountIniPath, ProbeWarn);
}
if (tsSockets.Count == 1)
{
@@ -537,6 +641,16 @@
try
{
+ value = ParameterManager.GetCommonParameterByName("AutoExecuteSeq");
+ AutoExecuteSeq = bool.Parse(value.Value);
+ }
+ catch
+ {
+ AutoExecuteSeq = true;
+ }
+
+ try
+ {
value = ParameterManager.GetCommonParameterByName("TestReportFolder");
csvDir = value.Value;
@@ -548,6 +662,55 @@
catch
{
csvDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TestReport");
+ }
+
+ try
+ {
+
+ value = ParameterManager.GetCommonParameterByName("IsOptRequirePassword");
+ IsOptRequirePassword = bool.Parse(value.Value);
+ }
+ catch
+ {
+ IsOptRequirePassword = false;
+ }
+
+ try
+ {
+
+ value = ParameterManager.GetCommonParameterByName("UI_CurrentWorkorder");
+ currentWorkorder = value.Value;
+ Set("CurrentWorkorder");
+ }
+ catch
+ {
+ currentWorkorder = string.Empty;
+ Set("CurrentWorkorder");
+ }
+
+ try
+ {
+
+ value = ParameterManager.GetCommonParameterByName("TS_ShowTitleWorkorder");
+ var boo = bool.Parse(value.Value);
+ if (boo)
+ {
+ workorderPanel.Visibility = Visibility.Visible;
+ }
+ }
+ catch
+ {
+ }
+
+ try
+ {
+
+ value = ParameterManager.GetCommonParameterByName("TS_DataLogPath");
+ dataLogPath = value.Value;
+ }
+ catch
+ {
+ dataLogPath = Path.Combine(PathHelper.ConfigFolder, "DataBoard", "DataLog.db");
}
//Convert.ToBoolean(IniFileHelper.ReadIniData("Config", "EnableMes", "true", CountIniPath));
@@ -577,6 +740,27 @@
{
ts?.SequenceFileContext?.StationGlobals.SetValBoolean($"SystemSetting.{name}", 1, value);
}
+ return true;
+ }
+ else
+ {
+ throw new Exception(errMsg);
+ }
+ }
+ catch (Exception ex)
+ {
+ MsgBoxHelper2.Error(ex.Message);
+ return false;
+ }
+ }
+
+ private bool WriteIni(string name, object value)
+ {
+ //IniFileHelper.WriteIniData("Config", name, value.ToString(), CountIniPath);
+ try
+ {
+ if (ParameterManager.UpdateCommonParameter(name, value, out string errMsg))
+ {
return true;
}
else
@@ -664,10 +848,6 @@
engine?.CommitGlobalsToDisk(promptOnSaveConflicts: false);
this.modeSeq = this.engine.GetSequenceFileEx(@"C:\Program Files\National Instruments\TestStand 2020\Components\Models\TestStandModels\ParallelModel.seq");
this.testSeq = this.engine.GetSequenceFileEx(this.testSeqFile, 0, TypeConflictHandlerTypes.ConflictHandler_UseGlobalType);
-
- //var sb = testSeq.GetSequenceByName("MainSequence");
- //sb.
-
this.execution = this.engine.NewExecution(this.testSeq, "Test UUTs", this.modeSeq, false, 0, null, null, null);
IsTesting = true;
}
@@ -706,10 +886,6 @@
win.Close();
});
}
- //Dispatcher.Invoke(() =>
- //{
-
- //});
}
).Info(LangUtil.Get("App.SequenceIsStopping"));
}
@@ -736,7 +912,9 @@
}
}
if (this.execution == null) return true;
- return this.execution.WaitForEndEx(2000, true, null, null);
+
+ bool res = this.execution.WaitForEndEx(2000, true, null, null);
+ return res;
}
catch (Exception ex)
{
@@ -805,21 +983,7 @@
/// <param name="e"></param>
private void AxApplicationMgr_ExecutionClosed(object sender, _ApplicationMgrEvents_ExecutionClosedEvent e)
{
- try
- {
- if (this.testSeq == null)
- return;
- this.engine.ReleaseSequenceFileEx(this.testSeq, 0);
- this.engine.ReleaseSequenceFileEx(this.modeSeq, 0);
- this.engine.UnloadAllModules();
- this.testSeq = null;
- this.modeSeq = null;
- }
- catch (Exception ex)
- {
- log.Error("ReleaseSequenceFileEx Failed.", ex);
- MsgBoxHelper.Error(Window.GetWindow(this), $"{LangUtil.Get("Ts.ReleaseSequenceFileFail")}: {ex.Message}");
- }
+ ReleaseSequenceFile();
}
public void UpdatePositionStatus(int index, string status)
@@ -859,6 +1023,125 @@
this.tsSockets[index].WriteToCSV(csvPath);
}
+ public void SavePositionDB(int index)
+ {
+ var socket = this.tsSockets[index];
+ var time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
+ string snr = socket.Barcode;
+
+ List<string> sqls = new List<string>();
+ foreach (var data in socket.Datasource)
+ {
+ sqls.Add($@"INSERT INTO serialData (sn,station,step,limitDown,limitUp,unit,value,status,finalStatus,consumeTime,totalConsumeTime,time) VALUES
+('{snr}','','{data.Name}','{data.LimitDown}','{data.LimitUp}','{data.Unit}','{data.Value}','{data.Result}','{socket.Status}','{data.ConsumeTime}','{socket.ElapseTime}','{time}')");
+ }
+ sqliteHelper.ExecuteBatchSql(sqls);
+ }
+
+ private void HandleUIMessage(int eventCode, int index, string strData)
+ {
+ switch (eventCode)
+ {
+ case 10002://鏇存柊娴嬭瘯鐘舵��
+ string status = strData;
+ UpdatePositionStatus(index, status);
+ break;
+
+ case 10003://鍙戦�佹祴璇曟暟鎹�
+ AddTestData(index, strData);
+ break;
+
+ case 10004://鍙戦�佹祴璇曡繃绋嬩俊鎭�
+ this.tsSockets[index].CurrentStep = strData;
+ break;
+
+ case 10005://鍒濆鍖栨祴璇曟暟鎹紝娓呯┖娴嬭瘯鏁版嵁
+ this.tsSockets[index].IniTestData();
+ break;
+
+ case 10006://鍙戦�佷骇鍝佹潯鐮�
+ SetPositionBarcode(index, strData);
+ break;
+
+ case 10007://寮�濮嬫祴璇曡鏃�
+ tsSockets[index].ElapseTime = "Start Timing";
+ BtnStopSeq.IsEnabled = false;
+ break;
+
+ case 10008://鍋滄娴嬭瘯璁℃椂
+ tsSockets[index].ElapseTime = "Stop Timing";
+ BtnStopSeq.IsEnabled = true;
+ break;
+
+ case 10009:
+ //
+ break;
+
+ case 10010:
+
+ //PropertyObj.SetValBoolean("Locals.MD5_Used", 0, true);
+ //PropertyObj.SetValVariant("FileGlobals.MD5_Value", 0, MD5_DATA);
+ //PropertyObj.SetValVariant("StationGlobals.MD5", 0, MD5_DATA);
+ break;
+
+ case 10011:
+ // write model
+
+ break;
+
+ case 10012:
+ // read model
+
+ break;
+
+ case 10013:
+ // read continue
+
+
+ break;
+
+ case 10014:
+
+ break;
+
+ case 10015:
+
+ break;
+ case 10016://鏄剧ず3D鎷兼帴鍥剧墖
+
+ break;
+ case 10017://鏇存柊娴嬭瘯璁℃椂锛岄拡瀵归儴鍒嗚鏃舵湁PLC瀹屾垚鐨勯」鐩�
+ this.tsSockets[index].ElapseTime = strData;
+ break;
+ case (int)UIMessageCodes.UIMsg_EndExecution://鎵ц缁撴潫
+ IsTesting = false;
+ //this.ReleaseSequenceFile();
+ break;
+ case 10030://鏄剧ず娴嬭瘯杩涘害
+ int ProcessVal = Convert.ToInt32(strData);
+ this.tsSockets[index].SetTestProcess(ProcessVal);
+ break;
+ case 10031://瀵煎嚭CSV
+ SavePositionCSV(index);
+ SavePositionDB(index);
+ break;
+ case 10032://鎸変笅鏍囨殏鍋滄祴璇�
+ this.tsSockets[index].ShowPausePanel();
+ break;
+ case 10033:
+ ShowAlarm(strData);
+ break;
+ default:
+ break;
+ }
+ }
+
+ private void ShowAlarm(string info)
+ {
+ AlarmShowHelper.ShowAlarm(info);
+ mSMQHelper.Send("Alarm", $"ATE娴嬭瘯 {info}");
+ }
+
/// <summary>
/// TestStand鐢ㄦ埛浜や簰浜嬩欢
/// </summary>
@@ -868,113 +1151,24 @@
{
try
{
- int EventCase = Convert.ToInt32(e.uiMsg.Event);
- int Index = Convert.ToInt16(e.uiMsg.NumericData);//SocketIndex
+ int eventCode = Convert.ToInt32(e.uiMsg.Event);
+ int index = Convert.ToInt16(e.uiMsg.NumericData);//SocketIndex
string strData = e.uiMsg.StringData;
try
{
- log.Info($"Event: {EventCase}, NumericData: {Index}, StringData: {strData}");
+ log.Info($"Event: {eventCode}, NumericData: {index}, StringData: {strData}");
}
catch
{
}
-
- switch (EventCase)
+ if (eventCode == 10001)
{
- case 10001://浼犻�扴ocketContext
- tsSockets[Index].SequenceFileContext = (SequenceContext)e.uiMsg.ActiveXData;
- break;
-
- case 10002://鏇存柊娴嬭瘯鐘舵��
- string status = e.uiMsg.StringData;
- UpdatePositionStatus(Index, status);
- break;
-
- case 10003://鍙戦�佹祴璇曟暟鎹�
- AddTestData(Index, e.uiMsg.StringData);
- break;
-
- case 10004://鍙戦�佹祴璇曡繃绋嬩俊鎭�
- this.tsSockets[Index].CurrentStep = e.uiMsg.StringData;
- break;
-
- case 10005://鍒濆鍖栨祴璇曟暟鎹紝娓呯┖娴嬭瘯鏁版嵁
- this.tsSockets[Index].IniTestData();
- break;
-
- case 10006://鍙戦�佷骇鍝佹潯鐮�
- SetPositionBarcode(Index, e.uiMsg.StringData);
- break;
-
- case 10007://寮�濮嬫祴璇曡鏃�
- tsSockets[Index].ElapseTime = "Start Timing";
- BtnStopSeq.IsEnabled = false;
- break;
-
- case 10008://鍋滄娴嬭瘯璁℃椂
- tsSockets[Index].ElapseTime = "Stop Timing";
- BtnStopSeq.IsEnabled = true;
- break;
-
- case 10009:
- //
- break;
-
- case 10010:
-
- //PropertyObj.SetValBoolean("Locals.MD5_Used", 0, true);
- //PropertyObj.SetValVariant("FileGlobals.MD5_Value", 0, MD5_DATA);
- //PropertyObj.SetValVariant("StationGlobals.MD5", 0, MD5_DATA);
- break;
-
- case 10011:
- // write model
-
- break;
-
- case 10012:
- // read model
-
- break;
-
- case 10013:
- // read continue
-
-
- break;
-
- case 10014:
-
- break;
-
- case 10015:
-
- break;
- case 10016://鏄剧ず3D鎷兼帴鍥剧墖
-
- break;
- case 10017://鏇存柊娴嬭瘯璁℃椂锛岄拡瀵归儴鍒嗚鏃舵湁PLC瀹屾垚鐨勯」鐩�
- this.tsSockets[Index].ElapseTime = e.uiMsg.StringData;
- break;
- case (int)UIMessageCodes.UIMsg_EndExecution://鎵ц缁撴潫
- IsTesting = false;
- // this.ReleaseSequenceFile();
- break;
- case 10030://鏄剧ず娴嬭瘯杩涘害
- int ProcessVal = Convert.ToInt32(e.uiMsg.StringData);
- this.tsSockets[Index].SetTestProcess(ProcessVal);
- break;
- case 10031://瀵煎嚭CSV
- SavePositionCSV(Index);
- break;
- case 10032://鎸変笅鏍囨殏鍋滄祴璇�
- this.tsSockets[Index].ShowPausePanel();
- break;
- default:
- break;
+ tsSockets[index].SequenceFileContext = (SequenceContext)e.uiMsg.ActiveXData;
+ return;
}
+ HandleUIMessage(eventCode, index, strData);
}
catch (Exception ex)
{
@@ -1027,13 +1221,6 @@
try
{
StopSequence();
- // this.engine?.TerminateAll();
- // this.engine?.ReleaseSequenceFileEx(this.testSeq, 0);
- // this.engine?.ReleaseSequenceFileEx(this.modeSeq, 0);
- // this.engine?.UnloadAllModules();
- // this.engine?.ShutDown(true);
- //this.testSeq = null;
- //this.modeSeq = null;
base.OnClose(sender, e);
}
catch (Exception ex)
@@ -1042,6 +1229,36 @@
}
}
+ /// <summary>
+ /// 閲婃斁鎵�鏈夌殑搴忓垪鏂囦欢
+ /// </summary>
+ private bool ReleaseSequenceFile()
+ {
+ try
+ {
+ lock (this)
+ {
+ if (this.testSeq == null)
+ return true;
+ if (this.engine.ReleaseSequenceFileEx(this.testSeq, 4))
+ {
+ this.testSeq = null;
+ }
+ if (this.engine.ReleaseSequenceFileEx(this.modeSeq, 4))
+ {
+ this.modeSeq = null;
+ }
+ this.engine.UnloadAllModules();
+ return true;
+ }
+ }
+ catch (Exception ex)
+ {
+ log.Warn("ReleaseSequenceFile Error.", ex);
+ return false;
+ }
+ }
+
private void PluginControl_SizeChanged(object sender, SizeChangedEventArgs e)
{
diff --git a/Plugin.TsExecution/app.config b/Plugin.TsExecution/app.config
deleted file mode 100644
index a0cefc2..0000000
--- a/Plugin.TsExecution/app.config
+++ /dev/null
@@ -1,11 +0,0 @@
-锘�<?xml version="1.0" encoding="utf-8"?>
-<configuration>
- <runtime>
- <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
- <dependentAssembly>
- <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
- <bindingRedirect oldVersion="0.0.0.0-13.0.0.0" newVersion="13.0.0.0" />
- </dependentAssembly>
- </assemblyBinding>
- </runtime>
-</configuration>
\ No newline at end of file
diff --git a/Plugin.TsSupport/Plugin.TsSupport.csproj b/Plugin.TsSupport/Plugin.TsSupport.csproj
new file mode 100644
index 0000000..7b4a211
--- /dev/null
+++ b/Plugin.TsSupport/Plugin.TsSupport.csproj
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{3068124E-F12B-473E-99A0-2DA5A0385D05}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Plugin.TsSupport</RootNamespace>
+ <AssemblyName>Plugin.TsSupport</AssemblyName>
+ <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <Deterministic>true</Deterministic>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NationalInstruments.TestStand.Interop.API, Version=20.0.0.49158, Culture=neutral, PublicKeyToken=ad9244eb3b825cd8, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <EmbedInteropTypes>True</EmbedInteropTypes>
+ <HintPath>..\..\..\..\Program Files\National Instruments\TestStand 2020\API\DotNET\Assemblies\CurrentVersion\NationalInstruments.TestStand.Interop.API.dll</HintPath>
+ </Reference>
+ <Reference Include="NationalInstruments.TestStand.Interop.UI.AxControls, Version=20.0.0.49158, Culture=neutral, PublicKeyToken=ad9244eb3b825cd8, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\..\..\..\Program Files\National Instruments\TestStand 2020\API\DotNET\Assemblies\CurrentVersion\NationalInstruments.TestStand.Interop.UI.AxControls.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Windows.Forms" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Net.Http" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="TestAppManager.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>
\ No newline at end of file
diff --git a/Plugin.TsSupport/Properties/AssemblyInfo.cs b/Plugin.TsSupport/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..427f8ed
--- /dev/null
+++ b/Plugin.TsSupport/Properties/AssemblyInfo.cs
@@ -0,0 +1,33 @@
+锘縰sing System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// 鏈夊叧绋嬪簭闆嗙殑涓�鑸俊鎭敱浠ヤ笅
+// 鎺у埗銆傛洿鏀硅繖浜涚壒鎬у�煎彲淇敼
+// 涓庣▼搴忛泦鍏宠仈鐨勪俊鎭��
+[assembly: AssemblyTitle("Plugin.TsSupport")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Plugin.TsSupport")]
+[assembly: AssemblyCopyright("Copyright 漏 2025")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 灏� ComVisible 璁剧疆涓� false 浼氫娇姝ょ▼搴忛泦涓殑绫诲瀷
+//瀵� COM 缁勪欢涓嶅彲瑙併�傚鏋滈渶瑕佷粠 COM 璁块棶姝ょ▼搴忛泦涓殑绫诲瀷
+//璇峰皢姝ょ被鍨嬬殑 ComVisible 鐗规�ц缃负 true銆�
+[assembly: ComVisible(false)]
+
+// 濡傛灉姝ら」鐩悜 COM 鍏紑锛屽垯涓嬪垪 GUID 鐢ㄤ簬绫诲瀷搴撶殑 ID
+[assembly: Guid("3068124e-f12b-473e-99a0-2da5a0385d05")]
+
+// 绋嬪簭闆嗙殑鐗堟湰淇℃伅鐢变笅鍒楀洓涓�肩粍鎴�:
+//
+// 涓荤増鏈�
+// 娆$増鏈�
+// 鐢熸垚鍙�
+// 淇鍙�
+//
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Plugin.TsSupport/TestAppManager.cs b/Plugin.TsSupport/TestAppManager.cs
new file mode 100644
index 0000000..aff44ab
--- /dev/null
+++ b/Plugin.TsSupport/TestAppManager.cs
@@ -0,0 +1,17 @@
+锘縰sing NationalInstruments.TestStand.Interop.UI.Ax;
+
+namespace Plugin.TsSupport
+{
+ public class TestAppManager
+ {
+ private static AxApplicationMgr instance;
+ public static AxApplicationMgr GetAxApplicationMgr()
+ {
+ if (instance == null)
+ {
+ instance = new AxApplicationMgr();
+ }
+ return instance;
+ }
+ }
+}
diff --git a/SimpleUtil/HMI.MQUtil/HMI.MQUtil.csproj b/SimpleUtil/HMI.MQUtil/HMI.MQUtil.csproj
new file mode 100644
index 0000000..67d0915
--- /dev/null
+++ b/SimpleUtil/HMI.MQUtil/HMI.MQUtil.csproj
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{F8B8B6B6-821B-4FF6-B556-9CAB840EA57A}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>HMI.MQUtil</RootNamespace>
+ <AssemblyName>HMI.MQUtil</AssemblyName>
+ <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <Deterministic>true</Deterministic>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Messaging" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Net.Http" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="MQConnector.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>
\ No newline at end of file
diff --git a/SimpleUtil/HMI.MQUtil/MQConnector.cs b/SimpleUtil/HMI.MQUtil/MQConnector.cs
new file mode 100644
index 0000000..d93b519
--- /dev/null
+++ b/SimpleUtil/HMI.MQUtil/MQConnector.cs
@@ -0,0 +1,110 @@
+锘縰sing System;
+using System.Messaging;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace HMI.MQUtil
+{
+ public class MQConnector : IDisposable
+ {
+ private MessageQueue myQueue = null;
+
+ public MQConnector(string name)
+ {
+ string mqName = $".\\private$\\{name}";
+ //濡傛灉涓嶅瓨鍦╩qName娑堟伅闃熷垪锛屽垯鍒涘缓璇qName娑堟伅闃熷垪
+ if (!MessageQueue.Exists(mqName))
+ {
+ MessageQueue.Create(mqName);
+
+ myQueue = new MessageQueue(mqName);
+ myQueue.SetPermissions("Everyone", MessageQueueAccessRights.FullControl, AccessControlEntryType.Allow); //鍔犳潈闄�
+ myQueue.SetPermissions("ANONYMOUS LOGON", MessageQueueAccessRights.FullControl, AccessControlEntryType.Allow);
+ }
+ else
+ {
+ myQueue = new MessageQueue(mqName);
+ }
+ }
+
+ public MQConnector(string host, string name)
+ {
+ string mqName = $@"FormatName:Direct=TCP:{host}\Private$\{name}";
+ if (!MessageQueue.Exists(mqName))
+ {
+ MessageQueue.Create(mqName);
+
+ myQueue = new MessageQueue(mqName);
+ myQueue.SetPermissions("Everyone", MessageQueueAccessRights.FullControl, AccessControlEntryType.Allow); //鍔犳潈闄�
+ myQueue.SetPermissions("ANONYMOUS LOGON", MessageQueueAccessRights.FullControl, AccessControlEntryType.Allow);
+ }
+ else
+ {
+ myQueue = new MessageQueue(mqName);
+ }
+ }
+
+ public void ClearAll()
+ {
+ myQueue?.Purge();
+ }
+
+ public void Close()
+ {
+ myQueue?.Close();
+ }
+
+
+
+ ManualResetEvent signal = new ManualResetEvent(false);
+
+ public void BeginReceive(Action<string> action)
+ {
+ Task.Run(() =>
+ {
+ //杩欓噷浣跨敤浜嗗鎵�,褰撴帴鏀舵秷鎭畬鎴愮殑鏃跺�欏氨鎵цMyReceiveCompleted鏂规硶
+ myQueue.ReceiveCompleted += new ReceiveCompletedEventHandler((source, e) =>
+ {
+ try
+ {
+ MessageQueue mq = (MessageQueue)source;
+ //瀹屾垚鎸囧畾鐨勫紓姝ユ帴鏀舵搷浣�
+ Message message = mq.EndReceive(e.AsyncResult);
+ signal.Set();
+ action(message.Body.ToString());
+ mq.BeginReceive();
+ }
+ catch (MessageQueueException)
+ {
+
+ }
+ });
+ myQueue.Formatter = new XmlMessageFormatter(new Type[] { typeof(String) });
+ myQueue.BeginReceive();
+ signal.WaitOne();
+ });
+ }
+
+ private void MyReceiveCompleted(Object source, ReceiveCompletedEventArgs asyncResult)
+ {
+
+ }
+
+ public bool SendMessage(string message)
+ {
+ myQueue.Send(message);
+ return true;
+ }
+
+ public bool SendUIMessage(int eventCode, int number, string message)
+ {
+ myQueue.Send($"{eventCode}|{number}|{message}");
+ return true;
+ }
+
+ public void Dispose()
+ {
+ Close();
+ }
+ }
+}
diff --git a/SimpleUtil/HMI.MQUtil/Properties/AssemblyInfo.cs b/SimpleUtil/HMI.MQUtil/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..06a22e8
--- /dev/null
+++ b/SimpleUtil/HMI.MQUtil/Properties/AssemblyInfo.cs
@@ -0,0 +1,33 @@
+锘縰sing System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// 鏈夊叧绋嬪簭闆嗙殑涓�鑸俊鎭敱浠ヤ笅
+// 鎺у埗銆傛洿鏀硅繖浜涚壒鎬у�煎彲淇敼
+// 涓庣▼搴忛泦鍏宠仈鐨勪俊鎭��
+[assembly: AssemblyTitle("HMI.MQUtil")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HMI.MQUtil")]
+[assembly: AssemblyCopyright("Copyright 漏 2025")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 灏� ComVisible 璁剧疆涓� false 浼氫娇姝ょ▼搴忛泦涓殑绫诲瀷
+//瀵� COM 缁勪欢涓嶅彲瑙併�傚鏋滈渶瑕佷粠 COM 璁块棶姝ょ▼搴忛泦涓殑绫诲瀷
+//璇峰皢姝ょ被鍨嬬殑 ComVisible 鐗规�ц缃负 true銆�
+[assembly: ComVisible(false)]
+
+// 濡傛灉姝ら」鐩悜 COM 鍏紑锛屽垯涓嬪垪 GUID 鐢ㄤ簬绫诲瀷搴撶殑 ID
+[assembly: Guid("f8b8b6b6-821b-4ff6-b556-9cab840ea57a")]
+
+// 绋嬪簭闆嗙殑鐗堟湰淇℃伅鐢变笅鍒楀洓涓�肩粍鎴�:
+//
+// 涓荤増鏈�
+// 娆$増鏈�
+// 鐢熸垚鍙�
+// 淇鍙�
+//
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/SimpleUtil/HMI.SerialData.Util/SerialDataHelper.cs b/SimpleUtil/HMI.SerialData.Util/SerialDataHelper.cs
index 4661184..178c70d 100644
--- a/SimpleUtil/HMI.SerialData.Util/SerialDataHelper.cs
+++ b/SimpleUtil/HMI.SerialData.Util/SerialDataHelper.cs
@@ -17,7 +17,15 @@
sn TEXT NOT NULL,
station TEXT NOT NULL,
step TEXT NOT NULL,
- status TEXT NOT NULL,
+ limitDown TEXT,
+ limitUp TEXT,
+ unit TEXT,
+ offset TEXT,
+ value TEXT,
+ status TEXT,
+ finalStatus TEXT,
+ consumeTime BIGINT,
+ totalConsumeTime BIGINT,
time DATETIME NOT NULL);";
private static string GetConnectionStr(string dbFile)
diff --git a/SimpleUtil/HMI.Simple.Util/HMI.Simple.Util.csproj b/SimpleUtil/HMI.Simple.Util/HMI.Simple.Util.csproj
index 8d18e6e..eea004c 100644
--- a/SimpleUtil/HMI.Simple.Util/HMI.Simple.Util.csproj
+++ b/SimpleUtil/HMI.Simple.Util/HMI.Simple.Util.csproj
@@ -36,6 +36,9 @@
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
+ <Reference Include="System.Data.SQLite">
+ <HintPath>..\..\..\HMI.Old\Plugin_OPCServer\Libs\System.Data.SQLite.dll</HintPath>
+ </Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
@@ -46,8 +49,10 @@
<ItemGroup>
<Compile Include="ParameterUtil.cs" />
<Compile Include="Parameter.cs" />
+ <Compile Include="ProductModelHelper.cs" />
<Compile Include="ProductUtil.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="SqliteHelper.cs" />
<Compile Include="XmlHelper.cs" />
</ItemGroup>
<ItemGroup>
diff --git a/SimpleUtil/HMI.Simple.Util/Parameter.cs b/SimpleUtil/HMI.Simple.Util/Parameter.cs
index 71237da..97bc1da 100644
--- a/SimpleUtil/HMI.Simple.Util/Parameter.cs
+++ b/SimpleUtil/HMI.Simple.Util/Parameter.cs
@@ -1,6 +1,6 @@
锘縩amespace HMI.Simple.Util
{
- public class ParameterData
+ internal class ParameterData
{
public string Id { get; set; }
public string Name { get; set; }
diff --git a/SimpleUtil/HMI.Simple.Util/ProductModelHelper.cs b/SimpleUtil/HMI.Simple.Util/ProductModelHelper.cs
new file mode 100644
index 0000000..dd584fb
--- /dev/null
+++ b/SimpleUtil/HMI.Simple.Util/ProductModelHelper.cs
@@ -0,0 +1,106 @@
+锘縰sing System;
+using System.Data;
+using System.IO;
+
+namespace HMI.Simple.Util
+{
+ public class ProductModelHelper
+ {
+ public static bool GetModelBySNR(string snr, out string model, out string msg)
+ {
+ model = string.Empty;
+ msg = string.Empty;
+ SqliteHelper sqliteHelper = null;
+ try
+ {
+ string appFolder = RegUtil.GetLocaltion();
+ string dbFilePath = Path.Combine(appFolder, "Config", "ModelManage", "data.db");
+ if (!File.Exists(dbFilePath))
+ {
+ msg = "鏁版嵁搴撴枃浠朵笉瀛樺湪";
+ return false;
+ }
+ sqliteHelper = new SqliteHelper(dbFilePath);
+
+ int codeLength = snr.Length;
+ var sql = $@"SELECT Model, CodeLength, StartIndex, Fixcode FROM ModelData
+WHERE CodeLength = {codeLength} AND SUBSTR('{snr}', StartIndex, LENGTH(Fixcode) + StartIndex + 1) = Fixcode";
+ //var sql = $@"SELECT Model, CodeLength, StartIndex, Length, Fixcode FROM ModelData WHERE CodeLength={codeLength} AND '{snr}' LIKE '%'||Fixcode||'%'";
+ DataTable dt = sqliteHelper.GetDataTable(sql);
+ if (dt.Rows.Count <= 0)
+ {
+ msg = "娌℃湁鍖归厤鐨勫瀷鍙�";
+ return false;
+ }
+ foreach (DataRow dr in dt.Rows)
+ {
+ var startIndex = int.Parse(dr["StartIndex"].ToString());
+ var fixcode = dr["Fixcode"].ToString();
+ if (string.Equals(snr.Substring(startIndex, fixcode.Length), fixcode, StringComparison.CurrentCultureIgnoreCase))
+ {
+ model = dr["Model"].ToString();
+ return true;
+ }
+ }
+ msg = "娌℃湁鍖归厤鐨勫瀷鍙�";
+ return false;
+ }
+ catch (Exception ex)
+ {
+ msg = ex.Message;
+ return false;
+ }
+ finally
+ {
+ sqliteHelper?.Dispose();
+ }
+ }
+
+ public static bool GetModelBySNR(string dbFilePath, string snr, out string model, out string msg)
+ {
+ model = string.Empty;
+ msg = string.Empty;
+ SqliteHelper sqliteHelper = null;
+ try
+ {
+ if (!File.Exists(dbFilePath))
+ {
+ msg = "鏁版嵁搴撴枃浠朵笉瀛樺湪";
+ return false;
+ }
+ sqliteHelper = new SqliteHelper(dbFilePath);
+
+ int codeLength = snr.Length;
+ var sql = $@"SELECT Model, CodeLength, StartIndex, Fixcode FROM ModelData
+WHERE CodeLength = {codeLength} AND SUBSTR('{snr}', StartIndex, LENGTH(Fixcode) + StartIndex + 1) = Fixcode";
+ DataTable dt = sqliteHelper.GetDataTable(sql);
+ if (dt.Rows.Count <= 0)
+ {
+ msg = "娌℃湁鍖归厤鐨勫瀷鍙�";
+ return false;
+ }
+ foreach (DataRow dr in dt.Rows)
+ {
+ var startIndex = int.Parse(dr["StartIndex"].ToString());
+ var fixcode = dr["Fixcode"].ToString();
+ if (string.Equals(snr.Substring(startIndex, fixcode.Length), fixcode, StringComparison.CurrentCultureIgnoreCase))
+ {
+ model = dr["Model"].ToString();
+ return true;
+ }
+ }
+ msg = "娌℃湁鍖归厤鐨勫瀷鍙�";
+ return false;
+ }
+ catch (Exception ex)
+ {
+ msg = ex.Message;
+ return false;
+ }
+ finally
+ {
+ sqliteHelper?.Dispose();
+ }
+ }
+ }
+}
diff --git a/SimpleUtil/HMI.Simple.Util/SqliteHelper.cs b/SimpleUtil/HMI.Simple.Util/SqliteHelper.cs
new file mode 100644
index 0000000..768d49c
--- /dev/null
+++ b/SimpleUtil/HMI.Simple.Util/SqliteHelper.cs
@@ -0,0 +1,238 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Data;
+using System.Data.SQLite;
+
+namespace HMI.Simple.Util
+{
+ internal class SqliteHelper : IDisposable
+ {
+ public string DataBaseFile { get; private set; } = string.Empty;
+
+ private string ConnectString = string.Empty;
+
+ private SQLiteConnection conn = null;
+
+ private SQLiteCommand cmd = null;
+
+ public SqliteHelper(string DBFile)
+ {
+ DataBaseFile = DBFile;
+ ConnectString = "DataSource=" + DataBaseFile + ";Version=3;Pooling=False;Max Pool Size=100;";
+ conn = new SQLiteConnection(ConnectString);
+ cmd = new SQLiteCommand(conn);
+ }
+
+ public static bool CreateDatabase(string DataBaseFile)
+ {
+ try
+ {
+ SQLiteConnection.CreateFile(DataBaseFile);
+ return true;
+ }
+ catch (Exception ex)
+ {
+ throw new Exception($"Create Database [${DataBaseFile}] Failed.", ex);
+ }
+ }
+
+ public int ExecuteSql(string Sql)
+ {
+ try
+ {
+ Connect();
+ cmd.CommandType = CommandType.Text;
+ cmd.CommandText = Sql;
+ return cmd.ExecuteNonQuery();
+ }
+ catch (Exception ex)
+ {
+ string message = "ExecuteSql Error:" + ex.Message;
+ throw new Exception(message);
+ }
+ finally
+ {
+ DisConnect();
+ }
+ }
+
+ public void ExecuteBatchSql(IEnumerable<string> sqls)
+ {
+ SQLiteTransaction tr = null;
+ try
+ {
+ Connect();
+ tr = conn.BeginTransaction();
+ cmd.CommandType = CommandType.Text;
+ foreach (string sql in sqls)
+ {
+ if (string.IsNullOrEmpty(sql) || string.IsNullOrWhiteSpace(sql)) continue;
+ cmd.CommandText = sql;
+ cmd.ExecuteNonQuery();
+ }
+ tr.Commit();
+ }
+ catch (Exception ex)
+ {
+ tr?.Rollback();
+ throw ex;
+ }
+ finally
+ {
+ DisConnect();
+ }
+ }
+
+ public DataTable GetDataTable(string Sql)
+ {
+ DataTable dataTable = new DataTable();
+ SQLiteDataAdapter sQLiteDataAdapter = new SQLiteDataAdapter();
+ try
+ {
+ Connect();
+ cmd.CommandType = CommandType.Text;
+ cmd.CommandText = Sql;
+ sQLiteDataAdapter.SelectCommand = cmd;
+ sQLiteDataAdapter.Fill(dataTable);
+ }
+ catch (Exception ex)
+ {
+ string message = "ExecuteSql Error:" + ex.Message;
+ throw new Exception(message);
+ }
+ finally
+ {
+ DisConnect();
+ }
+
+ return dataTable;
+ }
+
+ public string[,] GetDataTableToArray(string Sql)
+ {
+ try
+ {
+ DataTable dataTable = GetDataTable(Sql);
+ string[,] array = new string[dataTable.Rows.Count, dataTable.Columns.Count];
+ int num = 0;
+ int num2 = 0;
+ foreach (DataRow row in dataTable.Rows)
+ {
+ num2 = 0;
+ object[] itemArray = row.ItemArray;
+ foreach (object obj in itemArray)
+ {
+ array[num, num2] = obj.ToString();
+ num2++;
+ }
+
+ num++;
+ }
+
+ return array;
+ }
+ catch (Exception ex)
+ {
+ throw new Exception(ex.Message);
+ }
+ }
+
+ public void Close()
+ {
+ try
+ {
+ if (conn.State == ConnectionState.Open)
+ {
+ conn.Close();
+ }
+
+ if (cmd != null)
+ {
+ cmd.Dispose();
+ }
+
+ if (conn != null)
+ {
+ conn.Dispose();
+ }
+ }
+ catch (Exception ex)
+ {
+ throw new Exception(ex.Message);
+ }
+ }
+
+ public bool HasData(string sql)
+ {
+ DataTable dataTable = GetDataTable(sql);
+ return dataTable.Rows.Count > 0;
+ }
+
+ public string[] GetColumnNameFromTable(string TableName)
+ {
+ try
+ {
+ string sql = $"PRAGMA table_info('{TableName}')";
+ DataTable dataTable = GetDataTable(sql);
+ string[] array = new string[dataTable.Rows.Count];
+ int num = 0;
+ foreach (DataRow row in dataTable.Rows)
+ {
+ array[num] = row.ItemArray[1].ToString();
+ num++;
+ }
+
+ return array;
+ }
+ catch (Exception ex)
+ {
+ throw new Exception("鑾峰彇琛ㄥ瓧娈靛悕绉板け璐�:" + ex.Message);
+ }
+ }
+
+ public string[] GetAllTableInFile()
+ {
+ try
+ {
+ string sql = "select name from sqlite_master where type = 'table' order by name";
+ DataTable dataTable = GetDataTable(sql);
+ string[] array = new string[dataTable.Rows.Count];
+ int num = 0;
+ foreach (DataRow row in dataTable.Rows)
+ {
+ array[num] = row.ItemArray[0].ToString();
+ num++;
+ }
+
+ return array;
+ }
+ catch (Exception ex)
+ {
+ throw new Exception("鑾峰彇琛ㄥ悕澶辫触:" + ex.Message);
+ }
+ }
+
+ private void Connect()
+ {
+ if (conn.State == ConnectionState.Closed)
+ {
+ conn.ConnectionString = ConnectString;
+ cmd.Connection = conn;
+ conn.Open();
+ }
+ }
+
+ private void DisConnect()
+ {
+ if (conn.State == ConnectionState.Open)
+ {
+ conn.Close();
+ }
+ }
+
+ public void Dispose()
+ {
+ this.Close();
+ }
+ }
+}
diff --git a/WPFProject/Api/Api.txt b/WPFProject/Api/Api.txt
deleted file mode 100644
index 5f28270..0000000
--- a/WPFProject/Api/Api.txt
+++ /dev/null
@@ -1 +0,0 @@
-锘�
\ No newline at end of file
diff --git a/WPFProject/Api/SQLite.Interop.dll b/WPFProject/Api/SQLite.Interop.dll
new file mode 100644
index 0000000..f666eab
--- /dev/null
+++ b/WPFProject/Api/SQLite.Interop.dll
Binary files differ
diff --git a/WPFProject/App.xaml b/WPFProject/App.xaml
index e68ae7c..289fbe1 100644
--- a/WPFProject/App.xaml
+++ b/WPFProject/App.xaml
@@ -18,6 +18,7 @@
<ResourceDictionary Source="/HMI.UI;component/Style/Colors.xaml"/>
<ResourceDictionary Source="/HMI.UI;component/Style/PanuonResource.xaml"/>
<ResourceDictionary Source="/HMI.UI;component/Style/MsgBoxStyle.xaml"/>
+ <ResourceDictionary Source="/HMI.Base;component/MaskControl.xaml"/>
</ResourceDictionary.MergedDictionaries>
<sys:Double x:Key="nanD">NaN</sys:Double>
<Style TargetType="{x:Type pu:FormGroup}" BasedOn="{StaticResource InputFormGroupStyle}"></Style>
@@ -25,6 +26,7 @@
<uic:DataGridRowNumberConverter x:Key="rowNumber"/>
<uic:VisibilityBoolConverter x:Key="vbConverter"/>
<uic:DataGridRowFlagConverter x:Key="rowFlag"/>
+ <uic:ReverseBoolConverter x:Key="reverseBool"/>
<hc:LangConverter x:Key="lc"/>
<hc:WidthSizeConverter x:Key="fc"/>
<hc:HeightSizeConverter x:Key="hfc"/>
diff --git a/WPFProject/BuildCmd.bat b/WPFProject/BuildCmd.bat
index 1936efa..cfde15f 100644
--- a/WPFProject/BuildCmd.bat
+++ b/WPFProject/BuildCmd.bat
@@ -26,6 +26,10 @@
move /y "$(TargeDir)Plugin.DataBoard.dll" $(TargeDir)Plugin\Plugin.DataBoard.dll"
move /y "$(TargeDir)Plugin.JarUI.dll" $(TargeDir)Plugin\Plugin.JarUI.dll"
move /y "$(TargeDir)Plugin.SeqEditor.dll" $(TargeDir)Plugin\Plugin.SeqEditor.dll"
+move /y "$(TargeDir)Plugin.ChangeModel.dll" $(TargeDir)Plugin\Plugin.ChangeModel.dll"
+move /y "$(TargeDir)Plugin.MaterialOpt.dll" $(TargeDir)Plugin\Plugin.MaterialOpt.dll"
+move /y "$(TargeDir)Plugin.DODriverControl.dll" $(TargeDir)Plugin\Plugin.DODriverControl.dll"
+move /y "$(TargeDir)Plugin.ModelManage.dll" $(TargeDir)Plugin\Plugin.ModelManage.dll"
setlocal enabledelayedexpansion
@@ -35,6 +39,12 @@
rmdir /S /Q "%destination_folder%"
mkdir "%destination_folder%"
+for %%F in ("%source_folder%\*") do (
+ if /I "%%~nxF"=="System.Data.SQLite.dll" (
+ xcopy "%source_folder%\%%F" "%source_folder%\Api\%%F" /Y
+ )
+)
+
for /d %%D in ("%source_folder%\*") do (
if /I not "%%~nxD"=="Api" if /I not "%%~nxD"=="Config" if /I not "%%~nxD"=="Icon" if /I not "%%~nxD"=="Lang" if /I not "%%~nxD"=="Libs" if /I not "%%~nxD"=="Log" if /I not "%%~nxD"=="Plugin" if /I not "%%~nxD"=="TestPlatform.exe.WebView2" (
move /Y "%%D" "%destination_folder%"
@@ -42,7 +52,7 @@
)
for %%F in ("%source_folder%\*") do (
- if /I not "%%~nxF"=="$(TargetFileName)" if /I not "%%~nxF"=="$(TargetFileName).config" if /I not "%%~nxF"=="$(TargetName).pdb" if /I not "%%~nxF"=="clear.bat" (
+ if /I not "%%~nxF"=="$(TargetFileName)" if /I not "%%~nxF"=="$(TargetFileName).config" if /I not "%%~nxF"=="$(TargetName).pdb" if /I not "%%~nxF"=="clear.bat" if /I not "%%~nxF"=="瀹夎MSMQ.bat" (
move /Y "%%F" "%destination_folder%"
)
)
diff --git a/WPFProject/Controls/MainTabControl.xaml b/WPFProject/Controls/MainTabControl.xaml
index 2950b42..f28f6ee 100644
--- a/WPFProject/Controls/MainTabControl.xaml
+++ b/WPFProject/Controls/MainTabControl.xaml
@@ -187,12 +187,45 @@
</DockPanel>
</Border>
-
-
-
-
<Border x:Name="page" Grid.Row="2" BorderThickness="0" Margin="0" Background="White" Padding="0">
</Border>
+
+ <Border Height="80" Grid.Row="2" Background="Red" Visibility="Collapsed" VerticalAlignment="Top" x:Name="alarmBorder">
+ <Border.Style>
+ <Style TargetType="Border">
+ <Style.Triggers>
+ <Trigger Property="Visibility" Value="Visible">
+ <Trigger.EnterActions>
+ <BeginStoryboard>
+ <Storyboard>
+ <ColorAnimation Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)"
+ From="#ff2100"
+ To="#fe7975"
+ Duration="0:0:0.7"
+ AutoReverse="True"
+ RepeatBehavior="Forever"/>
+ </Storyboard>
+ </BeginStoryboard>
+ </Trigger.EnterActions>
+ </Trigger>
+ </Style.Triggers>
+ </Style>
+ </Border.Style>
+
+ <DockPanel>
+ <Button DockPanel.Dock="Right"
+ FontSize="25"
+ FontWeight="Bold"
+ Margin="0,10,10,0"
+ VerticalAlignment="Top"
+ Click="Button_Click_1"
+ FontFamily="{StaticResource iconfont}" Background="Transparent" Content=""/>
+
+ <Label Margin="10,0,0,0" FontSize="25" FontWeight="Bold"
+ VerticalAlignment="Center" Content="{Binding AlarmInfo}"/>
+
+ </DockPanel>
+ </Border>
</Grid>
</UserControl>
diff --git a/WPFProject/Controls/MainTabControl.xaml.cs b/WPFProject/Controls/MainTabControl.xaml.cs
index 874fe44..39d6077 100644
--- a/WPFProject/Controls/MainTabControl.xaml.cs
+++ b/WPFProject/Controls/MainTabControl.xaml.cs
@@ -1,6 +1,7 @@
锘縰sing HMI.Base;
using HMI.Core.Api;
using Panuon.WPF.UI;
+using Plugin.TestResult_WPF.Model;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
@@ -196,5 +197,27 @@
}
Loaded -= UserControl_Loaded;
}
+
+ private string alarmInfo;
+ public string AlarmInfo
+ {
+ get => alarmInfo;
+ set
+ {
+ RaiseAndSetIfChanged(ref alarmInfo, value);
+ }
+ }
+
+ private void Button_Click_1(object sender, RoutedEventArgs e)
+ {
+ alarmBorder.Visibility = Visibility.Collapsed;
+ AlarmInfo = string.Empty;
+ }
+
+ public void ShowAlarm(string message)
+ {
+ AlarmInfo = message;
+ alarmBorder.Visibility = Visibility.Visible;
+ }
}
}
diff --git a/WPFProject/Lang/en-US/AlarmInfoManage.json b/WPFProject/Lang/en-US/AlarmInfoManage.json
index 2e092d2..1b9c928 100644
--- a/WPFProject/Lang/en-US/AlarmInfoManage.json
+++ b/WPFProject/Lang/en-US/AlarmInfoManage.json
@@ -4,6 +4,7 @@
"Alm.Code": "Code",
"Alm.Info": "Info",
"Alm.Time": "Time",
+ "Alm.Description": "Description",
"Alm.OnlySupportXlsm": "Only .xlsm can be supported",
"Alm.RowImportFailed": "Import failed in row: {0}",
diff --git a/WPFProject/Lang/en-US/ChangeModel.json b/WPFProject/Lang/en-US/ChangeModel.json
new file mode 100644
index 0000000..92b6f90
--- /dev/null
+++ b/WPFProject/Lang/en-US/ChangeModel.json
@@ -0,0 +1,25 @@
+{
+ "cm.title": "Change Model",
+ "cm.lineName": "Line Name",
+ "cm.workorder": "Work Order",
+ "cm.productModel": "Model",
+ "cm.customProperty": "Custom Property",
+ "cm.workstation": "Workstation",
+ "cm.changeTime": "Time",
+ "cm.changeResult": "Result",
+ "cm.info": "Info",
+ "cm.cm": "Change",
+ "cm.rfhInfo": "Refresh",
+ "cm.rfhLog": "Refresh Log",
+ "cm.clrLog": "Clear Log",
+ "cm.rfhInfoErr": "Clear Current Model Failed: {0}",
+ "cm.makeSureChangeModel": "Are you sure you want to change model锛�",
+ "cm.makeSureDelLog": "Are you sure you want to clear log? Only 10 data will be left.",
+ "cm.mesConnectFail": "MES connected failed: {0}",
+ "cm.rfhLineNameFail": "Refresh line name failed: {0}",
+ "cm.rfhWorkOrderFail": "Refresh work order failed: {0}",
+ "cm.rfhModelFail": "Refresh model failed: {0}",
+ "cm.rfhLogFail": "Refresh log failed: {0}",
+ "cm.delLogFail": "Clear log failed: {0}",
+ "cm.changeFail": "Change model failed: {0}"
+}
\ No newline at end of file
diff --git a/WPFProject/Lang/en-US/app.json b/WPFProject/Lang/en-US/app.json
index 1f219a1..bf31815 100644
--- a/WPFProject/Lang/en-US/app.json
+++ b/WPFProject/Lang/en-US/app.json
@@ -87,6 +87,7 @@
"Test.LimitUp": "Limit up",
"Test.Result": "Result",
"Test.Range": "Range",
+ "Test.ConsumeTime": "Consume Time",
"Test.Condition": "Condition",
"Test.UpdateTime": "Update Time",
diff --git a/WPFProject/Lang/zh-CN/AlarmInfoManage.json b/WPFProject/Lang/zh-CN/AlarmInfoManage.json
index 8e48f05..d2ca3d6 100644
--- a/WPFProject/Lang/zh-CN/AlarmInfoManage.json
+++ b/WPFProject/Lang/zh-CN/AlarmInfoManage.json
@@ -4,6 +4,7 @@
"Alm.Code": "缂栧彿",
"Alm.Info": "淇℃伅",
"Alm.Time": "鏃堕棿",
+ "Alm.Description": "鎶ヨ鎻忚堪",
"Alm.OnlySupportXlsm": "浠呮敮鎸亁lsm鏍煎紡鏂囦欢",
"Alm.RowImportFailed": "绗瑊0}琛屽鍏ュ紓甯�",
diff --git a/WPFProject/Lang/zh-CN/ChangeModel.json b/WPFProject/Lang/zh-CN/ChangeModel.json
new file mode 100644
index 0000000..59ebbba
--- /dev/null
+++ b/WPFProject/Lang/zh-CN/ChangeModel.json
@@ -0,0 +1,25 @@
+{
+ "cm.title": "浜у搧鎹㈠瀷",
+ "cm.lineName": "浜х嚎鍚嶇О",
+ "cm.workorder": "宸ュ崟鍙�",
+ "cm.productModel": "浜у搧鍨嬪彿",
+ "cm.customProperty": "闄勫姞灞炴��",
+ "cm.workstation": "宸ョ珯",
+ "cm.changeTime": "鎹㈠瀷鏃堕棿",
+ "cm.changeResult": "鎹㈠瀷缁撴灉",
+ "cm.info": "淇℃伅",
+ "cm.cm": "鎹㈠瀷",
+ "cm.rfhInfo": "鍒锋柊",
+ "cm.rfhLog": "鍒锋柊Log",
+ "cm.clrLog": "娓呯悊Log",
+ "cm.rfhInfoErr": "鍒锋柊褰撳墠鍨嬪彿澶辫触: {0}",
+ "cm.makeSureChangeModel": "纭畾瑕佽繘琛屾崲鍨嬪悧锛�",
+ "cm.makeSureDelLog": "纭畾瑕佹竻鐞嗘棩蹇楀悧锛熷皢鍒犻櫎鏈�杩�10鏉℃棩蹇椾箣澶栫殑鎵�鏈夋棩蹇楄褰曘��",
+ "cm.mesConnectFail": "MES杩炴帴澶辫触: {0}",
+ "cm.rfhLineNameFail": "浜х嚎淇℃伅鍒锋柊澶辫触: {0}",
+ "cm.rfhWorkOrderFail": "宸ュ崟淇℃伅鍒锋柊澶辫触: {0}",
+ "cm.rfhModelFail": "浜у搧淇℃伅鍒锋柊澶辫触: {0}",
+ "cm.rfhLogFail": "Log鍒锋柊澶辫触: {0}",
+ "cm.delLogFail": "娓呯悊Log澶辫触: {0}",
+ "cm.changeFail": "鎹㈠瀷澶辫触: {0}"
+}
\ No newline at end of file
diff --git a/WPFProject/Lang/zh-CN/DOControl.json b/WPFProject/Lang/zh-CN/DOControl.json
index 2d37d79..7566651 100644
--- a/WPFProject/Lang/zh-CN/DOControl.json
+++ b/WPFProject/Lang/zh-CN/DOControl.json
@@ -7,5 +7,7 @@
"doc.readOnly": "鍙",
"doc.pressDownValue": "鎸変笅鍊�",
"doc.pressUpValue": "寮硅捣鍊�",
- "doc.controlType": "鎺т欢绫诲瀷"
+ "doc.controlType": "鎺т欢绫诲瀷",
+ "doc.pressDownText": "鎸変笅鏂囨湰",
+ "doc.pressUpText": "寮硅捣鏂囨湰"
}
\ No newline at end of file
diff --git a/WPFProject/Lang/zh-CN/app.json b/WPFProject/Lang/zh-CN/app.json
index 6b4b85f..4273245 100644
--- a/WPFProject/Lang/zh-CN/app.json
+++ b/WPFProject/Lang/zh-CN/app.json
@@ -87,6 +87,7 @@
"Test.LimitUp": "涓婇檺",
"Test.Result": "缁撴灉",
"Test.Range": "娴嬭瘯鑼冨洿",
+ "Test.ConsumeTime": "鑰楁椂",
"Test.Condition": "娴嬭瘯鏉′欢",
"Test.UpdateTime": "鏇存柊鏃堕棿",
diff --git a/WPFProject/Login.xaml b/WPFProject/Login.xaml
index f656f1f..3bc96d1 100644
--- a/WPFProject/Login.xaml
+++ b/WPFProject/Login.xaml
@@ -26,17 +26,6 @@
<ResourceDictionary Source="/HMI.UI;component/Style/Colors.xaml"/>
</ResourceDictionary.MergedDictionaries>
- <Style x:Key="SignInPasswordBoxStyle" TargetType="PasswordBox" BasedOn="{StaticResource {x:Type PasswordBox}}">
- <Setter Property="pu:PasswordBoxHelper.FocusedBorderBrush" Value="#6CBCEA" />
- <Setter Property="pu:PasswordBoxHelper.FocusedShadowColor" Value="#6CBCEA" />
- <Setter Property="pu:PasswordBoxHelper.CornerRadius" Value="2" />
- <Setter Property="pu:PasswordBoxHelper.WatermarkForeground" Value="#4A4A4A" />
- <Setter Property="pu:PasswordBoxHelper.FocusedWatermarkForeground" Value="#AAAAAA" />
- <Setter Property="pu:PasswordBoxHelper.ClearButtonVisibility" Value="VisibleOnHoverAndNonnull" />
- <Setter Property="Height" Value="35" />
- <Setter Property="Padding" Value="10,0" />
- </Style>
-
<Style x:Key="SignInButtonStyle" TargetType="Button" BasedOn="{StaticResource PrimaryButton}">
<Setter Property="pu:ButtonHelper.PendingSpinStyle">
<Setter.Value>
diff --git a/WPFProject/Login.xaml.cs b/WPFProject/Login.xaml.cs
index 3be043e..03bc65c 100644
--- a/WPFProject/Login.xaml.cs
+++ b/WPFProject/Login.xaml.cs
@@ -1,4 +1,5 @@
-锘縰sing HMI.Core.Entity;
+锘縰sing HMI.Base;
+using HMI.Core.Entity;
using HMI.Core.Setting;
using HMI.Core.Util;
using HMI.UI.DpUtil;
@@ -6,10 +7,12 @@
using log4net;
using Panuon.WPF.UI;
using System;
+using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Threading.Tasks;
using System.Windows;
+using System.Windows.Threading;
using WPFProject.Utils;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.StartPanel;
@@ -52,43 +55,98 @@
}
}
- private void DoLogin(string username, string password, bool rememberMe)
+ private List<PermissionData> SelectPermission(string username, SqliteHelper sqliteHelper, out List<PermissionData> allPermission)
{
- SqliteHelper helper = null;
-
+ List<PermissionData> data = new List<PermissionData>();
+ allPermission = new List<PermissionData>();
+ Dictionary<string, PermissionData> cache = new Dictionary<string, PermissionData>();
try
{
- helper = new SqliteHelper(PathHelper.DatabasePath);
- string sql = $"SELECT id,code,username,password,name From user WHERE username='{username}' and password='{password}'";
- DataTable dt = helper.GetDataTable(sql);
- if (dt == null || dt.Rows.Count <= 0)
- {
- throw new LoginException(LangUtil.Get("App.ErrorUsernameOrPassword"));
- }
- UserInfo user = new UserInfo(
- dt.Rows[0]["id"].ToString(),
- dt.Rows[0]["code"].ToString(),
- dt.Rows[0]["username"].ToString(),
- dt.Rows[0]["name"].ToString());
- UserInfo.Login(user);
- if (rememberMe)
- {
- // 璁颁綇鐧诲綍鎿嶄綔
- string userToken =
- JsonUtil.Serialize(
- new UserInfo(null, user.Code, user.Username, user.Name, dt.Rows[0]["password"].ToString()));
- // 瀛樺偍鏁版嵁
- BinUtil.SaveStrToBin(encryptor.Encrypt(userToken),
- Path.Combine(PathHelper.DatabaseFolder, "user.bin"));
- }
+ string sql = $@"SELECT DISTINCT m.* FROM menu AS m INNER JOIN role_menu_rel AS rrel ON m.code = rrel.menuCode
+INNER JOIN role AS r ON rrel.roleCode = r.code
+INNER JOIN user_role_rel AS urel ON r.code = urel.roleCode
+AND urel.username = '{username}' ORDER BY m.level,m.sort, m.id;";
- Dispatcher.Invoke(() =>
+ DataTable dt = sqliteHelper.GetDataTable(sql);
+ if (dt != null)
{
- LoadingWindow loading = new LoadingWindow();
- loading.Show();
- this.Closed -= window_Closed;
- this.Close();
- });
+ foreach (DataRow dr in dt.Rows)
+ {
+ string path = Path.Combine(PathHelper.IconFolder, dr["iconPath"].ToString());
+ var menu = new PermissionData
+ {
+ Code = dr["code"].ToString(),
+ Name = dr["name"].ToString(),
+ Type = dr["type"].ToString(),
+ ParentCode = dr["parentCode"].ToString(),
+ DllPath = dr["dllPath"].ToString(),
+ ClassName = dr["className"].ToString(),
+ IconFont = dr["icon"].ToString()
+ };
+ cache[menu.Code] = menu;
+ allPermission.Add(menu);
+ if (!cache.ContainsKey(menu.ParentCode))
+ {
+ data.Add(menu);
+ }
+ else
+ {
+ cache[menu.ParentCode].Children.Add(menu);
+ }
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ //LoadMessageAppend?.Invoke(this, ex.Message);
+ }
+ return data;
+ }
+
+ private void DoLogin(string username, string password, bool rememberMe)
+ {
+ try
+ {
+ using (SqliteHelper helper = new SqliteHelper(PathHelper.DatabasePath))
+ {
+ string sql = $"SELECT id,code,username,password,name From user WHERE username='{username}' and password='{password}'";
+ DataTable dt = helper.GetDataTable(sql);
+ if (dt == null || dt.Rows.Count <= 0)
+ {
+ throw new LoginException(LangUtil.Get("App.ErrorUsernameOrPassword"));
+ }
+ List<PermissionData> permissions = SelectPermission(username, helper, out List<PermissionData> allPermission);
+ UserInfo user = new UserInfo(
+ dt.Rows[0]["id"].ToString(),
+ dt.Rows[0]["code"].ToString(),
+ dt.Rows[0]["username"].ToString(),
+ dt.Rows[0]["name"].ToString(),
+ permissions,
+ allPermission,
+ dt.Rows[0]["password"].ToString()
+ );
+
+ UserInfo.Login(user);
+ if (rememberMe)
+ {
+ // 璁颁綇鐧诲綍鎿嶄綔
+ string userToken =
+ JsonUtil.Serialize(
+ new UserInfo(null, user.Code, user.Username, user.Name, null, null,
+ dt.Rows[0]["password"].ToString()));
+ // 瀛樺偍鏁版嵁
+ BinUtil.SaveStrToBin(encryptor.Encrypt(userToken),
+ Path.Combine(PathHelper.DatabaseFolder, "user.bin"));
+ }
+
+ Dispatcher.Invoke(() =>
+ {
+ LoadingWindow loading = new LoadingWindow();
+ loading.Show();
+ this.Closed -= window_Closed;
+ this.Close();
+ });
+ }
}
catch (Exception ex)
{
@@ -100,6 +158,7 @@
}
finally
{
+
Dispatcher.Invoke(() =>
{
ButtonHelper.SetIsPending(BtnLogin, false);
diff --git a/WPFProject/PanuonWindow.xaml b/WPFProject/PanuonWindow.xaml
index 867d337..09086ef 100644
--- a/WPFProject/PanuonWindow.xaml
+++ b/WPFProject/PanuonWindow.xaml
@@ -18,6 +18,7 @@
xmlns:hc="clr-namespace:HMI.Core;assembly=HMI.Core"
Closed="window_Closed"
Topmost="False"
+ pu:WindowXCaption.HeaderAlignment="Stretch"
Title="TestPlatform"
pu:WindowXCaption.Background="Transparent"
pu:WindowXCaption.Height="80"
@@ -46,91 +47,200 @@
<pu:WindowXCaption.HeaderTemplate>
<DataTemplate>
- <StackPanel DataContext="{Binding ElementName=window}" Orientation="Horizontal"
- VerticalAlignment="Center"
- dp:StackPanelHelper.ChildSpace="30" Margin="5,0,0,0" Height="100">
- <Image Source="{Binding WindowLogo}" Height="60" VerticalAlignment="Center" Stretch="Fill"
- RenderOptions.BitmapScalingMode="HighQuality" />
- <TextBlock FontSize="30" VerticalAlignment="Center" Text="{Binding WindowTitle}">
- <TextBlock.Effect>
- <DropShadowEffect ShadowDepth="8"
- Direction="330"
- Color="Black"
- Opacity="0.5"
- BlurRadius="4"/>
- </TextBlock.Effect>
- </TextBlock>
- </StackPanel>
+ <DockPanel DataContext="{Binding ElementName=window}" WindowChrome.IsHitTestVisibleInChrome="True"
+ VerticalAlignment="Center" Height="100">
+ <StackPanel Orientation="Horizontal">
+ <Image DockPanel.Dock="Left" Source="{Binding WindowLogo}" Margin="5,0,20,0" Height="60" VerticalAlignment="Center" Stretch="Fill"
+ RenderOptions.BitmapScalingMode="HighQuality" />
+ <TextBlock FontSize="30" VerticalAlignment="Center" Text="{Binding WindowTitle}">
+ <TextBlock.Effect>
+ <DropShadowEffect ShadowDepth="8"
+ Direction="330"
+ Color="Black"
+ Opacity="0.5"
+BlurRadius="4"/>
+ </TextBlock.Effect>
+ </TextBlock>
+ </StackPanel>
+
+ <StackPanel DockPanel.Dock="Right" VerticalAlignment="Top" Margin="10,10,0,0" Orientation="Horizontal">
+ <Menu Margin="0" Padding="0" VerticalAlignment="Top"
+ VerticalContentAlignment="Center" Style="{StaticResource UserMenu}"
+
+ Background="Transparent">
+ <MenuItem x:Name="userMenu" Header="{Binding WelcomeTitle}" FontSize="16">
+ <MenuItem Icon="" Cursor="Hand" FontSize="14" Header="閫�鍑虹櫥褰�"
+ x:Name="MiLogout" Click="MenuItem_Click"/>
+ <MenuItem Cursor="Hand" FontSize="14" Icon=""
+ Header="閲嶆柊鍚姩"
+ x:Name="MiRestart"
+ Click="MenuItem_Click"/>
+ </MenuItem>
+ </Menu>
+
+ <Button x:Name="BtnSwitchTheme"
+FontSize="18"
+FontFamily="/HMI.UI;component/Resources/Font/#iconfont"
+Content=""
+RenderTransformOrigin="0.5,0.5"
+Click="Button_Click">
+ <Button.Style>
+ <Style TargetType="Button" BasedOn="{StaticResource {x:Static pu:WindowXCaption.MinimizeButtonStyleKey}}">
+ <Setter Property="Focusable" Value="False"/>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding ShowMenu}" Value="True">
+ <Setter Property="Button.RenderTransform">
+ <Setter.Value>
+ <RotateTransform x:Name="MyAnimatedTransform" Angle="180" />
+ </Setter.Value>
+ </Setter>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Button.Style>
+ </Button>
+
+ <Button FontSize="18" Click="Button_Click" x:Name="minBtn">
+ <Button.Style>
+ <Style TargetType="Button" BasedOn="{StaticResource {x:Static pu:WindowXCaption.MinimizeButtonStyleKey}}">
+ <Setter Property="Focusable" Value="False"/>
+ <Setter Property="IsHitTestVisible" Value="True"/>
+ </Style>
+ </Button.Style>
+ </Button>
+
+ <Button FontSize="18" Click="Button_Click" x:Name="maxBtn">
+ <Button.Style>
+ <Style TargetType="Button" BasedOn="{StaticResource {x:Static pu:WindowXCaption.MaximizeButtonStyleKey}}">
+ <Setter Property="Focusable" Value="False"/>
+ </Style>
+ </Button.Style>
+ </Button>
+
+ <Button FontSize="18" Click="Button_Click" x:Name="closeBtn">
+ <Button.Style>
+ <Style TargetType="Button" BasedOn="{StaticResource {x:Static pu:WindowXCaption.CloseButtonStyleKey}}">
+ <Setter Property="Focusable" Value="False"/>
+ </Style>
+ </Button.Style>
+ </Button>
+ </StackPanel>
+
+ <ListBox x:Name="list"
+
+ Margin="20,15,10,15"
+ Background="#6FFFFFFF"
+ BorderThickness="0"
+ pu:ListBoxHelper.CornerRadius="5"
+ pu:ListBoxHelper.ItemsCornerRadius="5"
+ pu:ListBoxHelper.ItemsBackground="Red"
+ pu:ListBoxHelper.ItemsHoverBackground="#b20000"
+ pu:ListBoxHelper.ItemsSelectedBackground="#b20000"
+ pu:ListBoxHelper.ItemsIcon=""
+ ItemsSource="{Binding Alarms}"
+ Loaded="list_Loaded"
+
+ FontSize="15"
+Foreground="#FFF"
+
+ pu:IconHelper.FontFamily="/Panuon.WPF.UI;component/Resources/Fonts/#PanuonIcon"
+ pu:IconHelper.Foreground="Green"
+ pu:IconHelper.FontSize="20"
+ pu:IconHelper.Margin="5,0,5,0"
+ FontWeight="UltraBlack"
+
+
+ pu:ListBoxHelper.ItemsSeparatorVisibility="Visible"
+ pu:ListBoxHelper.ItemsSeparatorBrush="Transparent"
+ pu:ListBoxHelper.ItemsRemoveButtonVisibility="Visible">
+
+ <ListBox.Style>
+ <Style TargetType="ListBox" BasedOn="{StaticResource {x:Static pu:StyleKeys.ListBoxStyle}}">
+ <Setter Property="Visibility" Value="Visible"/>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding Alarms.Count}" Value="0">
+ <Setter Property="Visibility" Value="Hidden"/>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </ListBox.Style>
+
+ <ListBox.Resources>
+ <sys:Double x:Key="{x:Static SystemParameters.VerticalScrollBarWidthKey}">6</sys:Double>
+
+ <ControlTemplate x:Key="VerticalScrollBar" TargetType="RangeBase">
+ <Border Width="{TemplateBinding Width}" CornerRadius="2"
+ Background="{DynamicResource CommonBoarder}">
+ <Track Name="PART_Track" IsDirectionReversed="true">
+ <Track.DecreaseRepeatButton>
+ <RepeatButton Command="ScrollBar.PageUpCommand" Focusable="False">
+ <RepeatButton.Template>
+ <ControlTemplate>
+ <Border Background="Transparent"></Border>
+ </ControlTemplate>
+ </RepeatButton.Template>
+ </RepeatButton>
+ </Track.DecreaseRepeatButton>
+ <Track.Thumb>
+ <Thumb Width="{TemplateBinding Width}" Focusable="False">
+ <Thumb.Template>
+ <ControlTemplate>
+ <Border Background="Gray"
+ CornerRadius="2" />
+ </ControlTemplate>
+ </Thumb.Template>
+ </Thumb>
+ </Track.Thumb>
+ <Track.IncreaseRepeatButton>
+ <RepeatButton Command="ScrollBar.PageDownCommand" Focusable="False">
+ <RepeatButton.Template>
+ <ControlTemplate>
+ <Border Background="Transparent"></Border>
+ </ControlTemplate>
+ </RepeatButton.Template>
+ </RepeatButton>
+ </Track.IncreaseRepeatButton>
+ </Track>
+ </Border>
+ </ControlTemplate>
+
+ <Style x:Key="ScrollStyle_Mobile" TargetType="ScrollBar">
+ <Style.Resources>
+ <sys:Double x:Key="{x:Static SystemParameters.VerticalScrollBarWidthKey}">6</sys:Double>
+ <sys:Double x:Key="{x:Static SystemParameters.HorizontalScrollBarHeightKey}">6</sys:Double>
+ </Style.Resources>
+ <Style.Triggers>
+ <Trigger Property="Orientation" Value="Vertical">
+ <Setter Property="Width" Value="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}" />
+ <Setter Property="Height" Value="Auto" />
+ <Setter Property="Margin" Value="0" />
+ <Setter Property="Template" Value="{DynamicResource VerticalScrollBar}" />
+ </Trigger>
+ </Style.Triggers>
+ </Style>
+
+
+ <Style TargetType="ScrollBar" BasedOn="{StaticResource ScrollStyle_Mobile}"/>
+ </ListBox.Resources>
+
+ <ListBox.ItemContainerStyle>
+ <Style TargetType="ListBoxItem" BasedOn="{StaticResource {x:Static pu:StyleKeys.ListBoxItemStyle}}">
+ <Setter Property="Padding" Value="0"/>
+ <Setter Property="VerticalContentAlignment" Value="Center"/>
+ <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
+ <Setter Property="Height" Value="70"/>
+ <Setter Property="Margin" Value="0,0,0,1"/>
+ <Setter Property="BorderThickness" Value="0"/>
+ </Style>
+ </ListBox.ItemContainerStyle>
+ </ListBox>
+ </DockPanel>
</DataTemplate>
</pu:WindowXCaption.HeaderTemplate>
- <pu:WindowXCaption.ExtendControl>
- <StackPanel Orientation="Horizontal">
- <Menu Margin="0" Padding="0" VerticalAlignment="Top"
- VerticalContentAlignment="Center" Style="{StaticResource UserMenu}"
-
- Background="Transparent">
- <MenuItem x:Name="userMenu" FontSize="16">
- <MenuItem
- Icon=""
- Cursor="Hand" FontSize="14" Header="閫�鍑虹櫥褰�"
- x:Name="MiLogout"
- Click="MenuItem_Click"/>
- <MenuItem Cursor="Hand" FontSize="14"
- Icon=""
- Header="閲嶆柊鍚姩"
- x:Name="MiRestart"
- Click="MenuItem_Click"/>
- </MenuItem>
- </Menu>
-
- <Button x:Name="BtnSwitchTheme"
- FontSize="18"
- FontFamily="/HMI.UI;component/Resources/Font/#iconfont"
- Content=""
- RenderTransformOrigin="0.5,0.5"
- Click="Button_Click">
- <Button.Style>
- <Style TargetType="Button" BasedOn="{StaticResource {x:Static pu:WindowXCaption.MinimizeButtonStyleKey}}">
- <Setter Property="Focusable" Value="False"/>
- <Style.Triggers>
- <DataTrigger Binding="{Binding ShowMenu}" Value="True">
- <Setter Property="Button.RenderTransform">
- <Setter.Value>
- <RotateTransform x:Name="MyAnimatedTransform" Angle="180" />
- </Setter.Value>
- </Setter>
- </DataTrigger>
- </Style.Triggers>
- </Style>
- </Button.Style>
- </Button>
-
- <Button FontSize="18" Click="Button_Click" x:Name="minBtn">
- <Button.Style>
- <Style TargetType="Button" BasedOn="{StaticResource {x:Static pu:WindowXCaption.MinimizeButtonStyleKey}}">
- <Setter Property="Focusable" Value="False"/>
- </Style>
- </Button.Style>
- </Button>
-
- <Button FontSize="18" Click="Button_Click" x:Name="maxBtn">
- <Button.Style>
- <Style TargetType="Button" BasedOn="{StaticResource {x:Static pu:WindowXCaption.MaximizeButtonStyleKey}}">
- <Setter Property="Focusable" Value="False"/>
- </Style>
- </Button.Style>
- </Button>
-
- <Button FontSize="18" Click="Button_Click" x:Name="closeBtn">
- <Button.Style>
- <Style TargetType="Button" BasedOn="{StaticResource {x:Static pu:WindowXCaption.CloseButtonStyleKey}}">
- <Setter Property="Focusable" Value="False"/>
- </Style>
- </Button.Style>
- </Button>
- </StackPanel>
- </pu:WindowXCaption.ExtendControl>
+ <!--<pu:WindowXCaption.ExtendControl>
+
+ </pu:WindowXCaption.ExtendControl>-->
<Grid>
<Grid.RowDefinitions>
diff --git a/WPFProject/PanuonWindow.xaml.cs b/WPFProject/PanuonWindow.xaml.cs
index 71de9ee..f2026f0 100644
--- a/WPFProject/PanuonWindow.xaml.cs
+++ b/WPFProject/PanuonWindow.xaml.cs
@@ -6,18 +6,30 @@
using HMI.UI.Util;
using Panuon.WPF.UI;
using System;
+using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
+using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
namespace WPFProject
{
+ public class SimpleAlarm
+ {
+ public string Time { get; set; }
+ public string Message { get; set; }
+ public override string ToString()
+ {
+ return $"{Time} {Message}";
+ }
+ }
+
/// <summary>
/// PanuonWindow.xaml 鐨勪氦浜掗�昏緫
/// </summary>
- public partial class PanuonWindow : WindowX, IPluginContainer
+ public partial class PanuonWindow : WindowX, IPluginContainer,IAlarmShow
{
public PanuonWindow()
{
@@ -34,12 +46,45 @@
}
}
+ private string welcomeTitle;
+ public string WelcomeTitle
+ {
+ get => welcomeTitle;
+ set
+ {
+ Set(ref welcomeTitle, value);
+ }
+ }
+
+ private ObservableCollection<SimpleAlarm> alarms = new ObservableCollection<SimpleAlarm>();
+ public ObservableCollection<SimpleAlarm> Alarms
+ {
+ get => alarms;
+ set
+ {
+ Set(ref alarms, value);
+ }
+ }
+
+ public int AlarmCount
+ {
+ get => Alarms?.Count ?? 0;
+ }
+
+ public ListBox sb {
+ get;set;
+ }
+
private void PanuonWindow_Loaded(object sender, RoutedEventArgs e)
{
DataContext = this;
RefrshConfig();
InitializeComponent();
- userMenu.Header = this.lang("App.Welcome", UserInfo.User.Name);
+ AlarmShowHelper.Register(this);
+ var sb = WindowXCaption.GetHeaderTemplate(this);
+ //sb.FindName("list",this.Con);
+
+ WelcomeTitle = this.lang("App.Welcome", UserInfo.User.Name);
ShowMenu = false;
Application.Current.MainWindow = this;
SystemSetting.SystemSettingChanged += SystemSetting_SystemSettingChanged;
@@ -188,6 +233,32 @@
}
}
+ public bool ShowAlarm(string message)
+ {
+ bool res = false;
+ Dispatcher.Invoke(() =>
+ {
+ if (Alarms.FirstOrDefault(e => e.Message == message) == null)
+ {
+ var data = new SimpleAlarm
+ {
+ Time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
+ Message = message
+ };
+ Alarms.Add(data);
+ sb?.ScrollIntoView(data);
+ res = true;
+ }
+ });
+ return res;
+ }
+
+ private void list_Loaded(object sender, RoutedEventArgs e)
+ {
+ sb = sender as ListBox;
+ sb.Loaded -= list_Loaded;
+ }
+
//private void BaseWindow_Loaded(object sender, RoutedEventArgs e)
//{
// var s = (Style)this.Resources["WindowButton"];
diff --git a/WPFProject/Properties/app.manifest b/WPFProject/Properties/app.manifest
index f7c83c6..e1175ad 100644
--- a/WPFProject/Properties/app.manifest
+++ b/WPFProject/Properties/app.manifest
@@ -16,7 +16,7 @@
濡傛灉浣犵殑搴旂敤绋嬪簭闇�瑕佹铏氭嫙鍖栨潵瀹炵幇鍚戝悗鍏煎鎬э紝鍒欑Щ闄ゆ
鍏冪礌銆�
-->
- <requestedExecutionLevel level="asInvoker" uiAccess="false" />
+ <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
</requestedPrivileges>
<applicationRequestMinimum>
<defaultAssemblyRequest permissionSetReference="Custom" />
diff --git a/WPFProject/Utils/MainToastHandler.cs b/WPFProject/Utils/MainToastHandler.cs
index 3572136..9356303 100644
--- a/WPFProject/Utils/MainToastHandler.cs
+++ b/WPFProject/Utils/MainToastHandler.cs
@@ -2,6 +2,7 @@
using Panuon.WPF.UI;
using Panuon.WPF.UI.Configurations;
using HMI.UI.Util;
+using System;
namespace WPFProject.Utils
{
@@ -15,11 +16,11 @@
if (window is PanuonWindow pw)
{
double num = 20 + (pw.menuTab.MenuVisibility == Visibility.Visible ? pw.menuTab.Menu.ActualHeight + pw.menuTab.SubMenu.ActualHeight : 0);
- Toast.Show(pw, message, icon, position, num, durationMs, setting);
+ Show(pw, message, icon, position, num, durationMs, setting);
}
else if (window is WindowX wx)
{
- Toast.Show(wx, message, icon, position, 0, durationMs, setting);
+ Show(wx, message, icon, position, 0, durationMs, setting);
}
}
@@ -31,11 +32,11 @@
if (window is PanuonWindow pw)
{
double num = 20 + (pw.menuTab.MenuVisibility == Visibility.Visible ? pw.menuTab.Menu.ActualHeight + pw.menuTab.SubMenu.ActualHeight : 0);
- Toast.Show(pw, message, icon, position, num, durationMs, setting);
+ Show(pw, message, icon, position, num, durationMs, setting);
}
else if (window is WindowX wx)
{
- Toast.Show(wx, message, icon, position, 0, durationMs, setting);
+ Show(wx, message, icon, position, 0, durationMs, setting);
}
}
@@ -45,11 +46,11 @@
if (window is PanuonWindow pw)
{
double num = 20 + (pw.menuTab.MenuVisibility == Visibility.Visible ? pw.menuTab.Menu.ActualHeight + pw.menuTab.SubMenu.ActualHeight : 0);
- Toast.Show(pw, message, icon, position, num, durationMs, setting);
+ Show(pw, message, icon, position, num, durationMs, setting);
}
else if (window is WindowX wx)
{
- Toast.Show(wx, message, icon, position, 0, durationMs, setting);
+ Show(wx, message, icon, position, 0, durationMs, setting);
}
}
@@ -59,12 +60,17 @@
if (window is PanuonWindow pw)
{
double num = 20 + (pw.menuTab.MenuVisibility == Visibility.Visible ? pw.menuTab.Menu.ActualHeight + pw.menuTab.SubMenu.ActualHeight : 0);
- Toast.Show(pw, message, icon, position, num, durationMs, setting);
+ Show(pw, message, icon, position, num, durationMs, setting);
}
else if (window is WindowX wx)
{
- Toast.Show(wx, message, icon, position, 0, durationMs, setting);
+ Show(wx, message, icon, position, 0, durationMs, setting);
}
}
+
+ private void Show(WindowX window, string message, MessageBoxIcon icon, ToastPosition position, double offset, int durationMs, ToastSetting setting)
+ {
+ Toast.Show(window, message, icon, position, offset, durationMs, setting);
+ }
}
}
diff --git a/WPFProject/WPFProject.csproj b/WPFProject/WPFProject.csproj
index 55d3de6..4558ef5 100644
--- a/WPFProject/WPFProject.csproj
+++ b/WPFProject/WPFProject.csproj
@@ -279,7 +279,7 @@
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
- <Content Include="Api\Api.txt">
+ <Content Include="Api\SQLite.Interop.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="Config\Put Your Config Here.txt">
@@ -292,6 +292,9 @@
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="SuperSocket.SocketEngine.dll">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="瀹夎MSMQ.bat">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Resource Include="Icon\b1.jpg" />
@@ -404,6 +407,12 @@
<Content Include="Lang\en-US\SeqEditor.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
+ <Content Include="Lang\zh-CN\ChangeModel.json">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="Lang\en-US\ChangeModel.json">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
<None Include="packages.config" />
<None Include="Properties\app.manifest" />
<None Include="Properties\Settings.settings">
@@ -455,6 +464,10 @@
<Project>{de4205c6-5923-46fd-a4b9-65169bf61c75}</Project>
<Name>HMI.MenuManage</Name>
</ProjectReference>
+ <ProjectReference Include="..\Plugin.ChangeModel\Plugin.ChangeModel.csproj">
+ <Project>{ef5972b1-dd20-404d-b2b3-37e70e2a478a}</Project>
+ <Name>Plugin.ChangeModel</Name>
+ </ProjectReference>
<ProjectReference Include="..\Plugin.DataBoard\Plugin.DataBoard.csproj">
<Project>{be42ab26-3270-43e1-84b8-6929d862ff8d}</Project>
<Name>Plugin.DataBoard</Name>
@@ -463,9 +476,21 @@
<Project>{306a83dc-a7db-4057-baa7-477d8756f5d9}</Project>
<Name>Plugin.DOControl</Name>
</ProjectReference>
+ <ProjectReference Include="..\Plugin.DODriverControl\Plugin.DODriverControl.csproj">
+ <Project>{61df853d-829a-4426-bef8-0135586005b6}</Project>
+ <Name>Plugin.DODriverControl</Name>
+ </ProjectReference>
<ProjectReference Include="..\Plugin.JarUI\Plugin.JarUI.csproj">
<Project>{968fe602-22d6-42bd-981c-601ad518a896}</Project>
<Name>Plugin.JarUI</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Plugin.MaterialOpt\Plugin.MaterialOpt.csproj">
+ <Project>{e1f90cbd-a0d4-48da-ab25-7f490935aa4a}</Project>
+ <Name>Plugin.MaterialOpt</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Plugin.ModelManage\Plugin.ModelManage.csproj">
+ <Project>{76ce4d21-702c-416f-95b4-f4f4c5b2d162}</Project>
+ <Name>Plugin.ModelManage</Name>
</ProjectReference>
<ProjectReference Include="..\Plugin.SeqEditor\Plugin.SeqEditor.csproj">
<Project>{717fd815-ff95-4f30-b4d9-9cea978ca40e}</Project>
@@ -474,10 +499,6 @@
<ProjectReference Include="..\Plugin.ServoManage\Plugin.ServoManage.csproj">
<Project>{1853e00f-6865-4bc6-974b-6a5e1c00bafe}</Project>
<Name>Plugin.ServoManage</Name>
- </ProjectReference>
- <ProjectReference Include="..\Plugin.TestBuilder\Plugin.TestBuilder.csproj">
- <Project>{30201ec1-9a82-48db-94b9-bd5c1190228b}</Project>
- <Name>Plugin.TestBuilder</Name>
</ProjectReference>
<ProjectReference Include="..\Plugin.TestResult\Plugin.TestResult.csproj">
<Project>{7375b74c-b6bf-4814-9838-e1caacad1897}</Project>
@@ -520,7 +541,8 @@
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
- <PostBuildEvent>
+ <PostBuildEvent>IF "$(ConfigurationName)"=="Release" Confuser.CLI.exe $(TargeDir)..\ConfuserEx\$(TargetFileName).crproj
+
move /y "$(TargeDir)HMI.Core.dll" $(TargeDir)Libs\HMI.Core.dll"
move /y "$(TargeDir)HMI.Base.dll" $(TargeDir)Libs\HMI.Base.dll"
move /y "$(TargeDir)HMI.UI.dll" $(TargeDir)Libs\HMI.UI.dll"
@@ -547,6 +569,10 @@
move /y "$(TargeDir)Plugin.DataBoard.dll" $(TargeDir)Plugin\Plugin.DataBoard.dll"
move /y "$(TargeDir)Plugin.JarUI.dll" $(TargeDir)Plugin\Plugin.JarUI.dll"
move /y "$(TargeDir)Plugin.SeqEditor.dll" $(TargeDir)Plugin\Plugin.SeqEditor.dll"
+move /y "$(TargeDir)Plugin.ChangeModel.dll" $(TargeDir)Plugin\Plugin.ChangeModel.dll"
+move /y "$(TargeDir)Plugin.MaterialOpt.dll" $(TargeDir)Plugin\Plugin.MaterialOpt.dll"
+move /y "$(TargeDir)Plugin.DODriverControl.dll" $(TargeDir)Plugin\Plugin.DODriverControl.dll"
+move /y "$(TargeDir)Plugin.ModelManage.dll" $(TargeDir)Plugin\Plugin.ModelManage.dll"
setlocal enabledelayedexpansion
@@ -556,6 +582,12 @@
rmdir /S /Q "%25destination_folder%25"
mkdir "%25destination_folder%25"
+for %25%25F in ("%25source_folder%25\*") do (
+ if /I "%25%25~nxF"=="System.Data.SQLite.dll" (
+ xcopy "%25source_folder%25\%25%25F" "%25source_folder%25\Api\%25%25F" /Y
+ )
+)
+
for /d %25%25D in ("%25source_folder%25\*") do (
if /I not "%25%25~nxD"=="Api" if /I not "%25%25~nxD"=="Config" if /I not "%25%25~nxD"=="Icon" if /I not "%25%25~nxD"=="Lang" if /I not "%25%25~nxD"=="Libs" if /I not "%25%25~nxD"=="Log" if /I not "%25%25~nxD"=="Plugin" if /I not "%25%25~nxD"=="TestPlatform.exe.WebView2" (
move /Y "%25%25D" "%25destination_folder%25"
@@ -563,7 +595,7 @@
)
for %25%25F in ("%25source_folder%25\*") do (
- if /I not "%25%25~nxF"=="$(TargetFileName)" if /I not "%25%25~nxF"=="$(TargetFileName).config" if /I not "%25%25~nxF"=="$(TargetName).pdb" if /I not "%25%25~nxF"=="clear.bat" (
+ if /I not "%25%25~nxF"=="$(TargetFileName)" if /I not "%25%25~nxF"=="$(TargetFileName).config" if /I not "%25%25~nxF"=="$(TargetName).pdb" if /I not "%25%25~nxF"=="clear.bat" if /I not "%25%25~nxF"=="瀹夎MSMQ.bat" (
move /Y "%25%25F" "%25destination_folder%25"
)
)
diff --git a/WPFProject/WPFProject.sln b/WPFProject/WPFProject.sln
index 1e074b0..366f8fa 100644
--- a/WPFProject/WPFProject.sln
+++ b/WPFProject/WPFProject.sln
@@ -65,6 +65,22 @@
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Plugin.SeqEditor", "..\Plugin.SeqEditor\Plugin.SeqEditor.csproj", "{717FD815-FF95-4F30-B4D9-9CEA978CA40E}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Plugin.ChangeModel", "..\Plugin.ChangeModel\Plugin.ChangeModel.csproj", "{EF5972B1-DD20-404D-B2B3-37E70E2A478A}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "lmes", "..\..\MesApi\lmes.csproj", "{376CA791-49D8-B4D7-6F98-6E86BD46CAEF}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Plugin.MaterialOpt", "..\Plugin.MaterialOpt\Plugin.MaterialOpt.csproj", "{E1F90CBD-A0D4-48DA-AB25-7F490935AA4A}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HMI.MQUtil", "..\SimpleUtil\HMI.MQUtil\HMI.MQUtil.csproj", "{F8B8B6B6-821B-4FF6-B556-9CAB840EA57A}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Plugin.DODriverControl", "..\Plugin.DODriverControl\Plugin.DODriverControl.csproj", "{61DF853D-829A-4426-BEF8-0135586005B6}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HslCommunication", "..\..\hslCommunicationV12.0.3甯︽簮鐮乨emo\HslCommunication\HslCommunication.csproj", "{AA30059E-7269-415C-9DF2-55C310DD5548}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Plugin.TsSupport", "..\Plugin.TsSupport\Plugin.TsSupport.csproj", "{3068124E-F12B-473E-99A0-2DA5A0385D05}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Plugin.ModelManage", "..\Plugin.ModelManage\Plugin.ModelManage.csproj", "{76CE4D21-702C-416F-95B4-F4F4C5B2D162}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -313,6 +329,70 @@
{717FD815-FF95-4F30-B4D9-9CEA978CA40E}.Release|Any CPU.Build.0 = Release|Any CPU
{717FD815-FF95-4F30-B4D9-9CEA978CA40E}.Release|x64.ActiveCfg = Release|x64
{717FD815-FF95-4F30-B4D9-9CEA978CA40E}.Release|x64.Build.0 = Release|x64
+ {EF5972B1-DD20-404D-B2B3-37E70E2A478A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EF5972B1-DD20-404D-B2B3-37E70E2A478A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EF5972B1-DD20-404D-B2B3-37E70E2A478A}.Debug|x64.ActiveCfg = Debug|x64
+ {EF5972B1-DD20-404D-B2B3-37E70E2A478A}.Debug|x64.Build.0 = Debug|x64
+ {EF5972B1-DD20-404D-B2B3-37E70E2A478A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EF5972B1-DD20-404D-B2B3-37E70E2A478A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {EF5972B1-DD20-404D-B2B3-37E70E2A478A}.Release|x64.ActiveCfg = Release|Any CPU
+ {EF5972B1-DD20-404D-B2B3-37E70E2A478A}.Release|x64.Build.0 = Release|Any CPU
+ {376CA791-49D8-B4D7-6F98-6E86BD46CAEF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {376CA791-49D8-B4D7-6F98-6E86BD46CAEF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {376CA791-49D8-B4D7-6F98-6E86BD46CAEF}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {376CA791-49D8-B4D7-6F98-6E86BD46CAEF}.Debug|x64.Build.0 = Debug|Any CPU
+ {376CA791-49D8-B4D7-6F98-6E86BD46CAEF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {376CA791-49D8-B4D7-6F98-6E86BD46CAEF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {376CA791-49D8-B4D7-6F98-6E86BD46CAEF}.Release|x64.ActiveCfg = Release|Any CPU
+ {376CA791-49D8-B4D7-6F98-6E86BD46CAEF}.Release|x64.Build.0 = Release|Any CPU
+ {E1F90CBD-A0D4-48DA-AB25-7F490935AA4A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E1F90CBD-A0D4-48DA-AB25-7F490935AA4A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E1F90CBD-A0D4-48DA-AB25-7F490935AA4A}.Debug|x64.ActiveCfg = Debug|x64
+ {E1F90CBD-A0D4-48DA-AB25-7F490935AA4A}.Debug|x64.Build.0 = Debug|x64
+ {E1F90CBD-A0D4-48DA-AB25-7F490935AA4A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E1F90CBD-A0D4-48DA-AB25-7F490935AA4A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E1F90CBD-A0D4-48DA-AB25-7F490935AA4A}.Release|x64.ActiveCfg = Release|Any CPU
+ {E1F90CBD-A0D4-48DA-AB25-7F490935AA4A}.Release|x64.Build.0 = Release|Any CPU
+ {F8B8B6B6-821B-4FF6-B556-9CAB840EA57A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F8B8B6B6-821B-4FF6-B556-9CAB840EA57A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F8B8B6B6-821B-4FF6-B556-9CAB840EA57A}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {F8B8B6B6-821B-4FF6-B556-9CAB840EA57A}.Debug|x64.Build.0 = Debug|Any CPU
+ {F8B8B6B6-821B-4FF6-B556-9CAB840EA57A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F8B8B6B6-821B-4FF6-B556-9CAB840EA57A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F8B8B6B6-821B-4FF6-B556-9CAB840EA57A}.Release|x64.ActiveCfg = Release|Any CPU
+ {F8B8B6B6-821B-4FF6-B556-9CAB840EA57A}.Release|x64.Build.0 = Release|Any CPU
+ {61DF853D-829A-4426-BEF8-0135586005B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {61DF853D-829A-4426-BEF8-0135586005B6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {61DF853D-829A-4426-BEF8-0135586005B6}.Debug|x64.ActiveCfg = Debug|x64
+ {61DF853D-829A-4426-BEF8-0135586005B6}.Debug|x64.Build.0 = Debug|x64
+ {61DF853D-829A-4426-BEF8-0135586005B6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {61DF853D-829A-4426-BEF8-0135586005B6}.Release|Any CPU.Build.0 = Release|Any CPU
+ {61DF853D-829A-4426-BEF8-0135586005B6}.Release|x64.ActiveCfg = Release|Any CPU
+ {61DF853D-829A-4426-BEF8-0135586005B6}.Release|x64.Build.0 = Release|Any CPU
+ {AA30059E-7269-415C-9DF2-55C310DD5548}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AA30059E-7269-415C-9DF2-55C310DD5548}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AA30059E-7269-415C-9DF2-55C310DD5548}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {AA30059E-7269-415C-9DF2-55C310DD5548}.Debug|x64.Build.0 = Debug|Any CPU
+ {AA30059E-7269-415C-9DF2-55C310DD5548}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AA30059E-7269-415C-9DF2-55C310DD5548}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AA30059E-7269-415C-9DF2-55C310DD5548}.Release|x64.ActiveCfg = Release|Any CPU
+ {AA30059E-7269-415C-9DF2-55C310DD5548}.Release|x64.Build.0 = Release|Any CPU
+ {3068124E-F12B-473E-99A0-2DA5A0385D05}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3068124E-F12B-473E-99A0-2DA5A0385D05}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3068124E-F12B-473E-99A0-2DA5A0385D05}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {3068124E-F12B-473E-99A0-2DA5A0385D05}.Debug|x64.Build.0 = Debug|Any CPU
+ {3068124E-F12B-473E-99A0-2DA5A0385D05}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3068124E-F12B-473E-99A0-2DA5A0385D05}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3068124E-F12B-473E-99A0-2DA5A0385D05}.Release|x64.ActiveCfg = Release|Any CPU
+ {3068124E-F12B-473E-99A0-2DA5A0385D05}.Release|x64.Build.0 = Release|Any CPU
+ {76CE4D21-702C-416F-95B4-F4F4C5B2D162}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {76CE4D21-702C-416F-95B4-F4F4C5B2D162}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {76CE4D21-702C-416F-95B4-F4F4C5B2D162}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {76CE4D21-702C-416F-95B4-F4F4C5B2D162}.Debug|x64.Build.0 = Debug|Any CPU
+ {76CE4D21-702C-416F-95B4-F4F4C5B2D162}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {76CE4D21-702C-416F-95B4-F4F4C5B2D162}.Release|Any CPU.Build.0 = Release|Any CPU
+ {76CE4D21-702C-416F-95B4-F4F4C5B2D162}.Release|x64.ActiveCfg = Release|Any CPU
+ {76CE4D21-702C-416F-95B4-F4F4C5B2D162}.Release|x64.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -322,6 +402,7 @@
{6735FDB8-B471-41C3-93CB-E8ADBD0989F0} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
{6D0AAB08-0F3E-48CE-B755-9D29BC8F1225} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
{D59E25D1-9B27-46A1-8438-92661DD23FAE} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
+ {F8B8B6B6-821B-4FF6-B556-9CAB840EA57A} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {784CEA1D-A890-4625-B0C1-72294A6B4803}
diff --git "a/WPFProject/\345\256\211\350\243\205MSMQ.bat" "b/WPFProject/\345\256\211\350\243\205MSMQ.bat"
new file mode 100644
index 0000000..4396704
--- /dev/null
+++ "b/WPFProject/\345\256\211\350\243\205MSMQ.bat"
@@ -0,0 +1,5 @@
+;@ECHO on
+title AUTO START Windows function
+color 1F
+start /w pkgmgr /iu:MSMQ-Container;MSMQ-Server
+pause
\ No newline at end of file
--
Gitblit v1.9.1