From c1c3772a11b1f3fbad8846cc714120771d85fa53 Mon Sep 17 00:00:00 2001
From: alielie <alielie@git.com>
Date: 星期四, 12 六月 2025 20:10:59 +0800
Subject: [PATCH] 新增SeqEditor
---
Plugin.SeqEditor/SettingPanel/ActionPanel.xaml.cs | 39
Plugin.SeqEditor/AssemblyInfo.cs | 10
WPFProject/BuildCmd.bat | 10
Plugin.TestResult/SingleCell.xaml | 8
Plugin.SeqEditor/SettingPanel/StringValTestPanel.xaml | 57 +
Plugin.SeqEditor/Util/Step2EPO.cs | 44
Plugin.SeqEditor/SettingPanel/CommonProperty.xaml.cs | 45 +
Plugin.TestResult/TestResultView.xaml.cs | 1
WPFProject/Lang/zh-CN/app.json | 4
HMI.UI/Controls/treegrid/TreeItemConverter.cs | 28
HMI.MenuManage/RoleManage.xaml | 4
Plugin.SeqEditor/Entity/EditablePO/StringValTestEPO.cs | 66 +
Plugin.SeqEditor/SettingPanel/WaitPanel.xaml | 48 +
WPFProject/LoadingWindow.xaml.cs | 9
Plugin.SeqEditor/SettingPanel/NumValTestPanel.xaml | 50 +
Plugin.SeqEditor/ViewModel/SeqEditorViewModel.cs | 454 ++++++++++
HMI.UI/MaskWindow.xaml | 49
Plugin.SeqEditor/SettingPanel/NumValTestPanel.xaml.cs | 20
WPFProject/Lang/zh-CN/SeqEditor.json | 34
HMI.UI/Controls/treegrid/Controls/TreeItemData.cs | 6
Plugin.SeqEditor/Entity/StepUI.cs | 91 ++
WPFProject/App.config | 2
HMI.UI/Controls/treegrid/Themes/TreeItemContentControl.xaml | 9
HMI.UI/Controls/MultiCombox.xaml.cs | 201 ++++
Plugin.TsExecution/TsExecution.xaml.cs | 48
HMI.UnitTest/MainWindow.xaml.cs | 4
Plugin.SeqEditor/Constant/DefaultStepName.cs | 12
Plugin.SeqEditor/Util/ItemData.cs | 147 +++
Plugin.SeqEditor/SettingPanel/ActionPanel.xaml | 45 +
WPFProject/packages.config | 1
HMI.UI/Controls/treegrid/Controls/TreeDataGrid.cs | 25
HMI.UI/Util/MsgBoxHelper.cs | 5
Plugin.SeqEditor/Entity/EditablePO/IEPO.cs | 46 +
Plugin.SeqEditor/SeqEditor.xaml.cs | 70 +
Plugin.SeqEditor/SettingPanel/CommonProperty.xaml | 25
WPFProject/Lang/en-US/SeqEditor.json | 34
Plugin.SeqEditor/Entity/EditablePO/NumValTestEPO.cs | 57 +
HMI.UI/Style/FormStyle.xaml | 11
WPFProject/WPFProject.csproj | 22
Plugin.SeqEditor/SettingPanel/StringValTestPanel.xaml.cs | 21
HMI.UI/Style/PanuonResource.xaml | 38
HMI.UI/Controls/MultiCombox.xaml | 10
Plugin.TsExecution/SingleControl.xaml | 10
WPFProject/WPFProject.sln | 10
Plugin.JarUI/JarUI.xaml.cs | 156 +++
Plugin.TsExecution/SingleControl.xaml.cs | 43
Plugin.SeqEditor/Entity/SeqUI.cs | 27
Plugin.SeqEditor/Plugin.SeqEditor.csproj | 33
Plugin.SeqEditor/Entity/EditablePO/WaitEPO.cs | 37
Plugin.SeqEditor/Entity/VarUI.cs | 58 +
Plugin.JarUI/JarUI.xaml | 31
Plugin.SeqEditor/SettingPanel/WaitPanel.xaml.cs | 19
Plugin.SeqEditor/Constant/StepTypeStr.cs | 24
Plugin.SeqEditor/SeqEditor.xaml | 254 +++++
Plugin.TestResult/SingleCell.xaml.cs | 12
Plugin.SeqEditor/Util/PoExplain.cs | 44
HMI.UI/HMI.UI.csproj | 8
57 files changed, 2,579 insertions(+), 97 deletions(-)
diff --git a/HMI.MenuManage/RoleManage.xaml b/HMI.MenuManage/RoleManage.xaml
index 39e2f3e..eda62eb 100644
--- a/HMI.MenuManage/RoleManage.xaml
+++ b/HMI.MenuManage/RoleManage.xaml
@@ -99,8 +99,8 @@
Command="{Binding CheckCommand}"
CommandParameter="{Binding Path=IsChecked,RelativeSource={RelativeSource Mode=Self}}"
/>
- <Image Width="{StaticResource ContentFontSize}"
- Height="{StaticResource ContentFontSize}" Margin="5" Source="{Binding MenuIcon,Converter={StaticResource path2Image},Mode=OneWay}"/>
+ <!--<Image Width="{StaticResource ContentFontSize}"
+ Height="{StaticResource ContentFontSize}" Margin="5" Source="{Binding MenuIcon,Converter={StaticResource path2Image},Mode=OneWay}"/>-->
<TextBlock VerticalAlignment="Center" Text="{Binding MenuName}"/>
</StackPanel>
</HierarchicalDataTemplate>
diff --git a/HMI.UI/Controls/MultiCombox.xaml b/HMI.UI/Controls/MultiCombox.xaml
new file mode 100644
index 0000000..c098596
--- /dev/null
+++ b/HMI.UI/Controls/MultiCombox.xaml
@@ -0,0 +1,10 @@
+锘�<UserControl x:Class="HMI.UI.Controls.MultiCombox"
+ 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.Controls"
+ mc:Ignorable="d"
+ d:DesignHeight="450" d:DesignWidth="800">
+ <ComboBox ></ComboBox>
+</UserControl>
diff --git a/HMI.UI/Controls/MultiCombox.xaml.cs b/HMI.UI/Controls/MultiCombox.xaml.cs
new file mode 100644
index 0000000..85f5bcc
--- /dev/null
+++ b/HMI.UI/Controls/MultiCombox.xaml.cs
@@ -0,0 +1,201 @@
+锘縰sing System;
+using System.Collections;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Globalization;
+using System.Linq;
+using System.Reflection;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Input;
+
+namespace HMI.UI
+{
+ public class MultiComboBoxItem : ComboBoxItem, INotifyPropertyChanged
+ {
+ #region ...
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ protected void RaisePropertyChanged(string propertyName)
+ {
+ if (PropertyChanged != null)
+ {
+ PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+ }
+ }
+ #endregion
+
+ private MultiComboBox parent;
+ public MultiComboBoxItem(MultiComboBox parent)
+ {
+ this.parent = parent;
+ this.DataContextChanged += MultiComboBoxItem_DataContextChanged;
+ }
+
+ protected override void OnMouseMove(MouseEventArgs e)
+ {
+ this.PreviewMouseUp += MultiComboBoxItem_PreviewMouseUp;
+ base.OnMouseMove(e);
+ }
+
+ protected override void OnMouseLeave(MouseEventArgs e)
+ {
+ this.PreviewMouseUp -= MultiComboBoxItem_PreviewMouseUp;
+ base.OnMouseLeave(e);
+ }
+
+ protected override void OnLostFocus(RoutedEventArgs e)
+ {
+ this.PreviewMouseUp -= MultiComboBoxItem_PreviewMouseUp;
+ base.OnLostFocus(e);
+ }
+
+ private void MultiComboBoxItem_PreviewMouseUp(object sender, MouseButtonEventArgs e)
+ {
+ if (DataContext is MultiComboBoxData data)
+ {
+ data.IsChecked = !data.IsChecked;
+ e.Handled = true;
+ }
+ }
+
+ private void MultiComboBoxItem_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
+ {
+ if (e.OldValue != null && e.OldValue is MultiComboBoxData oldData)
+ {
+ oldData.IsCheckedChanged -= DataIsExpandedChange;
+ }
+ if (DataContext != null && DataContext is MultiComboBoxData newData)
+ {
+ newData.IsCheckedChanged += DataIsExpandedChange;
+ }
+ }
+
+ private void DataIsExpandedChange(object sender, bool IsExpanded)
+ {
+ parent.Item_IsCheckedChanged((MultiComboBoxData)sender, this, IsExpanded);
+ }
+ }
+
+ public class MultiComboBoxDataConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if (value is IEnumerable<object> items)
+ {
+ return items.Select(item => new MultiComboBoxData(item, "DisplayName", "DataValue")).ToList();
+ }
+ return null;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ return value;
+ }
+ }
+
+ public class MultiComboBoxData : INotifyPropertyChanged
+ {
+ #region ...
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ protected void RaisePropertyChanged(string propertyName)
+ {
+ if (PropertyChanged != null)
+ {
+ PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+ }
+ }
+ #endregion
+
+ public event EventHandler<bool> IsCheckedChanged;
+
+ private bool isChecked;
+
+ public bool IsChecked
+ {
+ get { return isChecked; }
+ set
+ {
+ isChecked = value;
+ RaisePropertyChanged("IsChecked");
+ IsCheckedChanged?.Invoke(this, value);
+ }
+ }
+ public string DisplayName
+ {
+ get => showName?.GetValue(Data).ToString();
+ }
+
+ public string DataValue
+ {
+ get => valueName?.GetValue(Data).ToString();
+ }
+
+ private PropertyInfo showName;
+ private PropertyInfo valueName;
+
+ public MultiComboBoxData(object data, string showName, string valueName)
+ {
+ this.Data = data;
+ this.showName = data.GetType().GetProperty(showName);
+ this.valueName = data.GetType().GetProperty(valueName);
+ }
+
+ public object Data { get; private set; }
+ }
+
+ /// <summary>
+ /// MultiCombox.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ public partial class MultiComboBox : ComboBox
+ {
+ protected override DependencyObject GetContainerForItemOverride()
+ {
+ var item = new MultiComboBoxItem(this);
+ return item;
+ }
+
+ [Bindable(true)]
+ [Category("Appearance")]
+ [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+ [Localizability(LocalizationCategory.NeverLocalize)]
+ public object SelectedValues
+ {
+ get
+ {
+ return GetValue(SelectedValuesProperty);
+ }
+ set
+ {
+ SetValue(SelectedValuesProperty, value);
+ }
+ }
+
+ public static readonly DependencyProperty SelectedValuesProperty =
+ DependencyProperty.RegisterAttached("SelectedValues", typeof(object), typeof(MultiComboBox),
+ new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
+
+
+ public void Item_IsCheckedChanged(MultiComboBoxData data, MultiComboBoxItem item, bool isChecked)
+ {
+ var selectedValues = SelectedValues?.ToString() ?? "";
+ var showNames = this.Text?.ToString() ?? "";
+ List<string> values = string.IsNullOrEmpty(selectedValues) ? new List<string>() : selectedValues.Split(',').ToList();
+ List<string> names = string.IsNullOrEmpty(showNames) ? new List<string>() : showNames.Split(',').ToList();
+ if (isChecked)
+ {
+ values.Add(data.DataValue);
+ names.Add(data.DisplayName);
+ }
+ else
+ {
+ values.Remove(data.DataValue);
+ names.Remove(data.DisplayName);
+ }
+ Text = string.Join(",", names);
+ SelectedValues = string.Join(",", values);
+ }
+ }
+}
diff --git a/HMI.UI/Controls/treegrid/Controls/TreeDataGrid.cs b/HMI.UI/Controls/treegrid/Controls/TreeDataGrid.cs
index fdd2866..8823656 100644
--- a/HMI.UI/Controls/treegrid/Controls/TreeDataGrid.cs
+++ b/HMI.UI/Controls/treegrid/Controls/TreeDataGrid.cs
@@ -48,21 +48,36 @@
{
if (e.OldValue != null && e.OldValue is TreeItemData oldTreeData)
{
+ oldTreeData.IsExpandedChange -= DataIsExpandedChange;
oldTreeData.VisibleChange -= DataVisiableChange;
+
}
if (DataContext != null && DataContext is TreeItemData treeData)
{
+ treeData.IsExpandedChange += DataIsExpandedChange;
treeData.VisibleChange += DataVisiableChange;
+ }
+ }
+
+ private void DataIsExpandedChange(object sender, bool IsExpanded)
+ {
+ object parent = ItemsControl.ItemsControlFromItemContainer(this);
+ if (sender is TreeItemData tid)
+ {
+ foreach (var data in tid.Items)
+ {
+ data.IsVisible = IsExpanded;
+ }
}
}
private void DataVisiableChange(object sender, bool visiable)
{
- object parent = ItemsControl.ItemsControlFromItemContainer(this);
- if (parent != null && parent is TreeDataGrid treeDataGrid)
- {
- treeDataGrid.OnExpandedChange(visiable);
- }
+ this.Visibility = visiable ? Visibility.Visible : Visibility.Collapsed;
+ //if (parent != null && parent is TreeDataGrid treeDataGrid)
+ //{
+ // treeDataGrid.OnExpandedChange(visiable);
+ //}
}
}
}
diff --git a/HMI.UI/Controls/treegrid/Controls/TreeItemData.cs b/HMI.UI/Controls/treegrid/Controls/TreeItemData.cs
index bec9926..46a045c 100644
--- a/HMI.UI/Controls/treegrid/Controls/TreeItemData.cs
+++ b/HMI.UI/Controls/treegrid/Controls/TreeItemData.cs
@@ -13,6 +13,7 @@
public class TreeItemData : NotifyBase
{
+ public event EventHandler<bool> IsExpandedChange;
public event EventHandler<bool> VisibleChange;
protected override void Set(string name)
@@ -38,7 +39,7 @@
_IsExpanded = value;
Set("IsExpanded");
SetItemsVisible(value);
- VisibleChange?.Invoke(this, value);
+ IsExpandedChange?.Invoke(this, value);
}
}
#endregion
@@ -206,7 +207,7 @@
{
return _IsVisible;
}
- private set
+ set
{
if (_IsVisible == value)
{
@@ -215,6 +216,7 @@
_IsVisible = value;
Set("IsVisible");
SetItemsVisible(value);
+ VisibleChange?.Invoke(this, value);
}
}
diff --git a/HMI.UI/Controls/treegrid/Themes/TreeItemContentControl.xaml b/HMI.UI/Controls/treegrid/Themes/TreeItemContentControl.xaml
index 741fe6b..7e13490 100644
--- a/HMI.UI/Controls/treegrid/Themes/TreeItemContentControl.xaml
+++ b/HMI.UI/Controls/treegrid/Themes/TreeItemContentControl.xaml
@@ -114,6 +114,8 @@
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="BorderBrush" Value="LightGray"/>
+ <Setter Property="Foreground" Value="{Binding Foreground,RelativeSource={RelativeSource Mode=FindAncestor,
+AncestorType=DataGridCell,AncestorLevel=1}}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:TreeItemContentControl}">
@@ -145,7 +147,7 @@
<Line x:Name="line" X1="7.5" Y1="0" X2="7.5" Y2="{Binding ElementName=lineGrid,Path=ActualHeight}" StrokeThickness="1"
Stroke="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=DataGridRow},Path=Foreground}" StrokeDashArray="1,1"/>
</Grid>
- <!-- 杩欓噷鏀惧紑鏈変釜闂锛屼細璁╁彧鏈変竴涓牴鑺傜偣鐨勬爲鍒楄〃鏄剧ず閿欒 -->
+ <!--杩欓噷鏀惧紑鏈変釜闂锛屼細璁╁彧鏈変竴涓牴鑺傜偣鐨勬爲鍒楄〃鏄剧ず閿欒-->
<!--<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsLastItem}" Value="true">
<Setter Property="Visibility" Value="Collapsed"/>
@@ -156,7 +158,10 @@
</ListBox>
</Grid>
- <ToggleButton x:Name="ExpanderButton" Grid.Column="1" Style="{StaticResource ClearToggleStyle}" HorizontalAlignment="Left"
+ <ToggleButton x:Name="ExpanderButton"
+ Cursor="Hand"
+ Grid.Column="1" Style="{StaticResource ClearToggleStyle}" HorizontalAlignment="Left"
+
IsChecked="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},Path=TreeData.IsExpanded,Mode=TwoWay}"
Content="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},Path=TreeData.IconType}"
ContentTemplate="{StaticResource Icon_Template}"
diff --git a/HMI.UI/Controls/treegrid/TreeItemConverter.cs b/HMI.UI/Controls/treegrid/TreeItemConverter.cs
new file mode 100644
index 0000000..bff69af
--- /dev/null
+++ b/HMI.UI/Controls/treegrid/TreeItemConverter.cs
@@ -0,0 +1,28 @@
+锘縰sing System;
+using System.Collections;
+using System.Globalization;
+using System.Windows.Data;
+
+namespace HMI.UI
+{
+ public class TreeItemConverter : IValueConverter
+ {
+ object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if (value == null || parameter == null)
+ {
+ return value;
+ }
+ if (value is IEnumerable items)
+ {
+ return new TreeItemDataCollection(items, parameter.ToString(), true);
+ }
+ return value;
+ }
+
+ object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ return value;
+ }
+ }
+}
diff --git a/HMI.UI/HMI.UI.csproj b/HMI.UI/HMI.UI.csproj
index 1e9ec04..9582666 100644
--- a/HMI.UI/HMI.UI.csproj
+++ b/HMI.UI/HMI.UI.csproj
@@ -83,6 +83,9 @@
<Compile Include="Controls\KeyboradWindow.xaml.cs">
<DependentUpon>KeyboradWindow.xaml</DependentUpon>
</Compile>
+ <Compile Include="Controls\MultiCombox.xaml.cs">
+ <DependentUpon>MultiCombox.xaml</DependentUpon>
+ </Compile>
<Compile Include="Controls\NumberPanel.xaml.cs">
<DependentUpon>NumberPanel.xaml</DependentUpon>
</Compile>
@@ -90,6 +93,7 @@
<Compile Include="Controls\treegrid\Controls\TreeGrid.cs" />
<Compile Include="Controls\treegrid\Controls\TreeItemContentControl.cs" />
<Compile Include="Controls\treegrid\Controls\TreeItemData.cs" />
+ <Compile Include="Controls\treegrid\TreeItemConverter.cs" />
<Compile Include="Controls\treegrid\TreeNodeExtend.cs" />
<Compile Include="Converter\VisibilityBoolConverter.cs" />
<Compile Include="Converter\DataGridRowFlagConverter.cs" />
@@ -127,6 +131,10 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
+ <Page Include="Controls\MultiCombox.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
<Page Include="Controls\NumberPanel.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
diff --git a/HMI.UI/MaskWindow.xaml b/HMI.UI/MaskWindow.xaml
index 3364c0d..c648b68 100644
--- a/HMI.UI/MaskWindow.xaml
+++ b/HMI.UI/MaskWindow.xaml
@@ -11,15 +11,16 @@
pu:WindowXCaption.Height="0"
ResizeMode="NoResize"
SizeToContent="WidthAndHeight"
- Height="20"
CanClose="False"
- WindowStyle="None"
+ MinWidth="300"
+ MinHeight="0"
+ Width="Auto"
x:Name="self"
WindowStartupLocation="CenterOwner">
<WindowChrome.WindowChrome>
<WindowChrome GlassFrameThickness="-1"/>
</WindowChrome.WindowChrome>
- <Window.Style>
+ <!--<Window.Style>
<Style TargetType="Window">
<Style.Triggers>
<DataTrigger Binding="{Binding Status}" Value="Info">
@@ -27,12 +28,50 @@
</DataTrigger>
</Style.Triggers>
</Style>
- </Window.Style>
+ </Window.Style>-->
<Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition />
+ </Grid.RowDefinitions>
+ <Border Padding="10,5,0,5" Background="{StaticResource PrimaryColor}" CornerRadius="5,5,0,0">
+ <Label Padding="5" FontSize="14" Margin="0" Foreground="#FFF" Content="{DynamicResource App.PleaseWait}"/>
+ </Border>
+
+ <StackPanel Grid.Row="1" Margin="20" Orientation="Horizontal" VerticalAlignment="Center"
+ HorizontalAlignment="Center">
+ <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>
+
+ <Label x:Name="label" VerticalContentAlignment="Center" HorizontalContentAlignment="Left"
+ FontSize="20" FontWeight="Bold" Margin="20,0,0,0" />
+ </StackPanel>
+
+ </Grid>
+ <!--<Grid>
<Label x:Name="label"
Margin="20"
VerticalContentAlignment="Center"
HorizontalContentAlignment="Center"
FontSize="20" FontWeight="Bold" Foreground="White"/>
- </Grid>
+ </Grid>-->
</pu:WindowX>
diff --git a/HMI.UI/Style/FormStyle.xaml b/HMI.UI/Style/FormStyle.xaml
index 5172944..b9a908f 100644
--- a/HMI.UI/Style/FormStyle.xaml
+++ b/HMI.UI/Style/FormStyle.xaml
@@ -67,6 +67,8 @@
<Setter Property="pu:TextBoxHelper.FocusedWatermarkForeground" Value="#AAAAAA" />
<Setter Property="Height" Value="35" />
<Setter Property="Padding" Value="5,0" />
+ <Setter Property="BorderThickness" Value="1" />
+ <Setter Property="BorderBrush" Value="Gray" />
<Setter Property="Background" Value="White" />
<Setter Property="Foreground" Value="Black" />
<Setter Property="VerticalContentAlignment" Value="Center"/>
@@ -85,7 +87,6 @@
<Setter Property="pu:TextBoxHelper.FocusedWatermarkForeground" Value="#AAAAAA" />
<Setter Property="Height" Value="35" />
<Setter Property="Padding" Value="5,0" />
- <Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground" Value="Black" />
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Style.Triggers>
@@ -151,6 +152,14 @@
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="Foreground" Value="Black" />
<Setter Property="SelectedValuePath" Value="Content"/>
+ <Setter Property="BorderThickness" Value="1" />
+ <Setter Property="BorderBrush" Value="Gray" />
+ <Style.Triggers>
+ <Trigger Property="IsEnabled" Value="False">
+ <Setter Property="Background" Value="#e8e8e8"/>
+ <Setter Property="Opacity" Value="1"/>
+ </Trigger>
+ </Style.Triggers>
</Style>
<Style x:Key="TimePicker" TargetType="pu:DateTimePicker">
diff --git a/HMI.UI/Style/PanuonResource.xaml b/HMI.UI/Style/PanuonResource.xaml
index 4fdbc63..246d9d4 100644
--- a/HMI.UI/Style/PanuonResource.xaml
+++ b/HMI.UI/Style/PanuonResource.xaml
@@ -12,7 +12,7 @@
xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/HMI.UI;component/Style/Colors.xaml"/>
- <pu:StyleDictionary Includes="PasswordBox,TextBox,ComboBox,Button,DataGrid,TreeView,Menu,ListBox" />
+ <pu:StyleDictionary Includes="PasswordBox,TextBox,ComboBox,Button,DataGrid,TreeView,Menu,ListBox,ContextMenu" />
<ResourceDictionary Source="/HMI.UI;component/Resources/Font/Font.xaml"/>
</ResourceDictionary.MergedDictionaries>
<sys:Double x:Key="TitleFontSize">20</sys:Double>
@@ -157,7 +157,7 @@
<Setter Property="BorderBrush" Value="{StaticResource CommonBoarder}"/>
<Setter Property="BorderThickness" Value="2"/>
<Setter Property="Background" Value="#f3f9ff"/>
- <Setter Property="Margin" Value="10"/>
+ <Setter Property="Margin" Value="5"/>
<Setter Property="Padding" Value="10"/>
</Style>
@@ -172,30 +172,35 @@
</Style>
<Style x:Key="TableTextBlock" TargetType="TextBlock">
- <Setter Property="Padding" Value="0"/>
+ <Setter Property="Padding" Value="0,2"/>
<Setter Property="Margin" Value="0"/>
<Setter Property="VerticalAlignment" Value="Center"/>
+ <Setter Property="TextWrapping" Value="Wrap"/>
</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="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 TargetType="DataGridColumnHeader"
BasedOn="{StaticResource {x:Static pu:StyleKeys.DataGridColumnHeaderStyle}}">
<Setter Property="Padding" Value="10"/>
<Setter Property="BorderThickness" Value="0"/>
</Style>
</Style.Resources>
- <Setter Property="pu:DataGridHelper.ColumnHeaderPadding" Value="0"/>
+
<Setter Property="RowHeight" Value="30"/>
<Setter Property="ColumnHeaderHeight" Value="36"/>
+
+ <Setter Property="pu:DataGridHelper.ColumnHeaderPadding" Value="0"/>
<Setter Property="ForceCursor" Value="True"/>
<Setter Property="SelectionMode" Value="Single"/>
<Setter Property="RowStyle" Value="{StaticResource DefaultDataGridRow}"/>
@@ -286,13 +291,6 @@
Value="{DynamicResource App.Save}"/>
<Setter Property="pu:WindowXModalDialog.ButtonPanelMargin" Value="0,30,10,10"/>
</Style>
-
- <Popup x:Key="testPop" Placement="Relative" StaysOpen="True" Width="1920" Height="1080">
- <Rectangle x:Name="RectMask"
- Fill="Red"
- Opacity="0"
- Visibility="Visible" />
- </Popup>
<Style x:Key="DefaultListBox" TargetType="ListBox" BasedOn="{StaticResource {x:Static pu:StyleKeys.ListBoxStyle}}">
<Setter Property="pu:ListBoxHelper.ItemsHoverBackground" Value="{StaticResource SecondPrimaryColor}"/>
diff --git a/HMI.UI/Util/MsgBoxHelper.cs b/HMI.UI/Util/MsgBoxHelper.cs
index 79174a2..18f2a30 100644
--- a/HMI.UI/Util/MsgBoxHelper.cs
+++ b/HMI.UI/Util/MsgBoxHelper.cs
@@ -74,7 +74,10 @@
owner.Dispatcher.Invoke(() =>
{
window = Window.GetWindow(owner) ?? Application.Current.MainWindow;
- res = MessageBoxX.Show(window, message, caption, button, icon, defaultButton, setting, countdown);
+ window.Dispatcher.Invoke(() =>
+ {
+ res = MessageBoxX.Show(window, message, caption, button, icon, defaultButton, setting, countdown);
+ });
});
}
else
diff --git a/HMI.UnitTest/MainWindow.xaml.cs b/HMI.UnitTest/MainWindow.xaml.cs
index 2de0f1d..11bfb1a 100644
--- a/HMI.UnitTest/MainWindow.xaml.cs
+++ b/HMI.UnitTest/MainWindow.xaml.cs
@@ -38,7 +38,8 @@
for (int j = 0; j < 1000; j++)
{
string status = (j % 2 == 0) ? "Passed" : "Failed";
- tsExecution.AddTestData(0, $"{j},2,3,4,5,6,{status}");
+ string d = (j % 2 == 0) ? "9" : "9999999999999999999999999999999999999999999999999999999999999999995";
+ tsExecution.AddTestData(0, $"ConnectivityCANRec,2,3,4,{d},6,{status}");
}
});
@@ -46,6 +47,7 @@
tsExecution.UpdatePositionProcessValue(0, 12);
tsExecution.PausePosition(0);
tsExecution.SetPositionBarcode(0, "123456789");
+ tsExecution.SavePositionCSV(0);
//tsExecution.UpdatePositionStatus(1, "Failed");
diff --git a/Plugin.JarUI/JarUI.xaml b/Plugin.JarUI/JarUI.xaml
index c160e66..b0a870c 100644
--- a/Plugin.JarUI/JarUI.xaml
+++ b/Plugin.JarUI/JarUI.xaml
@@ -21,23 +21,38 @@
</Grid.RowDefinitions>
<WindowsFormsHost x:Name="host" Visibility="Collapsed"/>
<DockPanel>
+ <DockPanel.Resources>
+ <Style TargetType="CheckBox">
+ <Setter Property="FontSize" Value="20"/>
+ <Setter Property="VerticalContentAlignment" Value="Center"/>
+ </Style>
+ </DockPanel.Resources>
+
<StackPanel DockPanel.Dock="Right" Orientation="Horizontal" dp:StackPanelHelper.ChildSpace="20">
<Button Style="{StaticResource SuccessButton}" x:Name="startBtn" Click="Button_Click"
- Content="{DynamicResource App.StopSequence}"/>
- <Button Style="{StaticResource DangerButton}" x:Name="stopBtn" Click="Button_Click"
Content="{DynamicResource App.StartSequence}"/>
+ <Button Style="{StaticResource DangerButton}" x:Name="stopBtn" Click="Button_Click"
+ Content="{DynamicResource App.StopSequence}"/>
<Button Style="{StaticResource PrimaryButton}" x:Name="scannerSettingBtn" Click="Button_Click"
Content="{DynamicResource App.ScannerSetting}"/>
</StackPanel>
- <pu:FormGroup HeaderHeight="Auto" HeaderPadding="0" HorizontalContentAlignment="Left">
- <pu:FormGroup.Header>
- <TextBlock FontSize="20" Foreground="#000" Text="{DynamicResource Ts.SelectProductModel}"/>
- </pu:FormGroup.Header>
- <ComboBox Style="{StaticResource FormComboxStyle}" MinWidth="180" ItemsSource="{Binding Products}"
+
+ <StackPanel Orientation="Horizontal" VerticalAlignment="Center" dp:StackPanelHelper.ChildSpace="20">
+ <pu:FormGroup HeaderHeight="Auto" HeaderPadding="0" HorizontalContentAlignment="Left">
+ <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"
MaxWidth="200"
SelectedItem="{Binding SelectedProduct}" x:Name="CbProduct"/>
- </pu:FormGroup>
+ </pu:FormGroup>
+
+ <CheckBox Grid.Column="1"
+IsChecked="{Binding EnableMes,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
+Content="{DynamicResource Ts.EnableMes}"
+/>
+ </StackPanel>
</DockPanel>
<UniformGrid Grid.Row="1" x:Name="uGrid" dp:UniformGridHelper.InnerBorder="1" Columns="6">
diff --git a/Plugin.JarUI/JarUI.xaml.cs b/Plugin.JarUI/JarUI.xaml.cs
index cdaea7c..4313b08 100644
--- a/Plugin.JarUI/JarUI.xaml.cs
+++ b/Plugin.JarUI/JarUI.xaml.cs
@@ -29,8 +29,8 @@
{
DataContext = this;
InitializeComponent();
- InitProducts();
InitTsEngine();
+ InitProducts();
}
public override void InitFinish()
@@ -97,8 +97,21 @@
get { return _selectedProduct; }
set
{
- SetTestSeqFile(value);
Set(ref _selectedProduct, value);
+ SetTestSeqFile(value);
+ }
+ }
+
+ private bool _enableMes;
+ public bool EnableMes
+ {
+ get => _enableMes;
+ set
+ {
+ if (WriteConfig("EnableMes", value))
+ {
+ Set(ref _enableMes, value);
+ }
}
}
@@ -156,17 +169,130 @@
if (!string.IsNullOrEmpty(lastModel))
{
var product = Products.FirstOrDefault(p => p.Name == lastModel);
- if (product != null) SelectedProduct = product;
- goto Write;
+ if (product != null)
+ {
+ SelectedProduct = product;
+ RefershUI();
+ return;
+ }
}
- goto Write;
-
- Write:
SelectedProduct = Products[0];
- engine?.Globals.SetValString("StationState.ProductModel", 1, Products[0].Name);
-
RefershUI();
}
+ }
+
+ private bool WriteConfig(string name, bool value)
+ {
+ //IniFileHelper.WriteIniData("Config", name, value.ToString(), CountIniPath);
+ try
+ {
+ if (ParameterManager.UpdateCommonParameter(name, value, out string errMsg))
+ {
+ SequenceContext?.StationGlobals.SetValBoolean($"SystemSetting.{name}", 1, value);
+ return true;
+ }
+ else
+ {
+ throw new Exception(errMsg);
+ }
+ }
+ catch (Exception ex)
+ {
+ MsgBoxHelper2.Error(ex.Message);
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// 璇诲彇閰嶇疆鏂囦欢閲岀殑鍑犱釜灞炴��
+ /// </summary>
+ /// <param name="pass"></param>
+ /// <param name="fail"></param>
+ private void ReadConfig()
+ {
+ ParameterData value;
+ try
+ {
+ value = ParameterManager.GetCommonParameterByName("EnableMes");
+ _enableMes = bool.Parse(value.Value);
+ Set("EnableMes");
+ }
+ catch
+ {
+ _enableMes = false;
+ Set("EnableMes");
+ }
+
+ //try
+ //{
+ // value = ParameterManager.GetCommonParameterByName("EnableNGPause");
+ // _enableNGPause = bool.Parse(value.Value);
+ // Set("EnableNGPause");
+ //}
+ //catch
+ //{
+ // _enableNGPause = false;
+ // Set("EnableNGPause");
+ //}
+
+ //try
+ //{
+ // value = ParameterManager.GetCommonParameterByName("EnableCanLog");
+ // _enableCanLog = bool.Parse(value.Value);
+ // Set("EnableCanLog");
+ //}
+ //catch
+ //{
+ // _enableCanLog = false;
+ // Set("EnableCanLog");
+ //}
+
+ //try
+ //{
+ // value = ParameterManager.GetCommonParameterByName("EnableDebugMode");
+ // _enableDebugMode = bool.Parse(value.Value);
+ // Set("EnableDebugMode");
+ //}
+ //catch
+ //{
+ // _enableDebugMode = false;
+ // Set("EnableDebugMode");
+ //}
+
+ //try
+ //{
+ // value = ParameterManager.GetCommonParameterByName("EnableSimpleMode");
+ // EnableSimpleMode = bool.Parse(value.Value);
+ //}
+ //catch
+ //{
+ // EnableSimpleMode = false;
+ //}
+
+ //try
+ //{
+ // value = ParameterManager.GetCommonParameterByName("UI_ShowInfoDock");
+ // UI_ShowInfoDock = bool.Parse(value.Value);
+ //}
+ //catch
+ //{
+ // UI_ShowInfoDock = false;
+ //}
+
+ //try
+ //{
+
+ // value = ParameterManager.GetCommonParameterByName("TestReportFolder");
+ // csvDir = value.Value;
+ // if (!Directory.Exists(csvDir))
+ // {
+ // Directory.CreateDirectory(csvDir);
+ // }
+ //}
+ //catch
+ //{
+ // csvDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TestReport");
+ //}
}
#region 鎵爜鏋浉鍏�
@@ -203,7 +329,10 @@
catch (Exception ex)
{
log.Error("Init Scan Gun Failed.", ex);
- MsgBoxHelper.Error(this, $"{this.lang("Tr.InitGunFailed")}: {ex.StackTrace}");
+ Dispatcher.Invoke(() =>
+ {
+ MsgBoxHelper.Error(this, $"{this.lang("Tr.InitGunFailed")}: {ex.StackTrace}");
+ });
}
}
private string ReadDataFrom(SerialPort sp)
@@ -343,7 +472,10 @@
catch (Exception ex)
{
log.Error("TsExecution Loaded Failed.", ex);
- MsgBoxHelper.Error(this, $"{LangUtil.Get("Ts.UserControlLoadFailed")}: {ex.Message}");
+ Dispatcher.Invoke(() =>
+ {
+ MsgBoxHelper.Error(this, $"{LangUtil.Get("Ts.UserControlLoadFailed")}: {ex.Message}");
+ });
}
Dispatcher.Invoke(() =>
{
@@ -362,6 +494,8 @@
try
{
if (!isLoadOk) return;
+ engine?.Globals.SetValString("StationState.ProductModel", 1, SelectedProduct?.Name);
+ 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);
this.execution = this.engine.NewExecution(this.testSeq, "Test UUTs", this.modeSeq, false, 0, null, null, null);
diff --git a/Plugin.SeqEditor/AssemblyInfo.cs b/Plugin.SeqEditor/AssemblyInfo.cs
new file mode 100644
index 0000000..cc29e7f
--- /dev/null
+++ b/Plugin.SeqEditor/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.SeqEditor/Constant/DefaultStepName.cs b/Plugin.SeqEditor/Constant/DefaultStepName.cs
new file mode 100644
index 0000000..8c1c992
--- /dev/null
+++ b/Plugin.SeqEditor/Constant/DefaultStepName.cs
@@ -0,0 +1,12 @@
+锘縩amespace Plugin.SeqEditor.Constant
+{
+ public abstract class DefaultStepName
+ {
+ public const string PassFailTest = "Pass/Fail Test";
+ public const string NumericLimitTest = "Numeric Limit Test";
+ public const string NI_MultipleNumericLimitTest = "Multiple Numeric Limit Test";
+ public const string StringValueTest = "String Value Test";
+
+ public const string Action = "Action";
+ }
+}
diff --git a/Plugin.SeqEditor/Constant/StepTypeStr.cs b/Plugin.SeqEditor/Constant/StepTypeStr.cs
new file mode 100644
index 0000000..4b6b28b
--- /dev/null
+++ b/Plugin.SeqEditor/Constant/StepTypeStr.cs
@@ -0,0 +1,24 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Plugin.SeqEditor.Constant
+{
+ public abstract class StepTypeStr
+ {
+ public const string PassFailTest = "PassFailTest";
+ public const string NumericLimitTest = "NumericLimitTest";
+ public const string NI_MultipleNumericLimitTest = "NI_MultipleNumericLimitTest";
+ public const string StringValueTest = "StringValueTest";
+
+ public const string NI_Wait = "NI_Wait";
+
+
+ public const string Action = "Action";
+ public const string SequenceCall = "SequenceCall";
+
+
+ }
+}
diff --git a/Plugin.SeqEditor/Entity/EditablePO/IEPO.cs b/Plugin.SeqEditor/Entity/EditablePO/IEPO.cs
new file mode 100644
index 0000000..dc06dfd
--- /dev/null
+++ b/Plugin.SeqEditor/Entity/EditablePO/IEPO.cs
@@ -0,0 +1,46 @@
+锘縰sing CommunityToolkit.Mvvm.ComponentModel;
+
+namespace Plugin.SeqEditor.Entity.EditablePO
+{
+ public class BaseEPO : ObservableObject
+ {
+ public StepUI StepUI { get; protected set; }
+
+
+ public string StepName
+ {
+ get => StepUI?.Name;
+ set
+ {
+ if (StepUI != null)
+ {
+ StepUI.Name = value;
+ OnPropertyChanged(nameof(StepName));
+ }
+ }
+ }
+ public string StepType
+ {
+ get => StepUI?.Type;
+ }
+
+ public string RunMode
+ {
+ get => StepUI?.RunMode;
+ set
+ {
+ if (StepUI != null)
+ {
+ StepUI.RunMode = value;
+ OnPropertyChanged(nameof(RunMode));
+ }
+ }
+ }
+
+ public virtual void CustomPropertyChanged(string name)
+ {
+ OnPropertyChanged(name);
+ //StepUI?.UpdatePropertyChanged("Description");
+ }
+ }
+}
diff --git a/Plugin.SeqEditor/Entity/EditablePO/NumValTestEPO.cs b/Plugin.SeqEditor/Entity/EditablePO/NumValTestEPO.cs
new file mode 100644
index 0000000..69d3272
--- /dev/null
+++ b/Plugin.SeqEditor/Entity/EditablePO/NumValTestEPO.cs
@@ -0,0 +1,57 @@
+锘縰sing CommunityToolkit.Mvvm.ComponentModel;
+using NationalInstruments.TestStand.Interop.API;
+
+namespace Plugin.SeqEditor.Entity.EditablePO
+{
+ public class NumValTestEPO : BaseEPO
+ {
+ public Step Step { get; private set; }
+ public PropertyObject PropertyObject { get; private set; }
+
+ public NumValTestEPO(StepUI stepUI)
+ {
+ StepUI = stepUI;
+ Step = stepUI?.step;
+ PropertyObject = Step?.AsPropertyObject();
+ }
+
+ public string ComparisonType
+ {
+ get => PropertyObject?.GetValString("Comp", 0);
+ set
+ {
+ if (PropertyObject != null)
+ {
+ PropertyObject.SetValString("Comp", 0, value);
+ CustomPropertyChanged(nameof(ComparisonType));
+ }
+ }
+ }
+
+ public double? Low
+ {
+ get => PropertyObject?.GetValNumber("Limits.Low", 0);
+ set
+ {
+ if (PropertyObject != null)
+ {
+ PropertyObject.SetValNumber("Limits.Low", 0, value ?? 0);
+ CustomPropertyChanged(nameof(Low));
+ }
+ }
+ }
+
+ public double? High
+ {
+ get => PropertyObject?.GetValNumber("Limits.High", 0);
+ set
+ {
+ if (PropertyObject != null)
+ {
+ PropertyObject.SetValNumber("Limits.High", 0, value ?? 0);
+ CustomPropertyChanged(nameof(Low));
+ }
+ }
+ }
+ }
+}
diff --git a/Plugin.SeqEditor/Entity/EditablePO/StringValTestEPO.cs b/Plugin.SeqEditor/Entity/EditablePO/StringValTestEPO.cs
new file mode 100644
index 0000000..352448b
--- /dev/null
+++ b/Plugin.SeqEditor/Entity/EditablePO/StringValTestEPO.cs
@@ -0,0 +1,66 @@
+锘縰sing CommunityToolkit.Mvvm.ComponentModel;
+using NationalInstruments.TestStand.Interop.API;
+
+namespace Plugin.SeqEditor.Entity.EditablePO
+{
+
+ public class StringValTestEPO : BaseEPO
+ {
+ public Step Step { get; private set; }
+ public PropertyObject PropertyObject { get; private set; }
+
+ public StringValTestEPO(StepUI stepUI)
+ {
+ StepUI = stepUI;
+ Step = StepUI?.step;
+ PropertyObject = Step?.AsPropertyObject();
+ }
+
+ public string ComparisonType
+ {
+ get => PropertyObject?.GetValString("Comp", 0);
+ set
+ {
+ if (PropertyObject != null)
+ {
+ PropertyObject.SetValString("Comp", 0, value);
+ CustomPropertyChanged(nameof(ComparisonType));
+ }
+ }
+ }
+
+ public bool IsReadOnly
+ {
+ get
+ {
+ if (PropertyObject == null) return false;
+ bool flag = PropertyObject.GetValBoolean("Limits.UseStringExpr", 0);
+ return flag == true;
+ }
+ }
+
+ public string StringValue
+ {
+ get
+ {
+ if (PropertyObject == null) return null;
+ var value = PropertyObject.GetValString("Limits.String", 0);
+ if (string.IsNullOrEmpty(value))
+ {
+ value = PropertyObject.GetValString("Limits.StringExpr", 0);
+ }
+ return value;
+ }
+ set
+ {
+ if (PropertyObject != null)
+ {
+ PropertyObject.SetValString("Limits.String", 0, value);
+ PropertyObject.SetValString("Limits.StringExpr", 0, null);
+ PropertyObject.SetValBoolean("Limits.UseStringExpr", 0, false);
+ CustomPropertyChanged(nameof(StringValue));
+ }
+ }
+ }
+ }
+}
diff --git a/Plugin.SeqEditor/Entity/EditablePO/WaitEPO.cs b/Plugin.SeqEditor/Entity/EditablePO/WaitEPO.cs
new file mode 100644
index 0000000..0bb84e7
--- /dev/null
+++ b/Plugin.SeqEditor/Entity/EditablePO/WaitEPO.cs
@@ -0,0 +1,37 @@
+锘縰sing NationalInstruments.TestStand.Interop.API;
+
+namespace Plugin.SeqEditor.Entity.EditablePO
+{
+ public class WaitEPO : BaseEPO
+ {
+ public Step Step { get; private set; }
+ public PropertyObject PropertyObject { get; private set; }
+
+ public WaitEPO(StepUI stepUI)
+ {
+ StepUI = stepUI;
+ Step = StepUI?.step;
+ PropertyObject = Step?.AsPropertyObject();
+ }
+
+ public string TimeInterval
+ {
+ get
+ {
+ //var str = PropertyObject?.GetValString("TimeExpr", 0);
+ //if (string.IsNullOrEmpty(str)) return null;
+ //double.TryParse(str, out double value);
+ //return value;
+ return PropertyObject?.GetValString("TimeExpr", 0);
+ }
+ set
+ {
+ if (PropertyObject != null)
+ {
+ PropertyObject.SetValString("TimeExpr", 0, value?.ToString());
+ CustomPropertyChanged(nameof(TimeInterval));
+ }
+ }
+ }
+ }
+}
diff --git a/Plugin.SeqEditor/Entity/SeqUI.cs b/Plugin.SeqEditor/Entity/SeqUI.cs
new file mode 100644
index 0000000..c008960
--- /dev/null
+++ b/Plugin.SeqEditor/Entity/SeqUI.cs
@@ -0,0 +1,27 @@
+锘縰sing CommunityToolkit.Mvvm.ComponentModel;
+using NationalInstruments.TestStand.Interop.API;
+
+namespace Plugin.SeqEditor.Entity
+{
+ public partial class SeqUI : ObservableObject
+ {
+ public Sequence sequence { get; private set; }
+ public SeqUI(Sequence sequence)
+ {
+ this.sequence = sequence;
+ }
+
+ public string Name
+ {
+ get => sequence?.Name;
+ set
+ {
+ if (sequence != null)
+ {
+ sequence.Name = value;
+ OnPropertyChanged(Name);
+ }
+ }
+ }
+ }
+}
diff --git a/Plugin.SeqEditor/Entity/StepUI.cs b/Plugin.SeqEditor/Entity/StepUI.cs
new file mode 100644
index 0000000..79f71b0
--- /dev/null
+++ b/Plugin.SeqEditor/Entity/StepUI.cs
@@ -0,0 +1,91 @@
+锘縰sing CommunityToolkit.Mvvm.ComponentModel;
+using NationalInstruments.TestStand.Interop.API;
+using System.Collections.ObjectModel;
+
+namespace Plugin.SeqEditor.Entity
+{
+ public partial class StepUI : ObservableObject
+ {
+ public Step step { get; private set; }
+
+ public StepUI(Step step)
+ {
+ this.step = step;
+ }
+
+ public void UpdatePropertyChanged(string name)
+ {
+ OnPropertyChanged(name);
+ }
+
+ public string Name
+ {
+ get => step?.Name;
+ set
+ {
+ if (step != null)
+ {
+ step.Name = value;
+ OnPropertyChanged(nameof(Name));
+ }
+ }
+ }
+
+ public string Description
+ {
+ get => step?.Description;
+ }
+
+ public string RunMode
+ {
+ get => step?.GetRunModeEx();
+ set
+ {
+ if (step != null)
+ {
+ step.SetRunModeEx(value);
+ OnPropertyChanged(nameof(RunMode));
+ }
+ }
+ }
+
+ public string Type
+ {
+ get => step?.StepType?.Name;
+ }
+
+ public bool CanChangeAdapter
+ {
+ get => step?.CanChangeAdapter() ?? true;
+ }
+
+ public string Adapter
+ {
+ get => step?.AdapterKeyName;
+ set
+ {
+ if (step != null)
+ {
+ step.ChangeAdapter(value);
+ OnPropertyChanged(nameof(RunMode));
+ }
+ }
+ }
+
+
+
+ public StepGroups? StepGroup
+ {
+ get
+ {
+ return step?.StepGroup;
+ }
+ }
+
+ [ObservableProperty]
+ private string group;
+
+ [ObservableProperty]
+ public ObservableCollection<StepUI> children = new();
+ }
+}
diff --git a/Plugin.SeqEditor/Entity/VarUI.cs b/Plugin.SeqEditor/Entity/VarUI.cs
new file mode 100644
index 0000000..c050503
--- /dev/null
+++ b/Plugin.SeqEditor/Entity/VarUI.cs
@@ -0,0 +1,58 @@
+锘縰sing CommunityToolkit.Mvvm.ComponentModel;
+using NationalInstruments.TestStand.Interop.API;
+using Plugin.SeqEditor.Util;
+using System.Collections.ObjectModel;
+
+namespace Plugin.SeqEditor.Entity
+{
+ public partial class VarUI : ObservableObject
+ {
+ private string prefix;
+ private PropertyObject propertyObject;
+
+ public VarUI(PropertyObject po)
+ {
+ this.propertyObject = po;
+ }
+
+ [ObservableProperty]
+ private ObservableCollection<VarUI> subProperties = new ObservableCollection<VarUI>();
+
+ public string Name
+ {
+ get => propertyObject?.Name;
+ set
+ {
+ if (propertyObject != null)
+ {
+ propertyObject.Name = value;
+ OnPropertyChanged(Name);
+ }
+ }
+ }
+
+ public string Value
+ {
+ get => propertyObject?.GetValueString();
+ set
+ {
+ propertyObject?.SetValueString(value);
+ }
+ }
+
+ public PropertyValueTypes? Type
+ {
+ get => propertyObject?.Type?.ValueType;
+ }
+
+ public PropertyValueTypes? ElementType
+ {
+ get => propertyObject?.Type?.ElementType?.ValueType;
+ }
+
+ public string DisplayString
+ {
+ get => propertyObject?.Type.DisplayString;
+ }
+ }
+}
diff --git a/Plugin.SeqEditor/Plugin.SeqEditor.csproj b/Plugin.SeqEditor/Plugin.SeqEditor.csproj
new file mode 100644
index 0000000..87fbf68
--- /dev/null
+++ b/Plugin.SeqEditor/Plugin.SeqEditor.csproj
@@ -0,0 +1,33 @@
+锘�<Project Sdk="Microsoft.NET.Sdk">
+ <PropertyGroup>
+ <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="..\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>
+ <ItemGroup>
+ <Reference Include="NationalInstruments.TestStand.Interop.AdapterAPI">
+ <HintPath>..\..\..\..\Program Files\National Instruments\TestStand 2020\API\DotNET\Assemblies\CurrentVersion\NationalInstruments.TestStand.Interop.AdapterAPI.dll</HintPath>
+ </Reference>
+ <Reference Include="NationalInstruments.TestStand.Interop.API">
+ <HintPath>..\..\..\..\Program Files\National Instruments\TestStand 2020\API\DotNET\Assemblies\CurrentVersion\NationalInstruments.TestStand.Interop.API.dll</HintPath>
+ </Reference>
+ <Reference Include="NationalInstruments.TestStand.Interop.UI.Support">
+ <HintPath>..\..\..\..\Program Files\National Instruments\TestStand 2020\API\DotNET\Assemblies\CurrentVersion\NationalInstruments.TestStand.Interop.UI.Support.dll</HintPath>
+ </Reference>
+ </ItemGroup>
+</Project>
diff --git a/Plugin.SeqEditor/SeqEditor.xaml b/Plugin.SeqEditor/SeqEditor.xaml
new file mode 100644
index 0000000..173f331
--- /dev/null
+++ b/Plugin.SeqEditor/SeqEditor.xaml
@@ -0,0 +1,254 @@
+锘�<hb:PluginControl x:Class="Plugin.SeqEditor.SeqEditor"
+ 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"
+ 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"
+xmlns:util="clr-namespace:Plugin.SeqEditor.Util"
+ xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
+ d:DesignHeight="450" d:DesignWidth="800">
+ <i:Interaction.Triggers>
+ <i:EventTrigger EventName="Loaded">
+ <i:InvokeCommandAction Command="{Binding LoadedCommand}" />
+ </i:EventTrigger>
+ </i:Interaction.Triggers>
+ <UserControl.Resources>
+ <ResourceDictionary>
+ <ResourceDictionary.MergedDictionaries>
+ <ResourceDictionary Source="/HMI.UI;component/Controls/TreeGrid/Themes/TreeItemContentControl.xaml"/>
+ <ResourceDictionary Source="/HMI.UI;component/Controls/TreeGrid/Themes/TreeGrid.xaml"/>
+ </ResourceDictionary.MergedDictionaries>
+
+ <Style TargetType="pu:FormGroup">
+ <Setter Property="Padding" Value="0,10"/>
+ <Setter Property="HeaderFontSize" Value="14"/>
+ <Setter Property="HeaderFontWeight" Value="Bold"/>
+ </Style>
+
+ <!-- 鏍慓rid缁勪欢 -->
+ <ui:TreeItemDataConverter x:Key="TreeItemDataConverter"/>
+
+ <CollectionViewSource x:Key="TreeGridFilter"
+ Source="{Binding AllSteps,Converter={StaticResource TreeItemDataConverter},ConverterParameter=Children}">
+ <CollectionViewSource.GroupDescriptions>
+ <PropertyGroupDescription PropertyName="Data.Group" />
+ </CollectionViewSource.GroupDescriptions>
+ </CollectionViewSource>
+
+ </ResourceDictionary>
+ </UserControl.Resources>
+ <Border Style="{StaticResource CardBoarder}" Padding="0">
+ <Grid dp:GridHelper.Space="10" Cursor="">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition/>
+ </Grid.RowDefinitions>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="0"/>
+ <ColumnDefinition Width="8*"/>
+ <ColumnDefinition Width="2*"/>
+ </Grid.ColumnDefinitions>
+
+ <DockPanel Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3" Margin="0,0,0,10">
+ <StackPanel DockPanel.Dock="Right" Orientation="Horizontal"
+ dp:StackPanelHelper.ChildSpace="10">
+ <Button Style="{StaticResource AddBtn}" Content="{DynamicResource se.open}" Command="{Binding OpenSeqFileCommand}"/>
+ <Button Style="{StaticResource SaveBtn}" Content="{DynamicResource se.save}" Command="{Binding SaveSeqFileCommand}"/>
+ <Button Style="{StaticResource SaveBtn}" pu:ButtonHelper.Icon=""
+ Content="{DynamicResource se.saveTo}"
+ Command="{Binding SaveSeqFileCommand}"/>
+ <Button Style="{StaticResource DelBtn}" Content="{DynamicResource se.close}"
+ pu:ButtonHelper.Icon=""
+ Command="{Binding CloseSeqFileCommand}"/>
+ </StackPanel>
+
+ <TextBlock DockPanel.Dock="Left" FontSize="{StaticResource TitleFontSize}"
+ VerticalAlignment="Center" HorizontalAlignment="Left" Text="{DynamicResource se.title}"/>
+
+ <TextBlock DockPanel.Dock="Left" FontSize="{StaticResource ContentFontSize2}"
+ Margin="20,0,0,0"
+VerticalAlignment="Bottom" LineHeight="{StaticResource TitleFontSize}" HorizontalAlignment="Left" Text="{Binding CurrentFileName}"/>
+ </DockPanel>
+
+ <!--<pu:FormGroup Header="{DynamicResource se.seq}" Orientation="Vertical" Grid.Row="1" Grid.Column="0">
+ <DataGrid ItemsSource="{Binding Sequences}" SelectedItem="{Binding CurrentSeqUI}">
+ <DataGrid.Columns>
+ <DataGridTextColumn Width="*" Binding="{Binding Name}">
+ <DataGridTextColumn.Header>
+ <TextBlock Text="{DynamicResource se.name}"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>
+ </DataGrid.Columns>
+ </DataGrid>
+ </pu:FormGroup>-->
+ <pu:FormGroup Grid.Row="1" Grid.Column="1" Header="姝ラ绫诲瀷" Style="{StaticResource InputFormGroupStyle}">
+ <StackPanel Orientation="Horizontal">
+
+ <!--<ComboBox Text="{Binding TargetType}"
+ MinWidth="180" Margin="0,0,10,0" x:Name="CbFilter"
+ SelectedValuePath="DataValue" IsEditable="True" >
+ <ComboBox.ItemTemplate>
+ <DataTemplate DataType="util:ItemData">
+ <StackPanel Orientation="Horizontal">
+ <CheckBox IsChecked="{Binding IsChecked}" />
+ <TextBlock Text="{Binding DisplayName}" />
+ </StackPanel>
+ </DataTemplate>
+ </ComboBox.ItemTemplate>
+ </ComboBox>-->
+
+ <ui:MultiComboBox SelectedValues="{Binding TargetType}"
+ Style="{StaticResource FormComboxStyle}"
+ pu:ComboBoxHelper.ClearButtonVisibility="Collapsed"
+ MinWidth="180" Margin="0,0,10,0" x:Name="CbFilter" IsEditable="True" IsReadOnly="True" >
+ <ui:MultiComboBox.ItemTemplate>
+ <DataTemplate DataType="util:ItemData">
+ <StackPanel Orientation="Horizontal">
+ <CheckBox IsChecked="{Binding IsChecked,UpdateSourceTrigger=PropertyChanged}" />
+ <TextBlock Text="{Binding DisplayName}" />
+ </StackPanel>
+ </DataTemplate>
+ </ui:MultiComboBox.ItemTemplate>
+ </ui:MultiComboBox>
+
+ <!--<ComboBox Style="{StaticResource FormComboxStyle}" MinWidth="180" Margin="0,0,10,0" x:Name="CbFilter"/>-->
+
+ <Button Style="{StaticResource RfhBtn}" Command="{Binding RefreshCommand}"/>
+ </StackPanel>
+ </pu:FormGroup>
+
+
+ <pu:FormGroup Header="{Binding CurrentSeqTitle}" Orientation="Vertical" Grid.Row="2" Grid.Column="1">
+ <!--<DataGrid ItemsSource="{Binding Source={StaticResource cvs}}"
+ RowStyle="{StaticResource StepRow}"
+ SelectedItem="{Binding CurrentStepUI}">
+ <DataGrid.GroupStyle>
+ <GroupStyle>
+ <GroupStyle.Panel>
+ <ItemsPanelTemplate>
+ <DataGridRowsPresenter/>
+ </ItemsPanelTemplate>
+ </GroupStyle.Panel>
+ <GroupStyle.ContainerStyle>
+ <Style TargetType="{x:Type GroupItem}" BasedOn="{StaticResource DataGridGroupStyle}"/>
+ </GroupStyle.ContainerStyle>
+ </GroupStyle>
+ </DataGrid.GroupStyle>
+
+ <DataGrid.Columns>
+ <DataGridTextColumn Width="2*" Binding="{Binding Name}">
+ <DataGridTextColumn.Header>
+ <TextBlock Text="{DynamicResource se.name}"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>
+
+ <DataGridTextColumn Width="1*" Binding="{Binding Type}">
+ <DataGridTextColumn.Header>
+ <TextBlock Text="{DynamicResource se.name}"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>
+
+ <DataGridTextColumn Width="6*" Binding="{Binding Description}">
+ <DataGridTextColumn.Header>
+ <TextBlock Text="{DynamicResource se.description}"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>
+
+ <DataGridTemplateColumn Width="1*">
+ <DataGridTemplateColumn.Header>
+ <TextBlock Text="{DynamicResource se.runMode}"/>
+ </DataGridTemplateColumn.Header>
+ <DataGridTemplateColumn.CellTemplate>
+ <DataTemplate>
+ <Grid x:Name="border" Margin="0">
+ <TextBlock x:Name="text" Margin="-1" Padding="0" VerticalAlignment="Center"/>
+ </Grid>
+ <DataTemplate.Triggers>
+ <DataTrigger Binding="{Binding RunMode}" Value="Normal">
+ <Setter TargetName="text" Property="Text" Value="{DynamicResource se.normal}"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding RunMode}" Value="Skip">
+ <Setter TargetName="text" Property="Text" Value="{DynamicResource se.skip}"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding RunMode}" Value="Pass">
+ <Setter TargetName="text" Property="Text" Value="{DynamicResource se.pass}"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding RunMode}" Value="Fail">
+ <Setter TargetName="text" Property="Text" Value="{DynamicResource se.fail}"/>
+ </DataTrigger>
+ </DataTemplate.Triggers>
+ </DataTemplate>
+ </DataGridTemplateColumn.CellTemplate>
+ </DataGridTemplateColumn>
+ </DataGrid.Columns>
+ ItemsSource="{Binding AllSteps,Converter={StaticResource treeC}}"
+ </DataGrid>-->
+
+ <ui:TreeDataGrid Grid.Row="1" x:Name="treeDataGrid"
+ VirtualizingPanel.IsContainerVirtualizable="True"
+ VirtualizingPanel.IsVirtualizing="True"
+ VirtualizingPanel.VirtualizationMode="Recycling"
+ ScrollViewer.CanContentScroll="False"
+ VirtualizingPanel.IsVirtualizingWhenGrouping="True"
+ EnableColumnVirtualization="True"
+ EnableRowVirtualization="True"
+ PreviewMouseWheel="treeDataGrid_PreviewMouseWheel"
+ AutoGenerateColumns="False"
+ IsReadOnly="True"
+ Style="{StaticResource DefaultDataGrid}"
+ ItemsSource="{Binding Source={StaticResource TreeGridFilter}}"
+ SelectedItem="{Binding TreeItemData}">
+
+ <!--<DataGrid.GroupStyle>
+ <GroupStyle>
+ <GroupStyle.ContainerStyle>
+ <Style TargetType="{x:Type GroupItem}">
+ <Setter Property="Margin" Value="0,0,0,5" />
+ <Setter Property="Template">
+ <Setter.Value>
+ <ControlTemplate TargetType="{x:Type GroupItem}">
+ <GroupBox Header="{Binding Name}">
+ <ItemsPresenter />
+ </GroupBox>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style>
+ </GroupStyle.ContainerStyle>
+ </GroupStyle>
+ </DataGrid.GroupStyle>-->
+
+ <ui:TreeDataGrid.Columns>
+ <DataGridTemplateColumn IsReadOnly="True" Width="Auto">
+ <DataGridTemplateColumn.CellTemplate>
+ <DataTemplate>
+ <ui:TreeItemContentControl IconLineStroke="Black" TreeData="{Binding }"/>
+ </DataTemplate>
+ </DataGridTemplateColumn.CellTemplate>
+ </DataGridTemplateColumn>
+
+ <DataGridTextColumn Header="鍚嶇О" Width="1*" Binding="{Binding Data.Name}"></DataGridTextColumn>
+ <DataGridTextColumn Header="绫诲瀷" Width="1*" Binding="{Binding Data.Type}"></DataGridTextColumn>
+ <DataGridTextColumn Header="鎻忚堪" Width="7*" Binding="{Binding Data.Description}"></DataGridTextColumn>
+ <DataGridTextColumn Header="RunMode" Width="*" Binding="{Binding Data.RunMode}"></DataGridTextColumn>
+ </ui:TreeDataGrid.Columns>
+ </ui:TreeDataGrid>
+
+ </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>
+ </Grid>
+ </Border>
+</hb:PluginControl>
diff --git a/Plugin.SeqEditor/SeqEditor.xaml.cs b/Plugin.SeqEditor/SeqEditor.xaml.cs
new file mode 100644
index 0000000..94f8f87
--- /dev/null
+++ b/Plugin.SeqEditor/SeqEditor.xaml.cs
@@ -0,0 +1,70 @@
+using HMI.Base;
+using HMI.UI;
+using Panuon.WPF.UI;
+using Plugin.SeqEditor.Util;
+using Plugin.SeqEditor.ViewModel;
+using System.Windows;
+using System.Windows.Data;
+using System.Windows.Input;
+
+namespace Plugin.SeqEditor;
+
+/// <summary>
+/// Interaction logic for UserControl1.xaml
+/// </summary>
+public partial class SeqEditor : PluginControl
+{
+ public SeqEditor()
+ {
+ InitializeComponent();
+ CbFilter.ItemsSource = (IEnumerable<MultiComboBoxData>)
+ new MultiComboBoxDataConverter().Convert(FilterTypeData.ItemSource,
+ null,null,null
+ );
+ }
+
+ public override void InitFinish()
+ {
+ this.DataContext = new SeqEditorViewModel(this, log);
+ }
+
+ public void BackgroundAction(Action action, string message)
+ {
+ new MaskWindow((WindowX)Window.GetWindow(this),
+ (win) =>
+ {
+ action?.Invoke();
+ }
+ ).Info(message);
+ }
+
+ /// <summary>
+ /// 树数据展示过滤
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e"></param>
+ private void CollectionViewSource_Filter(object sender, FilterEventArgs e)
+ {
+ if (e.Item is TreeItemData data)
+ {
+ e.Accepted = data.IsVisible;
+ }
+ }
+
+ // <summary>
+ /// 树展开/关闭事件
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e"></param>
+ private void treeDataGrid_ExpandedChange(object sender, bool e)
+ {
+ //CollectionViewSource cvs = this.Resources["TreeGridFilter"] as CollectionViewSource;
+ //cvs?.View.Refresh();
+ }
+
+ private void treeDataGrid_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
+ {
+ e.Handled = false;
+ }
+}
+
diff --git a/Plugin.SeqEditor/SettingPanel/ActionPanel.xaml b/Plugin.SeqEditor/SettingPanel/ActionPanel.xaml
new file mode 100644
index 0000000..0d51042
--- /dev/null
+++ b/Plugin.SeqEditor/SettingPanel/ActionPanel.xaml
@@ -0,0 +1,45 @@
+锘�<UserControl x:Class="Plugin.SeqEditor.SettingPanel.ActionPanel"
+ 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"
+ d:DesignHeight="450" d:DesignWidth="800">
+ <Grid>
+ <StackPanel>
+ <pu:FormGroup Header="{DynamicResource se.stepName}" Orientation="Vertical"
+ Style="{StaticResource InputFormGroupStyle}">
+ <TextBox IsReadOnly="True" Style="{StaticResource EditorTextBoxStyle}" Text="{Binding Name}" />
+ </pu:FormGroup>
+
+ <pu:FormGroup Header="{DynamicResource se.stepType}" Orientation="Vertical"
+ Style="{StaticResource InputFormGroupStyle}">
+ <TextBox IsReadOnly="True" Style="{StaticResource EditorTextBoxStyle}" Text="{Binding Type,Mode=OneWay}" />
+ </pu:FormGroup>
+
+ <pu:FormGroup Header="{DynamicResource se.runMode}" Orientation="Vertical"
+ Style="{StaticResource InputFormGroupStyle}">
+
+ <ComboBox x:Name="CbRunMode" Style="{StaticResource FormComboxStyle}"
+ VirtualizingPanel.IsVirtualizing="True"
+ SelectedValue="{Binding RunMode}"
+ DisplayMemberPath="DisplayName" SelectedValuePath="DataValue"/>
+ </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/ActionPanel.xaml.cs b/Plugin.SeqEditor/SettingPanel/ActionPanel.xaml.cs
new file mode 100644
index 0000000..2fd2076
--- /dev/null
+++ b/Plugin.SeqEditor/SettingPanel/ActionPanel.xaml.cs
@@ -0,0 +1,39 @@
+锘縰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 ActionPanel : UserControl
+ {
+ public event EventHandler SettingChanged;
+
+ public StepUI stepUI;
+ public Step step;
+ public PropertyObject propertyObject;
+
+ protected void CustomPropertyChanged(string name)
+ {
+ OnPropertyChanged(name);
+ SettingChanged?.Invoke(this, EventArgs.Empty);
+ }
+
+ public ActionPanel(StepUI stepUI)
+ {
+ this.stepUI = stepUI;
+ this.step = stepUI.step;
+ propertyObject = this.step?.AsPropertyObject();
+ this.DataContext = stepUI;
+ InitializeComponent();
+ CbRunMode.ItemsSource = RunModeData.ItemSource;
+ //CbAdapter.ItemsSource = StepAdapterData.ItemSource;
+ }
+ }
+}
diff --git a/Plugin.SeqEditor/SettingPanel/CommonProperty.xaml b/Plugin.SeqEditor/SettingPanel/CommonProperty.xaml
new file mode 100644
index 0000000..2c44659
--- /dev/null
+++ b/Plugin.SeqEditor/SettingPanel/CommonProperty.xaml
@@ -0,0 +1,25 @@
+锘�<UserControl x:Class="Plugin.SeqEditor.SettingPanel.CommonProperty"
+ 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"
+ d:DesignHeight="450" d:DesignWidth="800">
+ <Grid>
+ <StackPanel>
+ <Label>Name</Label>
+ <TextBox Text="{Binding Name}"/>
+
+ <Label>Type</Label>
+ <TextBox IsEnabled="False" Text="{Binding Type,Mode=OneWay}"/>
+
+ <Label>Adapter</Label>
+ <ComboBox x:Name="CbAdapter"
+ IsEnabled="{Binding CanChangeAdapter}"
+ SelectedValue="{Binding Adapter}"
+ DisplayMemberPath="DisplayName" SelectedValuePath="DataValue"/>
+ </StackPanel>
+
+ </Grid>
+</UserControl>
diff --git a/Plugin.SeqEditor/SettingPanel/CommonProperty.xaml.cs b/Plugin.SeqEditor/SettingPanel/CommonProperty.xaml.cs
new file mode 100644
index 0000000..deaed82
--- /dev/null
+++ b/Plugin.SeqEditor/SettingPanel/CommonProperty.xaml.cs
@@ -0,0 +1,45 @@
+锘縰sing CommunityToolkit.Mvvm.ComponentModel;
+using NationalInstruments.TestStand.Interop.API;
+using System.ComponentModel;
+using System.Windows.Controls;
+using Plugin.SeqEditor.Constant;
+using Plugin.SeqEditor.Entity;
+using Plugin.SeqEditor.Util;
+
+namespace Plugin.SeqEditor.SettingPanel
+{
+ /// <summary>
+ /// CommonProperty.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ [INotifyPropertyChanged]
+ public partial class CommonProperty : UserControl
+ {
+ public event EventHandler SettingChanged;
+
+ public StepUI stepUI;
+ public Step step;
+ public PropertyObject propertyObject;
+
+ protected void CustomPropertyChanged(string name)
+ {
+ OnPropertyChanged(name);
+ SettingChanged?.Invoke(this, EventArgs.Empty);
+ }
+
+ public CommonProperty()
+ {
+ DataContext = this;
+ InitializeComponent();
+ CbAdapter.ItemsSource = StepAdapterData.ItemSource;
+ }
+
+ public void RefreshStep(StepUI stepUI)
+ {
+ this.stepUI = stepUI;
+ this.step = stepUI.step;
+ propertyObject = this.step?.AsPropertyObject();
+ this.DataContext = stepUI;
+ }
+
+ }
+}
diff --git a/Plugin.SeqEditor/SettingPanel/NumValTestPanel.xaml b/Plugin.SeqEditor/SettingPanel/NumValTestPanel.xaml
new file mode 100644
index 0000000..24016dd
--- /dev/null
+++ b/Plugin.SeqEditor/SettingPanel/NumValTestPanel.xaml
@@ -0,0 +1,50 @@
+锘�<UserControl x:Class="Plugin.SeqEditor.SettingPanel.NumValTestPanel"
+ 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"
+
+ Padding="5"
+ 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"
+ d:DesignHeight="450" d:DesignWidth="800">
+ <StackPanel>
+ <pu:FormGroup Header="{DynamicResource se.runMode}"
+ Orientation="Vertical"
+ Style="{StaticResource InputFormGroupStyle}">
+
+ <ComboBox x:Name="CbRunMode"
+ Style="{StaticResource FormComboxStyle}"
+ SelectedValue="{Binding RunMode}"
+ DisplayMemberPath="DisplayName" SelectedValuePath="DataValue"/>
+ </pu:FormGroup>
+
+ <pu:FormGroup Header="{DynamicResource se.compType}"
+ Orientation="Vertical"
+ Style="{StaticResource InputFormGroupStyle}">
+
+ <ComboBox x:Name="CbType"
+ Style="{StaticResource FormComboxStyle}" SelectedValue="{Binding ComparisonType}"
+ DisplayMemberPath="DisplayName"
+ SelectedValuePath="DataValue"/>
+ </pu:FormGroup>
+
+ <pu:FormGroup Header="Low"
+Orientation="Vertical"
+Style="{StaticResource InputFormGroupStyle}">
+ <ui:NumberInput Style="{StaticResource EditorTextBoxStyle}" Text="{Binding Low}"/>
+ </pu:FormGroup>
+
+ <pu:FormGroup Header="High"
+Orientation="Vertical"
+Style="{StaticResource InputFormGroupStyle}">
+ <ui:NumberInput Style="{StaticResource EditorTextBoxStyle}" Text="{Binding High}"/>
+ </pu:FormGroup>
+ </StackPanel>
+</UserControl>
diff --git a/Plugin.SeqEditor/SettingPanel/NumValTestPanel.xaml.cs b/Plugin.SeqEditor/SettingPanel/NumValTestPanel.xaml.cs
new file mode 100644
index 0000000..e6dc157
--- /dev/null
+++ b/Plugin.SeqEditor/SettingPanel/NumValTestPanel.xaml.cs
@@ -0,0 +1,20 @@
+锘縰sing Plugin.SeqEditor.Entity.EditablePO;
+using Plugin.SeqEditor.Util;
+using System.Windows.Controls;
+
+namespace Plugin.SeqEditor.SettingPanel
+{
+ /// <summary>
+ /// NumValTestPanel.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ public partial class NumValTestPanel : UserControl
+ {
+ public NumValTestPanel(NumValTestEPO epo)
+ {
+ DataContext = epo;
+ InitializeComponent();
+ CbRunMode.ItemsSource = RunModeData.ItemSource;
+ CbType.ItemsSource = NumCompTypeData.ItemSource;
+ }
+ }
+}
diff --git a/Plugin.SeqEditor/SettingPanel/StringValTestPanel.xaml b/Plugin.SeqEditor/SettingPanel/StringValTestPanel.xaml
new file mode 100644
index 0000000..7a8c260
--- /dev/null
+++ b/Plugin.SeqEditor/SettingPanel/StringValTestPanel.xaml
@@ -0,0 +1,57 @@
+锘�<UserControl x:Class="Plugin.SeqEditor.SettingPanel.StringValTestPanel"
+ 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"
+ Padding="5"
+ 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"
+ d:DesignHeight="450" d:DesignWidth="800">
+ <StackPanel>
+ <pu:FormGroup Header="{DynamicResource se.stepName}"
+ Orientation="Vertical"
+ Style="{StaticResource InputFormGroupStyle}">
+
+ <TextBox IsReadOnly="True" Style="{StaticResource EditorTextBoxStyle}" Text="{Binding StepName}" />
+ </pu:FormGroup>
+
+ <pu:FormGroup Header="{DynamicResource se.stepType}"
+Orientation="Vertical"
+Style="{StaticResource InputFormGroupStyle}">
+
+ <TextBox IsReadOnly="True" Style="{StaticResource EditorTextBoxStyle}" Text="{Binding StepType,Mode=OneWay}" />
+ </pu:FormGroup>
+
+ <pu:FormGroup Header="{DynamicResource se.runMode}"
+ Orientation="Vertical"
+ Style="{StaticResource InputFormGroupStyle}">
+
+ <ComboBox x:Name="CbRunMode"
+ Style="{StaticResource FormComboxStyle}"
+ SelectedValue="{Binding RunMode}"
+ DisplayMemberPath="DisplayName" SelectedValuePath="DataValue"/>
+ </pu:FormGroup>
+
+ <pu:FormGroup Header="{DynamicResource se.compType}"
+ Orientation="Vertical"
+ Style="{StaticResource InputFormGroupStyle}">
+
+ <ComboBox x:Name="CbType"
+ Style="{StaticResource FormComboxStyle}" SelectedValue="{Binding ComparisonType}"
+ DisplayMemberPath="DisplayName" SelectedValuePath="DataValue"/>
+ </pu:FormGroup>
+
+ <pu:FormGroup Header="{DynamicResource se.targetVal}"
+Orientation="Vertical"
+Style="{StaticResource InputFormGroupStyle}">
+
+ <TextBox IsReadOnly="{Binding IsReadOnly}" Style="{StaticResource EditorTextBoxStyle}" Text="{Binding StringValue}"/>
+ </pu:FormGroup>
+ </StackPanel>
+</UserControl>
diff --git a/Plugin.SeqEditor/SettingPanel/StringValTestPanel.xaml.cs b/Plugin.SeqEditor/SettingPanel/StringValTestPanel.xaml.cs
new file mode 100644
index 0000000..00c015c
--- /dev/null
+++ b/Plugin.SeqEditor/SettingPanel/StringValTestPanel.xaml.cs
@@ -0,0 +1,21 @@
+锘縰sing System.Windows.Controls;
+using Plugin.SeqEditor.Entity.EditablePO;
+using Plugin.SeqEditor.Util;
+
+namespace Plugin.SeqEditor.SettingPanel
+{
+ /// <summary>
+ /// StringValueTest.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ public partial class StringValTestPanel : UserControl
+ {
+ public StringValTestPanel(StringValTestEPO data)
+ {
+ this.DataContext = data;
+ InitializeComponent();
+
+ CbRunMode.ItemsSource = RunModeData.ItemSource;
+ CbType.ItemsSource = StringCompTypeData.ItemSource;
+ }
+ }
+}
diff --git a/Plugin.SeqEditor/SettingPanel/WaitPanel.xaml b/Plugin.SeqEditor/SettingPanel/WaitPanel.xaml
new file mode 100644
index 0000000..b7f9340
--- /dev/null
+++ b/Plugin.SeqEditor/SettingPanel/WaitPanel.xaml
@@ -0,0 +1,48 @@
+锘�<UserControl x:Class="Plugin.SeqEditor.SettingPanel.WaitPanel"
+ 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"
+ d:DesignHeight="450" d:DesignWidth="800">
+ <StackPanel>
+ <pu:FormGroup Header="{DynamicResource se.stepName}"
+ Orientation="Vertical"
+ Style="{StaticResource InputFormGroupStyle}">
+
+ <TextBox IsReadOnly="True" Style="{StaticResource EditorTextBoxStyle}" Text="{Binding StepName}" />
+ </pu:FormGroup>
+
+ <pu:FormGroup Header="{DynamicResource se.stepType}"
+ Orientation="Vertical"
+ Style="{StaticResource InputFormGroupStyle}">
+
+ <TextBox IsReadOnly="True" Style="{StaticResource EditorTextBoxStyle}" Text="{Binding StepType,Mode=OneWay}" />
+ </pu:FormGroup>
+
+ <pu:FormGroup Header="{DynamicResource se.runMode}"
+ Orientation="Vertical"
+ Style="{StaticResource InputFormGroupStyle}">
+
+ <ComboBox x:Name="CbRunMode"
+ Style="{StaticResource FormComboxStyle}"
+ SelectedValue="{Binding RunMode}"
+ DisplayMemberPath="DisplayName" SelectedValuePath="DataValue"/>
+ </pu:FormGroup>
+
+ <pu:FormGroup Header="{DynamicResource se.waitInterval}"
+ Orientation="Vertical"
+ Style="{StaticResource InputFormGroupStyle}">
+ <ui:NumberInput Style="{StaticResource EditorTextBoxStyle}"
+ Text="{Binding TimeInterval,UpdateSourceTrigger=PropertyChanged}"/>
+ </pu:FormGroup>
+ </StackPanel>
+</UserControl>
diff --git a/Plugin.SeqEditor/SettingPanel/WaitPanel.xaml.cs b/Plugin.SeqEditor/SettingPanel/WaitPanel.xaml.cs
new file mode 100644
index 0000000..31abae1
--- /dev/null
+++ b/Plugin.SeqEditor/SettingPanel/WaitPanel.xaml.cs
@@ -0,0 +1,19 @@
+锘縰sing Plugin.SeqEditor.Entity.EditablePO;
+using Plugin.SeqEditor.Util;
+using System.Windows.Controls;
+
+namespace Plugin.SeqEditor.SettingPanel
+{
+ /// <summary>
+ /// WaitPanel.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ public partial class WaitPanel : UserControl
+ {
+ public WaitPanel(WaitEPO epo)
+ {
+ this.DataContext = epo;
+ InitializeComponent();
+ CbRunMode.ItemsSource = RunModeData.ItemSource;
+ }
+ }
+}
diff --git a/Plugin.SeqEditor/Util/ItemData.cs b/Plugin.SeqEditor/Util/ItemData.cs
new file mode 100644
index 0000000..3b81e9c
--- /dev/null
+++ b/Plugin.SeqEditor/Util/ItemData.cs
@@ -0,0 +1,147 @@
+锘縰sing HMI.Core.Util;
+using NationalInstruments.TestStand.Interop.API;
+
+namespace Plugin.SeqEditor.Util
+{
+ public class ItemData
+ {
+ public string DisplayName { get; private set; }
+ public string DataValue { get; private set; }
+
+ public ItemData(string displayName, string dataValue)
+ {
+ this.DisplayName = displayName;
+ this.DataValue = dataValue;
+ }
+ }
+
+
+ public abstract class StringCompTypeData
+ {
+ public static readonly ItemData None =
+ new(LangUtil.Get("se.data.none"), "LOG");
+
+ public static readonly ItemData SCCS =
+ new(LangUtil.Get("se.strComp.SCCS"), "CaseSensitive");
+ public static readonly ItemData SCIC =
+ new(LangUtil.Get("se.strComp.SCIC"), "IgnoreCase");
+
+ public static readonly ItemData RECS =
+ new(LangUtil.Get("se.strComp.RECS"), "RegularExpressionCaseSensitive");
+ public static readonly ItemData REIC =
+ new(LangUtil.Get("se.strComp.REIC"), "IgnoreCase");
+
+ public static readonly List<ItemData> ItemSource =
+ new List<ItemData> {
+ None,SCCS,SCIC,//RECS,REIC
+ };
+ }
+
+ public abstract class FilterTypeData
+ {
+ public static readonly ItemData Wait =
+ new(LangUtil.Get("Wait"), "NI_Wait");
+
+ public static readonly ItemData Action =
+ new(LangUtil.Get("Action"), "Action");
+ public static readonly ItemData StrValTest =
+ new(LangUtil.Get("String Val Test"), "StringValueTest");
+
+ public static readonly ItemData NumValTest =
+ new(LangUtil.Get("Numeric Limit Test"), "NumericLimitTest");
+
+ public static readonly ItemData RECS =
+ new(LangUtil.Get("SequenceCall"), "SequenceCall");
+
+ public static readonly List<ItemData> ItemSource =
+ new List<ItemData> {
+ Wait,Action,StrValTest,//RECS,REIC
+ };
+ }
+
+ public abstract class NumCompTypeData
+ {
+
+ public static readonly ItemData EQ =
+ new("= Low", "EQ");
+ public static readonly ItemData NE =
+ new("!= Low", "NE");
+
+ public static readonly ItemData GT =
+ new("> Low", "GT");
+
+ public static readonly ItemData LT =
+ new("< Low", "LT");
+
+ public static readonly ItemData GE =
+ new(">= Low", "GE");
+
+ public static readonly ItemData LE =
+ new("<= Low", "LE");
+
+ public static readonly ItemData GTLT =
+ new("> Low锛�< High", "GTLT");
+
+ public static readonly ItemData GELE =
+ new(">=Low锛�<= High", "GELE");
+ public static readonly ItemData GELT =
+ new(">= Low锛�< High", "GELT");
+ public static readonly ItemData GTLE =
+ new("> Low锛�<= High", "GTLE");
+
+
+ public static readonly ItemData LTGT =
+ new("< Low OR > High", "LTGT");
+ public static readonly ItemData LEGE =
+ new("<= Low OR >= High", "LEGE");
+ public static readonly ItemData LEGT =
+ new("<= Low OR > High", "LEGT");
+ public static readonly ItemData LTGE =
+ new("< Low OR >= High", "LTGE");
+
+ public static readonly List<ItemData> ItemSource =
+ new List<ItemData> {
+ EQ,NE,GT,LT,GE,LE,GTLT,GELE,GELT,GTLE,LTGT,LEGE,LEGT,LTGE
+ };
+ }
+
+ public abstract class RunModeData
+ {
+ public static readonly ItemData Normal =
+ new(LangUtil.Get("se.normal"), "Normal");
+
+ public static readonly ItemData Skip =
+ new(LangUtil.Get("se.skip"), "Skip");
+
+ public static readonly ItemData ForcePass =
+ new(LangUtil.Get("se.pass"), "Pass");
+
+ public static readonly ItemData ForceFail =
+ new(LangUtil.Get("se.fail"), "Fail");
+
+ public static readonly List<ItemData> ItemSource =
+ new List<ItemData> {
+ Normal,Skip,ForcePass,ForceFail
+ };
+ }
+
+ public abstract class StepAdapterData
+ {
+ public static readonly ItemData LabView = new("LabVIEW", AdapterKeyNames.FlexLVAdapterKeyName);
+ public static readonly ItemData LabWindows = new("LabWindows/CVI",
+ AdapterKeyNames.FlexCVIAdapterKeyName);
+ public static readonly ItemData CCPlus = new("C/C++ DLL", AdapterKeyNames.FlexCAdapterKeyName);
+ public static readonly ItemData DotNet = new(".NET", AdapterKeyNames.DotNetAdapterKeyname);
+ public static readonly ItemData ActiveX = new("ActiveX/COM", AdapterKeyNames.AutomationAdapterKeyName);
+ public static readonly ItemData None = new("None", AdapterKeyNames.NoneAdapterKeyName);
+ public static readonly ItemData LabViewNGX = new("LabVIEW NXG", AdapterKeyNames.LabVIEWNXGAdapterKeyName);
+ public static readonly ItemData Python = new("Python", AdapterKeyNames.PythonAdapterKeyName);
+ public static readonly ItemData SequenceCall =
+ new("SequenceCall", AdapterKeyNames.SequenceAdapterKeyName);
+
+ public static readonly List<ItemData> ItemSource =
+ new List<ItemData> {
+ LabView,LabWindows,CCPlus,DotNet,ActiveX,None,LabViewNGX,Python,SequenceCall
+ };
+ }
+}
diff --git a/Plugin.SeqEditor/Util/PoExplain.cs b/Plugin.SeqEditor/Util/PoExplain.cs
new file mode 100644
index 0000000..3d828ff
--- /dev/null
+++ b/Plugin.SeqEditor/Util/PoExplain.cs
@@ -0,0 +1,44 @@
+锘縰sing NationalInstruments.TestStand.Interop.API;
+
+namespace Plugin.SeqEditor.Util
+{
+ public static class PoExtensions
+ {
+ public static string GetValueString(this PropertyObject po)
+ {
+ var lookUpStr = string.Empty;
+ switch (po.Type.ValueType)
+ {
+ case PropertyValueTypes.PropValType_String:
+ return po.GetValString(lookUpStr, 0);
+ case PropertyValueTypes.PropValType_Boolean:
+ return po.GetValBoolean(lookUpStr, 0).ToString();
+ case PropertyValueTypes.PropValType_Number:
+ return po.GetValNumber(lookUpStr, 0).ToString();
+ default:
+ return string.Empty;
+ }
+ }
+
+ public static void SetValueString(this PropertyObject po, string value)
+ {
+ var lookUpStr = string.Empty;
+ switch (po.Type.ValueType)
+ {
+ case PropertyValueTypes.PropValType_String:
+ po.SetValString(lookUpStr, 0, value);
+ break;
+ case PropertyValueTypes.PropValType_Boolean:
+ bool boolVal = bool.Parse(value);
+ po.SetValBoolean(lookUpStr, 0, boolVal);
+ break;
+ case PropertyValueTypes.PropValType_Number:
+ double doubleVal = double.Parse(value);
+ po.SetValNumber(lookUpStr, 0, doubleVal);
+ break;
+ default:
+ return;
+ }
+ }
+ }
+}
diff --git a/Plugin.SeqEditor/Util/Step2EPO.cs b/Plugin.SeqEditor/Util/Step2EPO.cs
new file mode 100644
index 0000000..7f3bff8
--- /dev/null
+++ b/Plugin.SeqEditor/Util/Step2EPO.cs
@@ -0,0 +1,44 @@
+锘縰sing System.Windows.Controls;
+using Plugin.SeqEditor.Constant;
+using Plugin.SeqEditor.Entity;
+using Plugin.SeqEditor.Entity.EditablePO;
+using Plugin.SeqEditor.SettingPanel;
+
+namespace Plugin.SeqEditor.Util
+{
+ public class StepUI2EPO
+ {
+ public static object Convert2EPO(StepUI step)
+ {
+ switch (step.Type)
+ {
+ case StepTypeStr.StringValueTest:
+ return new StringValTestEPO(step);
+ default:
+ return null;
+ }
+ }
+
+ public static UserControl Convert2EditPanel(StepUI step)
+ {
+ if (step == null) return null;
+ object epo;
+ switch (step.Type)
+ {
+ case StepTypeStr.StringValueTest:
+ epo = new StringValTestEPO(step);
+ return new StringValTestPanel((StringValTestEPO)epo);
+ case StepTypeStr.NI_Wait:
+ epo = new WaitEPO(step);
+ return new WaitPanel((WaitEPO)epo);
+ case StepTypeStr.NumericLimitTest:
+ epo = new NumValTestEPO(step);
+ return new NumValTestPanel((NumValTestEPO)epo);
+ case StepTypeStr.Action:
+ return new ActionPanel(step);
+ default:
+ return null;
+ }
+ }
+ }
+}
diff --git a/Plugin.SeqEditor/ViewModel/SeqEditorViewModel.cs b/Plugin.SeqEditor/ViewModel/SeqEditorViewModel.cs
new file mode 100644
index 0000000..b369169
--- /dev/null
+++ b/Plugin.SeqEditor/ViewModel/SeqEditorViewModel.cs
@@ -0,0 +1,454 @@
+锘縰sing CommunityToolkit.Mvvm.ComponentModel;
+using CommunityToolkit.Mvvm.Input;
+using HMI.Core.Util;
+using HMI.UI;
+using HMI.UI.Util;
+using log4net;
+using Microsoft.Win32;
+using NationalInstruments.TestStand.Interop.API;
+using Plugin.SeqEditor.Constant;
+using Plugin.SeqEditor.Entity;
+using Plugin.SeqEditor.Util;
+using System.Collections.ObjectModel;
+using System.IO;
+
+namespace Plugin.SeqEditor.ViewModel
+{
+
+ public partial class SeqEditorViewModel : ObservableObject
+ {
+ private ObservableCollection<StepUI> setupSteps = new ObservableCollection<StepUI>();
+
+ private ObservableCollection<StepUI> mainSteps = new ObservableCollection<StepUI>();
+
+ private ObservableCollection<StepUI> cleanupSteps = new ObservableCollection<StepUI>();
+
+ [ObservableProperty]
+ private ObservableCollection<StepUI> allSteps = new ObservableCollection<StepUI>();
+
+ [ObservableProperty]
+ private ObservableCollection<SeqUI> sequences = new ObservableCollection<SeqUI>();
+
+ [ObservableProperty]
+ private SeqUI currentSeqUI;
+
+ [ObservableProperty]
+ private StepUI currentStepUI;
+
+ [ObservableProperty]
+ private string currentFileName;
+
+ [ObservableProperty]
+ private string currentSeqTitle = LangUtil.Get("se.steps");
+
+ [ObservableProperty]
+ private string targetType = null;
+
+
+ private string currentFilePath;
+ private Engine engine;
+ private SequenceFile sequenceFile;
+ private bool isLoaded;
+ private ILog log;
+ public SeqEditor control { get; private set; }
+
+ public List<ItemData> Types = FilterTypeData.ItemSource;
+
+ private HashSet<string> edits = new HashSet<string> {
+ StepTypeStr.PassFailTest,
+ StepTypeStr.NumericLimitTest,
+ StepTypeStr.NI_MultipleNumericLimitTest,
+ StepTypeStr.StringValueTest,
+ StepTypeStr.Action,
+ StepTypeStr.NI_Wait,
+ StepTypeStr.SequenceCall,
+ };
+
+ public SeqEditorViewModel(SeqEditor control, ILog log)
+ {
+ this.log = log;
+ this.control = control;
+ engine = new Engine();
+ engine.LoadTypePaletteFilesEx();
+ }
+
+ ~SeqEditorViewModel()
+ {
+ if (engine != null)
+ {
+ if (sequenceFile != null)
+ {
+ engine.ReleaseSequenceFileEx(sequenceFile);
+ }
+ engine.ShutDown(true);
+ // 涓嶅姞寤舵椂浼氬脊绐梞d
+ System.Threading.Thread.Sleep(2500);
+ }
+ }
+
+ private ObservableCollection<StepUI> LoadSteps(Sequence seq, string group = null)
+ {
+ //setupSteps.Clear();
+ //var steps = new ObservableCollection<StepUI>();
+ //int num = seq.GetNumSteps(StepGroups.StepGroup_Setup);
+ //for (int i = 0; i < num; i++)
+ //{
+ // Step step = seq.GetStep(i, StepGroups.StepGroup_Setup);
+ // var ui = new StepUI(step);
+ // if (edits.Contains(ui.Type))
+ // {
+ // setupSteps.Add(ui);
+ // steps.Add(ui);
+ // }
+ //}
+ ////SetupSteps = steps;
+ ////steps = new ObservableCollection<StepUI>();
+ //mainSteps.Clear();
+ //num = seq.GetNumSteps(StepGroups.StepGroup_Main);
+ //for (int i = 0; i < num; i++)
+ //{
+ // Step step = seq.GetStep(i, StepGroups.StepGroup_Main);
+ // var ui = new StepUI(step);
+ // if (edits.Contains(ui.Type))
+ // {
+ // mainSteps.Add(ui);
+ // steps.Add(ui);
+ // }
+ //}
+ ////MainSteps = steps;
+ ////steps = new ObservableCollection<StepUI>();
+ //cleanupSteps.Clear();
+ //num = seq.GetNumSteps(StepGroups.StepGroup_Cleanup);
+ //for (int i = 0; i < num; i++)
+ //{
+ // Step step = seq.GetStep(i, StepGroups.StepGroup_Cleanup);
+ // var ui = new StepUI(step);
+ // if (edits.Contains(ui.Type))
+ // {
+ // cleanupSteps.Add(ui);
+ // steps.Add(ui);
+ // }
+ //}
+ //AllSteps = steps;
+ //CurrentStepUI = null;
+
+ var steps = new ObservableCollection<StepUI>();
+
+ int num = seq.GetNumSteps(StepGroups.StepGroup_Setup);
+ for (int i = 0; i < num; i++)
+ {
+ Step step = seq.GetStep(i, StepGroups.StepGroup_Setup);
+ var ui = Convert2StepUI(step, group);
+ if (ui != null)
+ {
+ steps.Add(ui);
+ }
+ }
+
+ num = seq.GetNumSteps(StepGroups.StepGroup_Main);
+ for (int i = 0; i < num; i++)
+ {
+ Step step = seq.GetStep(i, StepGroups.StepGroup_Main);
+ var ui = Convert2StepUI(step, group);
+ if (ui != null)
+ {
+ steps.Add(ui);
+ }
+ }
+
+ num = seq.GetNumSteps(StepGroups.StepGroup_Cleanup);
+ for (int i = 0; i < num; i++)
+ {
+ Step step = seq.GetStep(i, StepGroups.StepGroup_Cleanup);
+ var ui = Convert2StepUI(step, group);
+ if (ui != null)
+ {
+ steps.Add(ui);
+ }
+ }
+ return steps;
+ }
+
+ private StepUI Convert2StepUI(Step step, string group)
+ {
+ var ui = new StepUI(step);
+ if (!edits.Contains(ui.Type))
+ {
+ return null;
+ }
+
+ if (string.IsNullOrEmpty(group))
+ {
+ if (ui.StepGroup == StepGroups.StepGroup_Setup)
+ {
+ group = "Setup";
+ }
+ else if (ui.StepGroup == StepGroups.StepGroup_Main)
+ {
+ group = "Main";
+ }
+ else if (ui.StepGroup == StepGroups.StepGroup_Cleanup)
+ {
+ group = "Cleanup";
+ }
+ else
+ {
+ group = "Unkown";
+ }
+ }
+ ui.Group = group;
+
+ if (ui.Type == StepTypeStr.SequenceCall)
+ {
+ var po = step.Module.AsPropertyObject();
+ bool useCurFile = po.GetValBoolean("UseCurFile", 0);
+ if (useCurFile)
+ {
+ string seqName = po.GetValString("SeqName", 0);
+ Sequence sequence = sequenceFile.GetSequenceByName(seqName);
+ if (sequence == null)
+ {
+ return ui;
+ }
+ ui.Children = LoadSteps(sequence, group);
+ }
+ }
+ return ui;
+ }
+
+
+ [RelayCommand]
+ private void Loaded()
+ {
+ if (!isLoaded)
+ {
+ }
+ }
+
+ [RelayCommand]
+ private void OpenSeqFile()
+ {
+ OpenFileDialog ofd = new OpenFileDialog()
+ {
+ Filter = $"{LangUtil.Get("se.seq")}|*.seq;"
+ };
+ if (ofd.ShowDialog() == true)
+ {
+ control.BackgroundAction(() =>
+ {
+ try
+ {
+ var start = DateTime.Now;
+ currentFilePath = ofd.FileName;
+ CurrentFileName = $"{LangUtil.Get("se.currentFile")}{Path.GetFileName(currentFilePath)}";
+ if (sequenceFile != null)
+ {
+ engine.ReleaseSequenceFileEx(sequenceFile);
+ }
+ sequenceFile = engine.GetSequenceFileEx(currentFilePath);
+ Sequence main = sequenceFile.GetSequenceByName("MainSequence");
+ CurrentSeqUI = new SeqUI(main);
+
+ //var seqs = new ObservableCollection<SeqUI>();
+ //for (int i = 0; i < sequenceFile.NumSequences; i++)
+ //{
+ // var tsSequence = sequenceFile.GetSequence(i);
+ // seqs.Add(new SeqUI(tsSequence));
+ //}
+ //Sequences = seqs;
+
+ if (Sequences != null && Sequences.Count > 0)
+ {
+ CurrentSeqUI = Sequences[0];
+ }
+ log.Info($"Open File [{currentFilePath}] In {(DateTime.Now - start).TotalMilliseconds}ms");
+ }
+ catch (Exception ex)
+ {
+
+ }
+ }, LangUtil.Get("se.seqIsLoading"));
+ }
+ }
+
+ [RelayCommand]
+ private void SaveSeqFile()
+ {
+ sequenceFile?.Save(currentFilePath);
+ }
+
+ [RelayCommand]
+ private void Refresh()
+ {
+ if (CurrentSeqUI == null) return;
+ if (string.IsNullOrEmpty(TargetType))
+ {
+ edits = new HashSet<string> {
+ StepTypeStr.PassFailTest,
+ StepTypeStr.NumericLimitTest,
+ StepTypeStr.NI_MultipleNumericLimitTest,
+ StepTypeStr.StringValueTest,
+ StepTypeStr.Action,
+ StepTypeStr.NI_Wait,
+ StepTypeStr.SequenceCall,
+ };
+ }
+ else
+ {
+ edits = new HashSet<string>(TargetType.Split(','))
+ {
+ StepTypeStr.SequenceCall
+ };
+ }
+ AllSteps = LoadSteps(CurrentSeqUI.sequence);
+ }
+
+ [RelayCommand]
+ private void CloseSeqFile()
+ {
+ //AllSteps = new ObservableCollection<StepUI>();
+ if (engine != null && sequenceFile != null)
+ {
+ engine.ReleaseSequenceFileEx(sequenceFile);
+ sequenceFile = null;
+ }
+ setupSteps.Clear();
+ mainSteps.Clear();
+ cleanupSteps.Clear();
+ AllSteps = new();
+ Sequences.Clear();
+ currentFilePath = string.Empty;
+ CurrentFileName = string.Empty;
+ CurrentSeqUI = null;
+ CurrentStepUI = null;
+ CurrentSeqTitle = LangUtil.Get("se.steps");
+ }
+
+ [RelayCommand]
+ private void AddStep(string type)
+ {
+ try
+ {
+ var group = CurrentStepUI.step.StepGroup;
+
+ ObservableCollection<StepUI> source;
+ if (group == StepGroups.StepGroup_Setup)
+ {
+ source = setupSteps;
+ }
+ else if (group == StepGroups.StepGroup_Main)
+ {
+ source = mainSteps;
+ }
+ else
+ {
+ source = cleanupSteps;
+ }
+ int index = source.IndexOf(CurrentStepUI);
+ if (index < 0)
+ {
+ return;
+ }
+ Step newStep;
+ switch (type)
+ {
+ case "Tests.PassFail":
+ newStep = engine.NewStep(AdapterKeyNames.FlexLVAdapterKeyName, StepTypeStr.PassFailTest);
+ newStep.Name = DefaultStepName.PassFailTest;
+ var p = newStep.AsPropertyObject();
+ string name = p.Name;
+ var ps = p.GetSubProperties("", 0);
+ foreach (var pp in ps)
+ {
+ string sname = pp.Name;
+ }
+
+ break;
+ case "Tests.NumericLimitTest":
+ newStep = engine.NewStep(AdapterKeyNames.FlexLVAdapterKeyName, StepTypeStr.NumericLimitTest);
+ newStep.Name = DefaultStepName.NumericLimitTest;
+ break;
+ case "Tests.NI_MultipleNumericLimitTest":
+ newStep = engine.NewStep(AdapterKeyNames.FlexLVAdapterKeyName, StepTypeStr.NI_MultipleNumericLimitTest);
+ newStep.Name = DefaultStepName.NI_MultipleNumericLimitTest;
+ break;
+ case "Tests.StringValueTest":
+ newStep = engine.NewStep(AdapterKeyNames.FlexLVAdapterKeyName, StepTypeStr.StringValueTest);
+ newStep.Name = DefaultStepName.StringValueTest;
+ break;
+ case "Actions.LabVIEW":
+ newStep = engine.NewStep(AdapterKeyNames.FlexLVAdapterKeyName, StepTypeStr.Action);
+ newStep.Name = DefaultStepName.Action;
+ break;
+ case "Actions.LabWindows/CVI":
+ newStep = engine.NewStep(AdapterKeyNames.FlexCVIAdapterKeyName, StepTypeStr.Action);
+ newStep.Name = DefaultStepName.Action;
+ break;
+ case "Actions.C/C++ DLL":
+ newStep = engine.NewStep(AdapterKeyNames.FlexCAdapterKeyName, StepTypeStr.Action);
+ newStep.Name = DefaultStepName.Action;
+ break;
+ case "Actions..NET":
+ newStep = engine.NewStep(AdapterKeyNames.DotNetAdapterKeyname, StepTypeStr.Action);
+ newStep.Name = DefaultStepName.Action;
+ break;
+ case "Actions.ActiveX/COM":
+ newStep = engine.NewStep(AdapterKeyNames.AutomationAdapterKeyName, StepTypeStr.Action);
+ newStep.Name = DefaultStepName.Action;
+ break;
+ case "Actions.None":
+ newStep = engine.NewStep(AdapterKeyNames.NoneAdapterKeyName, StepTypeStr.Action);
+ newStep.Name = DefaultStepName.Action;
+ break;
+ case "Actions.LabVIEW NXG":
+ newStep = engine.NewStep(AdapterKeyNames.LabVIEWNXGAdapterKeyName, StepTypeStr.Action);
+ newStep.Name = DefaultStepName.Action;
+ break;
+ case "Actions.Python":
+ newStep = engine.NewStep(AdapterKeyNames.PythonAdapterKeyName, StepTypeStr.Action);
+ newStep.Name = DefaultStepName.Action;
+ break;
+
+ default:
+ return;
+ }
+ CurrentSeqUI.sequence.InsertStep(newStep, index + 1, group);
+ AllSteps = LoadSteps(CurrentSeqUI.sequence);
+ }
+ catch (Exception ex)
+ {
+ log.Error("Insert Step Error.", ex);
+ MsgBoxHelper2.Error(ex.Message);
+ }
+ }
+
+ [ObservableProperty]
+ private TreeItemData treeItemData;
+
+ partial void OnTreeItemDataChanged(TreeItemData data)
+ {
+ CurrentStepUI = data?.Data as StepUI;
+ }
+
+ partial void OnCurrentStepUIChanged(StepUI stepUI)
+ {
+ var panel = StepUI2EPO.Convert2EditPanel(stepUI);
+ control.editPanelContainer.Child = panel;
+ if (stepUI != null)
+ {
+
+ //window.commonP.RefreshStep(stepUI);
+ }
+ }
+
+ partial void OnCurrentSeqUIChanged(SeqUI seqUI)
+ {
+ if (seqUI != null)
+ {
+ CurrentStepUI = null;
+ AllSteps = LoadSteps(seqUI.sequence);
+ }
+ CurrentSeqTitle = $"{seqUI?.Name} {LangUtil.Get("se.steps")}";
+ }
+ }
+}
diff --git a/Plugin.TestResult/SingleCell.xaml b/Plugin.TestResult/SingleCell.xaml
index c374a6e..57c824f 100644
--- a/Plugin.TestResult/SingleCell.xaml
+++ b/Plugin.TestResult/SingleCell.xaml
@@ -5,6 +5,8 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Plugin.TestResult_WPF"
mc:Ignorable="d"
+ xmlns:pw="https://opensource.panuon.com/wpf"
+xmlns:pu="https://opensource.panuon.com/wpf-ui"
x:Name="uc"
Padding="5"
MouseDoubleClick="UserControl_MouseDoubleClick"
@@ -17,6 +19,12 @@
<ToolTip Padding="5" BorderThickness="1" BorderBrush="Black" Background="Yellow" Content="{Binding tooltipContent}"/>
</UserControl.ToolTip>-->
+ <UserControl.ContextMenu>
+ <ContextMenu>
+ <MenuItem IsCheckable="True" IsChecked="{Binding CellIsDisabled,Mode=TwoWay}" Header="绂佺敤"/>
+ </ContextMenu>
+ </UserControl.ContextMenu>
+
<UserControl.Style>
<Style TargetType="UserControl">
<Style.Triggers>
diff --git a/Plugin.TestResult/SingleCell.xaml.cs b/Plugin.TestResult/SingleCell.xaml.cs
index 08fb6b7..b8b62a7 100644
--- a/Plugin.TestResult/SingleCell.xaml.cs
+++ b/Plugin.TestResult/SingleCell.xaml.cs
@@ -78,6 +78,18 @@
}
}
+ private bool cellIsDisabled;
+
+ public bool CellIsDisabled
+ {
+ get { return cellIsDisabled; }
+ set
+ {
+ RaiseAndSetIfchanged(ref cellIsDisabled, value);
+ }
+ }
+
+
public string title => $"{parentName}-{index + 1}";
private string _status = CommonStatus.WAITING;
diff --git a/Plugin.TestResult/TestResultView.xaml.cs b/Plugin.TestResult/TestResultView.xaml.cs
index d8fa337..5f56462 100644
--- a/Plugin.TestResult/TestResultView.xaml.cs
+++ b/Plugin.TestResult/TestResultView.xaml.cs
@@ -1,5 +1,6 @@
锘縰sing HMI.Core.Util;
using HMI.UI.Util;
+using NationalInstruments.TestStand.Interop.AdapterAPI;
using NationalInstruments.TestStand.Interop.API;
using NationalInstruments.TestStand.Interop.UI.Ax;
using NationalInstruments.TestStand.Utility;
diff --git a/Plugin.TsExecution/SingleControl.xaml b/Plugin.TsExecution/SingleControl.xaml
index 0aa2f1e..5cfe37e 100644
--- a/Plugin.TsExecution/SingleControl.xaml
+++ b/Plugin.TsExecution/SingleControl.xaml
@@ -8,6 +8,7 @@
xmlns:pu="https://opensource.panuon.com/wpf-ui"
xmlns:local="clr-namespace:Plugin.TsExecution"
mc:Ignorable="d"
+ xmlns:sys="clr-namespace:System;assembly=mscorlib"
Loaded="UserControl_Loaded"
Background="#ccc6c7"
FontSize="{Binding ActualHeight,RelativeSource={RelativeSource AncestorType=UserControl},
@@ -15,6 +16,8 @@
x:Name="control"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
+ <sys:Double x:Key="nanD">NaN</sys:Double>
+
<Style TargetType="Label" x:Key="baseLabel">
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
@@ -207,8 +210,7 @@
VirtualizingPanel.IsContainerVirtualizable="True"
VirtualizingPanel.IsVirtualizing="True"
VirtualizingPanel.VirtualizationMode="Recycling"
- RowHeight="{Binding ActualWidth,ElementName=control,
-Converter={StaticResource fc}, ConverterParameter='35,1093,-1,45'}"
+ RowHeight="{StaticResource nanD}"
ColumnHeaderHeight="{Binding ActualWidth,ElementName=control,
Converter={StaticResource fc}, ConverterParameter='30,1093,-1,45'}"
ItemsSource="{Binding Datasource}"
@@ -249,7 +251,7 @@
<TextBlock Text="{DynamicResource Test.Name}"/>
</DataGridTextColumn.Header>
</DataGridTextColumn>
- <DataGridTextColumn Width="*" Binding="{Binding Unit}"
+ <DataGridTextColumn Width="100" Binding="{Binding Unit}"
ElementStyle="{StaticResource TableTextBlock}">
<DataGridTextColumn.Header>
<TextBlock Text="{DynamicResource Test.Unit}"/>
@@ -273,7 +275,7 @@
<TextBlock Text="{DynamicResource Test.LimitUp}"/>
</DataGridTextColumn.Header>
</DataGridTextColumn>
- <DataGridTemplateColumn Width="*">
+ <DataGridTemplateColumn Width="120">
<DataGridTemplateColumn.Header>
<TextBlock Text="{DynamicResource Test.Result}"/>
</DataGridTemplateColumn.Header>
diff --git a/Plugin.TsExecution/SingleControl.xaml.cs b/Plugin.TsExecution/SingleControl.xaml.cs
index 8b0cfff..c82ecb6 100644
--- a/Plugin.TsExecution/SingleControl.xaml.cs
+++ b/Plugin.TsExecution/SingleControl.xaml.cs
@@ -408,34 +408,37 @@
public void WriteToCSV(string path)
{
- try
+ Dispatcher.BeginInvoke(new Action(() =>
{
-
- FileInfo fi = new FileInfo(path);
- if (!fi.Directory.Exists)
+ try
{
- fi.Directory.Create(); //鏂囦欢涓嶅瓨鍦紝鍒涘缓鏂囦欢
- }
- using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write))
- using (StreamWriter sw = new StreamWriter(fs, System.Text.Encoding.UTF8))
- {
- string title = "椤圭洰鍚嶇О,娴嬭瘯鍙傛暟,娴嬭瘯鍊�,涓婇檺,涓嬮檺,鍗曚綅,缁撴灉";
- sw.WriteLine(title);
-
- if (Datasource != null && Datasource.Count > 0)
+ FileInfo fi = new FileInfo(path);
+ if (!fi.Directory.Exists)
{
- foreach (var data in Datasource)
+ fi.Directory.Create(); //鏂囦欢涓嶅瓨鍦紝鍒涘缓鏂囦欢
+ }
+
+ using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write))
+ using (StreamWriter sw = new StreamWriter(fs, System.Text.Encoding.UTF8))
+ {
+ string title = "椤圭洰鍚嶇О,娴嬭瘯鍙傛暟,娴嬭瘯鍊�,涓婇檺,涓嬮檺,鍗曚綅,缁撴灉";
+ sw.WriteLine(title);
+
+ if (Datasource != null && Datasource.Count > 0)
{
- sw.WriteLine($"{data.Name},{data.Step},{data.Value},{data.LimitUp},{data.LimitDown},{data.Unit},{data.Result}");
+ foreach (var data in Datasource)
+ {
+ sw.WriteLine($"{data.Name},{data.Step},{data.Value},{data.LimitUp},{data.LimitDown},{data.Unit},{data.Result}");
+ }
}
}
}
- }
- catch (Exception ex)
- {
- TsExecution.logger.Error("Write CSV File Failed.", ex);
- }
+ catch (Exception ex)
+ {
+ TsExecution.logger.Error("Write CSV File Failed.", ex);
+ }
+ }));
}
public void ShowPausePanel()
diff --git a/Plugin.TsExecution/TsExecution.xaml.cs b/Plugin.TsExecution/TsExecution.xaml.cs
index fb1f427..528df03 100644
--- a/Plugin.TsExecution/TsExecution.xaml.cs
+++ b/Plugin.TsExecution/TsExecution.xaml.cs
@@ -212,7 +212,6 @@
}
}
-
public TsExecution()
{
DataContext = this;
@@ -283,15 +282,14 @@
if (!string.IsNullOrEmpty(lastModel))
{
var product = Products.FirstOrDefault(p => p.Name == lastModel);
- if (product != null) SelectedProduct = product;
- goto Write;
+ if (product != null)
+ {
+ SelectedProduct = product;
+ RefershUI();
+ return;
+ }
}
- goto Write;
-
- Write:
SelectedProduct = Products[0];
- engine?.Globals.SetValString("StationState.ProductModel", 1, Products[0].Name);
-
RefershUI();
}
SampleStatus = false;
@@ -461,6 +459,8 @@
fail = Convert.ToInt32(IniFileHelper.ReadIniData("Count", "Fail", "0", CountIniPath));
}
+ private string csvDir;
+
/// <summary>
/// 璇诲彇閰嶇疆鏂囦欢閲岀殑鍑犱釜灞炴��
/// </summary>
@@ -535,6 +535,21 @@
catch
{
UI_ShowInfoDock = false;
+ }
+
+ try
+ {
+
+ value = ParameterManager.GetCommonParameterByName("TestReportFolder");
+ csvDir = value.Value;
+ if (!Directory.Exists(csvDir))
+ {
+ Directory.CreateDirectory(csvDir);
+ }
+ }
+ catch
+ {
+ csvDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TestReport");
}
//Convert.ToBoolean(IniFileHelper.ReadIniData("Config", "EnableMes", "true", CountIniPath));
@@ -647,8 +662,14 @@
//MaskWindow mask = new MaskWindow();
try
{
+ engine?.Globals.SetValString("StationState.ProductModel", 1, SelectedProduct?.Name);
+ 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;
}
@@ -831,6 +852,15 @@
this.tsSockets[index].Barcode = barcode;
}
+ public void SavePositionCSV(int index)
+ {
+ var time = DateTime.Now;
+ string status = this.tsSockets[index].Status == "Passed" ? "PASS" : "FAIL";
+ string csvPath = Path.Combine(csvDir, SelectedProduct?.Name ?? "鏈煡浜у搧", time.ToString("yyyyMMdd"), status,
+ $"{this.tsSockets[index].Barcode}-{time.ToString("HHmmss")}.csv");
+ this.tsSockets[index].WriteToCSV(csvPath);
+ }
+
/// <summary>
/// TestStand鐢ㄦ埛浜や簰浜嬩欢
/// </summary>
@@ -939,7 +969,7 @@
this.tsSockets[Index].SetTestProcess(ProcessVal);
break;
case 10031://瀵煎嚭CSV
- this.tsSockets[Index].WriteToCSV(e.uiMsg.StringData);
+ SavePositionCSV(Index);
break;
case 10032://鎸変笅鏍囨殏鍋滄祴璇�
this.tsSockets[Index].ShowPausePanel();
diff --git a/WPFProject/App.config b/WPFProject/App.config
index d1cf364..603cbae 100644
--- a/WPFProject/App.config
+++ b/WPFProject/App.config
@@ -3,7 +3,7 @@
<configSections>
<section name="TestResultConfig" type="System.Configuration.SingleTagSectionHandler" />
</configSections>
- <TestResultConfig Row="2" Column="3" PortStart="6660" PositionColumn="3" PositionCount="18" NameStr="A1,A2,A3,B1,B2,B3"/>
+ <TestResultConfig Row="2" Column="3" PortStart="6660" PositionColumn="3" PositionCount="18" NameStr="A1,A2,A3,B1,B2,B3" />
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
diff --git a/WPFProject/BuildCmd.bat b/WPFProject/BuildCmd.bat
index c912389..1936efa 100644
--- a/WPFProject/BuildCmd.bat
+++ b/WPFProject/BuildCmd.bat
@@ -1,8 +1,15 @@
-锘縨ove /y "$(TargeDir)HMI.Core.dll" $(TargeDir)Libs\HMI.Core.dll"
+锘縄F "$(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"
move /y "$(TargeDir)HMI.Util.dll" $(TargeDir)Libs\HMI.Util.dll"
move /y "$(TargeDir)ConnectionUtil.dll" $(TargeDir)Libs\ConnectionUtil.dll"
+
+move /y "$(TargeDir)HMI.LogUtil.dll" $(TargeDir)Api\HMI.LogUtil.dll"
+move /y "$(TargeDir)HMI.SerialData.Util.dll" $(TargeDir)Api\HMI.SerialData.Util.dll"
+move /y "$(TargeDir)HMI.Simple.Util.dll" $(TargeDir)Api\HMI.Simple.Util.dll"
+move /y "$(TargeDir)HMI.Util.Base.dll" $(TargeDir)Api\HMI.Util.Base.dll"
move /y "$(TargeDir)HMI.AlarmInfoManage.dll" $(TargeDir)Plugin\HMI.AlarmInfoManage.dll"
move /y "$(TargeDir)HMI.DataViewer.dll" $(TargeDir)Plugin\HMI.DataViewer.dll"
@@ -18,6 +25,7 @@
move /y "$(TargeDir)Plugin.TestBuilder.dll" $(TargeDir)Plugin\Plugin.TestBuilder.dll"
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"
setlocal enabledelayedexpansion
diff --git a/WPFProject/Lang/en-US/SeqEditor.json b/WPFProject/Lang/en-US/SeqEditor.json
new file mode 100644
index 0000000..e2643bf
--- /dev/null
+++ b/WPFProject/Lang/en-US/SeqEditor.json
@@ -0,0 +1,34 @@
+{
+ "se.title": "Seq Config",
+ "se.file": "File",
+ "se.open": "Open",
+ "se.save": "Save",
+ "se.saveTo": "Save To",
+ "se.close": "Close",
+ "se.stepName": "Step",
+ "se.stepType": "Type",
+ "se.runMode": "Run Mode",
+ "se.waitInterval": "Interval (s)",
+ "se.adapter": "Adapter",
+ "se.seq": "Sequence",
+ "se.name": "Name",
+ "se.type": "Type",
+ "se.description": "Description",
+ "se.propertySetting": "Setting",
+ "se.normal": "Normal",
+ "se.skip": "Skip",
+ "se.pass": "Force to PASS",
+ "se.fail": "Force to FAIL",
+ "se.steps": "Steps",
+ "se.currentFile": "Current File: ",
+ "se.seqIsLoading": "Sequence is loading",
+ "se.compType": "Comparison Type",
+ "se.targetVal": "Target Val",
+
+ "se.data.none": "None",
+ "se.strComp.SCCS": "String Comparsion - Case Sensitive",
+ "se.strComp.SCIC": "String Comparsion - Ignore Case",
+ "se.strComp.RECS": "Regular Expression - Case Sensitive",
+ "se.strComp.REIC": "Regular Expression - Ignore Case"
+
+}
\ No newline at end of file
diff --git a/WPFProject/Lang/zh-CN/SeqEditor.json b/WPFProject/Lang/zh-CN/SeqEditor.json
new file mode 100644
index 0000000..018e449
--- /dev/null
+++ b/WPFProject/Lang/zh-CN/SeqEditor.json
@@ -0,0 +1,34 @@
+{
+ "se.title": "搴忓垪閰嶇疆",
+ "se.file": "鏂囦欢",
+ "se.open": "鎵撳紑",
+ "se.save": "淇濆瓨",
+ "se.saveTo": "鍙﹀瓨",
+ "se.close": "鍏抽棴",
+ "se.stepName": "姝ラ鍚嶇О",
+ "se.stepType": "姝ラ绫诲瀷",
+ "se.runMode": "杩愯璁剧疆",
+ "se.waitInterval": "绛夊緟鏃堕棿锛坰锛�",
+ "se.adapter": "閫傞厤鍣�",
+ "se.seq": "娴嬭瘯搴忓垪",
+ "se.name": "鍚嶇О",
+ "se.type": "绫诲瀷",
+ "se.description": "鎻忚堪",
+ "se.propertySetting": "灞炴�ц缃�",
+ "se.normal": "姝e父",
+ "se.skip": "璺宠繃",
+ "se.pass": "寮哄埗PASS",
+ "se.fail": "寮哄埗FAIL",
+ "se.steps": "娴嬭瘯姝ラ",
+ "se.currentFile": "褰撳墠鏂囦欢锛�",
+ "se.seqIsLoading": "姝e湪鍔犺浇娴嬭瘯搴忓垪",
+ "se.compType": "姣旇緝鏂瑰紡",
+ "se.targetVal": "鏈熸湜鍊�",
+
+ "se.data.none": "鏃�",
+ "se.strComp.SCCS": "姣旇緝瀛楃涓�-澶у皬鍐欐晱鎰�",
+ "se.strComp.SCIC": "姣旇緝瀛楃涓�-蹇界暐澶у皬鍐�",
+ "se.strComp.RECS": "姝e垯琛ㄨ揪寮�-澶у皬鍐欐晱鎰�",
+ "se.strComp.REIC": "姝e垯琛ㄨ揪寮�-蹇界暐澶у皬鍐�"
+
+}
\ No newline at end of file
diff --git a/WPFProject/Lang/zh-CN/app.json b/WPFProject/Lang/zh-CN/app.json
index 79111c2..6b4b85f 100644
--- a/WPFProject/Lang/zh-CN/app.json
+++ b/WPFProject/Lang/zh-CN/app.json
@@ -5,7 +5,7 @@
"App.Password": "瀵嗙爜",
"App.UsernameHolder": "璇疯緭鍏ョ敤鎴峰悕",
"App.PasswordHolder": "璇疯緭鍏ュ瘑鐮�",
- "App.PleaseWait": "璇风瓑寰�",
+ "App.PleaseWait": "璇风◢鍊�",
"App.LoginFailed": "鐧婚檰澶辫触",
"App.ErrorUsernameOrPassword": "鐢ㄦ埛鍚嶆垨瀵嗙爜閿欒",
"App.IconMustInFolder": "璇峰皢鍥炬爣绉诲姩鑷崇▼搴廔con鐩綍涓�",
@@ -156,5 +156,5 @@
"App.ScannerSetting": "鎵爜鏋缃�",
"App.SequenceIsStarting": "姝e湪鍚姩娴嬭瘯搴忓垪锛岃绋嶅悗...",
"App.Status": "鐘舵��",
- "App.Info": "淇℃伅"
+ "App.Info": "淇℃伅",
}
\ No newline at end of file
diff --git a/WPFProject/LoadingWindow.xaml.cs b/WPFProject/LoadingWindow.xaml.cs
index e0c4fc1..4e1ff79 100644
--- a/WPFProject/LoadingWindow.xaml.cs
+++ b/WPFProject/LoadingWindow.xaml.cs
@@ -1,5 +1,4 @@
锘縰sing HMI.Base;
-using HMI.Core.Api;
using HMI.UI.Util;
using Panuon.WPF.UI;
using System;
@@ -85,9 +84,11 @@
private void Button_Click(object sender, RoutedEventArgs e)
{
+ this.Closed -= ShutDownWhen_Closed;
window.Show();
this.Close();
}
+
private PanuonWindow window;
private double total;
private double finished;
@@ -116,9 +117,15 @@
ShowConsole = true;
BtnNext.Visibility = Visibility.Visible;
MsgBoxHelper.Error(this, "鍔犺浇鍑洪敊锛岃纭");
+ this.Closed += ShutDownWhen_Closed; ;
}
}
+ private void ShutDownWhen_Closed(object sender, EventArgs e)
+ {
+ Application.Current.Shutdown();
+ }
+
public void Add(string text, bool? result)
{
Message = text;
diff --git a/WPFProject/WPFProject.csproj b/WPFProject/WPFProject.csproj
index 89e92ba..55d3de6 100644
--- a/WPFProject/WPFProject.csproj
+++ b/WPFProject/WPFProject.csproj
@@ -107,6 +107,9 @@
<Reference Include="Microsoft.DwayneNeed.Win32">
<HintPath>..\Libs\Microsoft.DwayneNeed.Win32.dll</HintPath>
</Reference>
+ <Reference Include="Microsoft.Xaml.Behaviors, Version=1.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+ <HintPath>packages\Microsoft.Xaml.Behaviors.Wpf.1.1.135\lib\net462\Microsoft.Xaml.Behaviors.dll</HintPath>
+ </Reference>
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
@@ -395,6 +398,12 @@
<Content Include="Lang\en-US\DataBoard.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
+ <Content Include="Lang\zh-CN\SeqEditor.json">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="Lang\en-US\SeqEditor.json">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
<None Include="packages.config" />
<None Include="Properties\app.manifest" />
<None Include="Properties\Settings.settings">
@@ -458,6 +467,10 @@
<Project>{968fe602-22d6-42bd-981c-601ad518a896}</Project>
<Name>Plugin.JarUI</Name>
</ProjectReference>
+ <ProjectReference Include="..\Plugin.SeqEditor\Plugin.SeqEditor.csproj">
+ <Project>{717fd815-ff95-4f30-b4d9-9cea978ca40e}</Project>
+ <Name>Plugin.SeqEditor</Name>
+ </ProjectReference>
<ProjectReference Include="..\Plugin.ServoManage\Plugin.ServoManage.csproj">
<Project>{1853e00f-6865-4bc6-974b-6a5e1c00bafe}</Project>
<Name>Plugin.ServoManage</Name>
@@ -507,11 +520,17 @@
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
- <PostBuildEvent>move /y "$(TargeDir)HMI.Core.dll" $(TargeDir)Libs\HMI.Core.dll"
+ <PostBuildEvent>
+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"
move /y "$(TargeDir)HMI.Util.dll" $(TargeDir)Libs\HMI.Util.dll"
move /y "$(TargeDir)ConnectionUtil.dll" $(TargeDir)Libs\ConnectionUtil.dll"
+
+move /y "$(TargeDir)HMI.LogUtil.dll" $(TargeDir)Api\HMI.LogUtil.dll"
+move /y "$(TargeDir)HMI.SerialData.Util.dll" $(TargeDir)Api\HMI.SerialData.Util.dll"
+move /y "$(TargeDir)HMI.Simple.Util.dll" $(TargeDir)Api\HMI.Simple.Util.dll"
+move /y "$(TargeDir)HMI.Util.Base.dll" $(TargeDir)Api\HMI.Util.Base.dll"
move /y "$(TargeDir)HMI.AlarmInfoManage.dll" $(TargeDir)Plugin\HMI.AlarmInfoManage.dll"
move /y "$(TargeDir)HMI.DataViewer.dll" $(TargeDir)Plugin\HMI.DataViewer.dll"
@@ -527,6 +546,7 @@
move /y "$(TargeDir)Plugin.TestBuilder.dll" $(TargeDir)Plugin\Plugin.TestBuilder.dll"
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"
setlocal enabledelayedexpansion
diff --git a/WPFProject/WPFProject.sln b/WPFProject/WPFProject.sln
index 3c6d196..ded9cb2 100644
--- a/WPFProject/WPFProject.sln
+++ b/WPFProject/WPFProject.sln
@@ -63,6 +63,8 @@
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Plugin.JarUI", "..\Plugin.JarUI\Plugin.JarUI.csproj", "{968FE602-22D6-42BD-981C-601AD518A896}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Plugin.SeqEditor", "..\Plugin.SeqEditor\Plugin.SeqEditor.csproj", "{717FD815-FF95-4F30-B4D9-9CEA978CA40E}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -303,6 +305,14 @@
{968FE602-22D6-42BD-981C-601AD518A896}.Release|Any CPU.Build.0 = Release|Any CPU
{968FE602-22D6-42BD-981C-601AD518A896}.Release|x64.ActiveCfg = Release|Any CPU
{968FE602-22D6-42BD-981C-601AD518A896}.Release|x64.Build.0 = Release|Any CPU
+ {717FD815-FF95-4F30-B4D9-9CEA978CA40E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {717FD815-FF95-4F30-B4D9-9CEA978CA40E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {717FD815-FF95-4F30-B4D9-9CEA978CA40E}.Debug|x64.ActiveCfg = Debug|x64
+ {717FD815-FF95-4F30-B4D9-9CEA978CA40E}.Debug|x64.Build.0 = Debug|x64
+ {717FD815-FF95-4F30-B4D9-9CEA978CA40E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {717FD815-FF95-4F30-B4D9-9CEA978CA40E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {717FD815-FF95-4F30-B4D9-9CEA978CA40E}.Release|x64.ActiveCfg = Release|Any CPU
+ {717FD815-FF95-4F30-B4D9-9CEA978CA40E}.Release|x64.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/WPFProject/packages.config b/WPFProject/packages.config
index 80bed4e..b62d154 100644
--- a/WPFProject/packages.config
+++ b/WPFProject/packages.config
@@ -1,6 +1,7 @@
锘�<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="log4net" version="3.0.4" targetFramework="net472" />
+ <package id="Microsoft.Xaml.Behaviors.Wpf" version="1.1.135" targetFramework="net472" />
<package id="Newtonsoft.Json" version="13.0.3" targetFramework="net472" />
<package id="Panuon.WPF" version="1.1.3" targetFramework="net472" />
<package id="Panuon.WPF.UI" version="1.3.0.2" targetFramework="net472" />
--
Gitblit v1.9.1