34个文件已修改
57个文件已添加
1 文件已重命名
| | |
| | | </pu:FormGroup> |
| | | </StackPanel> |
| | | </GroupBox> |
| | | |
| | | <Button Click="Button_Click">保存</Button> |
| | | </StackPanel> |
| | | </Grid> |
| | | </UserControl> |
| | |
| | | using HMI.AlarmInfoManage.Entity; |
| | | using HMI.Core.Api; |
| | | using HMI.Core.Util; |
| | | using System.Windows; |
| | | using System.Windows.Controls; |
| | |
| | | /// <summary> |
| | | /// AlarmInfoManage_Setting.xaml 的交互逻辑 |
| | | /// </summary> |
| | | public partial class AlarmInfoManage_Setting : UserControl |
| | | public partial class AlarmInfoManage_Setting : UserControl, IConfigManager |
| | | { |
| | | public AlarmInfoManage_Setting() |
| | | { |
| | |
| | | |
| | | private void UserControl_Loaded(object sender, RoutedEventArgs e) |
| | | { |
| | | DataContext = AimSetting.Instance.GetModel(); |
| | | ResetConfig(); |
| | | } |
| | | |
| | | private void Button_Click(object sender, RoutedEventArgs e) |
| | | public object GetConfig() |
| | | { |
| | | return AimSetting.Instance; |
| | | } |
| | | |
| | | public void SaveConfig() |
| | | { |
| | | AimSettingModel model = (AimSettingModel)DataContext; |
| | | |
| | | AimSetting newSetting = AimSetting.FromModel(model); |
| | | |
| | | XmlHelper.SerializeToXml(PathHelper.ConfigFolder + "\\AimSetting.xml", model); |
| | | } |
| | | |
| | | public void ResetConfig() |
| | | { |
| | | DataContext = AimSetting.Instance.GetModel(); |
| | | } |
| | | } |
| | | } |
| | |
| | | xmlns:pu="https://opensource.panuon.com/wpf-ui" |
| | | xmlns:uic="clr-namespace:HMI.UI.Converter;assembly=HMI.UI" |
| | | xmlns:ui="clr-namespace:HMI.UI;assembly=HMI.UI" |
| | | xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI" |
| | | mc:Ignorable="d" |
| | | Title="Form" |
| | | SizeToContent="Height" |
| | |
| | | pu:WindowXModalDialog.ButtonPanelMargin="0,30,10,10"> |
| | | <Grid Margin="10"> |
| | | <StackPanel x:Name="formPanel"> |
| | | <pu:FormGroup ui:FormGroupHelper.IsRequired="True" |
| | | ui:FormGroupHelper.ValidateMethod="ValidateDBAddress" |
| | | <pu:FormGroup dp:FormGroupHelper.IsRequired="True" |
| | | dp:FormGroupHelper.ValidateMethod="ValidateDBAddress" |
| | | Header="DB地址" GroupName="MyFormGroup"> |
| | | <pu:NumberInput Style="{StaticResource FormNumberInput}" |
| | | x:Name="dbAddress" Interval="1"/> |
| | | </pu:FormGroup> |
| | | |
| | | <pu:FormGroup ui:FormGroupHelper.IsRequired="True" |
| | | <pu:FormGroup dp:FormGroupHelper.IsRequired="True" |
| | | Header="起始地址" GroupName="MyFormGroup"> |
| | | <pu:NumberInput Style="{StaticResource FormNumberInput}" x:Name="startAddress" Interval="1"/> |
| | | </pu:FormGroup> |
| | | |
| | | <pu:FormGroup ui:FormGroupHelper.IsRequired="True" |
| | | <pu:FormGroup dp:FormGroupHelper.IsRequired="True" |
| | | Header="长度" GroupName="MyFormGroup"> |
| | | <pu:NumberInput Style="{StaticResource FormNumberInput}" x:Name="length" Interval="1"/> |
| | | </pu:FormGroup> |
| | |
| | | using HMI.AlarmInfoManage.Entity; |
| | | using HMI.Core.Util; |
| | | using HMI.UI; |
| | | using HMI.UI.DpUtil; |
| | | using HMI.UI.Util; |
| | | using log4net; |
| | | using Panuon.WPF.UI; |
| New file |
| | |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | |
| | | namespace HMI.Core.Api |
| | | { |
| | | public interface IConfigManager |
| | | { |
| | | object GetConfig(); |
| | | |
| | | void SaveConfig(); |
| | | |
| | | void ResetConfig(); |
| | | } |
| | | } |
| | |
| | | <Reference Include="System.Xml" /> |
| | | </ItemGroup> |
| | | <ItemGroup> |
| | | <Compile Include="Api\IConfigManager.cs" /> |
| | | <Compile Include="Api\IConfigRefresh.cs" /> |
| | | <Compile Include="Api\IFolderOwner.cs" /> |
| | | <Compile Include="Api\IPlugin.cs" /> |
| | |
| | | </Grid>--> |
| | | <StackPanel Grid.Row="1" Grid.ColumnSpan="2" HorizontalAlignment="Left" Style="{StaticResource ButtonGroup}"> |
| | | |
| | | <TextBlock Style="{StaticResource TitleBox}" Text="开始时间"/> |
| | | <pu:DateTimePicker Width="190" Style="{StaticResource TimePicker}" SelectedDateTime="{x:Null}" x:Name="startTimeInput"/> |
| | | <TextBlock Style="{StaticResource TitleBox}" Text="结束时间"/> |
| | | <pu:DateTimePicker Width="190" Style="{StaticResource TimePicker}" SelectedDateTime="{x:Null}" x:Name="endTimeInput"/> |
| | | <TextBlock Style="{StaticResource TitleBox}" FontSize="{StaticResource ContentFontSize2}" Text="开始时间"/> |
| | | <pu:DateTimePicker Style="{StaticResource TimePicker}" SelectedDateTime="{x:Null}" x:Name="startTimeInput"/> |
| | | <TextBlock Style="{StaticResource TitleBox}" FontSize="{StaticResource ContentFontSize2}" Text="结束时间"/> |
| | | <pu:DateTimePicker Style="{StaticResource TimePicker}" SelectedDateTime="{x:Null}" x:Name="endTimeInput"/> |
| | | |
| | | <Button Style="{StaticResource PrimaryButton}" pu:ButtonHelper.Icon="" |
| | | x:Name="srhBtn" Click="Button_Click">查询</Button> |
| | |
| | | <Button Style="{StaticResource PrimaryButton}" pu:ButtonHelper.Icon="" |
| | | x:Name="resetBtn" Click="Button_Click">重置</Button> |
| | | |
| | | <Menu x:Name="anyBtn" > |
| | | <Menu x:Name="anyBtn" Style="{StaticResource CommonMenu}"> |
| | | <MenuItem Header="分析"> |
| | | <MenuItem Header="CPK" /> |
| | | <MenuItem Header="CPK" Click="MenuItem_Click"/> |
| | | <MenuItem Header="RandR" /> |
| | | </MenuItem> |
| | | </Menu> |
| | |
| | | |
| | | <DockPanel Grid.Row="2" Grid.ColumnSpan="2" Margin="0,10,0,0"> |
| | | <pu:Drawer DockPanel.Dock="Left" x:Name="DrwMenu" MinWidth="34" MaxWidth="400" |
| | | Padding="0" |
| | | ShadowColor="{x:Null}" |
| | | AnimationDuration="0" BorderThickness="2,2,0,2" BorderBrush="{StaticResource CommonBoarder}"> |
| | | AnimationDuration="0" BorderThickness="2,0,0,2" BorderBrush="{StaticResource CommonBoarder}"> |
| | | <Grid> |
| | | <Grid.RowDefinitions> |
| | | <RowDefinition Height="Auto"/> |
| | |
| | | </Grid.ColumnDefinitions> |
| | | |
| | | <DockPanel Grid.ColumnSpan="2" Background="{StaticResource CommonBoarder}"> |
| | | <ToggleButton Grid.Column="1" x:Name="drawerBtn" BorderThickness="0" |
| | | <ToggleButton x:Name="drawerBtn" BorderThickness="0" |
| | | DockPanel.Dock="Right" |
| | | Background="Transparent" |
| | | Width="34" Height="34" HorizontalAlignment="Right" |
| | |
| | | FontFamily="{StaticResource iconfont}" |
| | | Content="" IsChecked="{Binding IsOpen, ElementName=DrwMenu, Mode=TwoWay}"> |
| | | <ToggleButton.Style> |
| | | <Style TargetType="ToggleButton"> |
| | | <Style TargetType="ToggleButton" BasedOn="{StaticResource CommonToggle}"> |
| | | <Style.Triggers> |
| | | <DataTrigger Binding="{Binding IsOpen, ElementName=DrwMenu}" Value="False"> |
| | | <Setter Property="RenderTransform"> |
| | |
| | | </Style> |
| | | </ToggleButton.Style> |
| | | </ToggleButton> |
| | | |
| | | |
| | | <TextBlock Text="高级查询" FontSize="16" VerticalAlignment="Center" HorizontalAlignment="Center"/> |
| | | </DockPanel> |
| | | |
| | |
| | | <Label Content="选择查询项目"/> |
| | | <ComboBox Grid.Column="1" x:Name="programInput" SelectionChanged="programInput_SelectionChanged"/> |
| | | </DockPanel> |
| | | |
| | | |
| | | <DataGrid Margin="10" Grid.Row="1" Grid.ColumnSpan="2" Style="{StaticResource DefaultDataGrid}" |
| | | IsReadOnly="False" |
| | | SelectionMode="Single" |
| | | BorderThickness="0" |
| | | ItemsSource="{Binding Datas}"> |
| | | <DataGrid.Columns> |
| | |
| | | </Grid> |
| | | </pu:Drawer> |
| | | |
| | | <DataGrid BorderThickness="2" BorderBrush="{StaticResource CommonBoarder}" x:Name="dataTable" Style="{StaticResource DefaultDataGrid}"> |
| | | <DataGrid BorderThickness="2" BorderBrush="{StaticResource CommonBoarder}" x:Name="dataTable" |
| | | Style="{StaticResource DefaultDataGrid}" |
| | | SelectionUnit="CellOrRowHeader" |
| | | SelectionMode="Extended" |
| | | pu:DataGridHelper.CellSelectedBackground="{StaticResource PrimaryColor}" |
| | | PreviewMouseLeftButtonDown="dataTable_PreviewMouseLeftButtonDown"> |
| | | <DataGrid.Columns> |
| | | <DataGridTemplateColumn Header="#" IsReadOnly="True" CanUserResize="False"> |
| | | <DataGridTemplateColumn.CellTemplate> |
| | |
| | | using HMI.Core.Util; |
| | | using HMI.DataViewer.Entity; |
| | | using HMI.UI.Util; |
| | | using Panuon.WPF.UI; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Collections.ObjectModel; |
| | |
| | | using System.Linq; |
| | | using System.Windows; |
| | | using System.Windows.Controls; |
| | | using System.Windows.Controls.Primitives; |
| | | using System.Windows.Data; |
| | | using System.Windows.Media; |
| | | |
| | | namespace HMI.DataViewer |
| | | { |
| | |
| | | } |
| | | |
| | | DataBase_Setting setting = Map[program]; |
| | | |
| | | |
| | | |
| | | string fields = string.Join(",", Datas?.Select(d => $"[{d.Key}]").ToList()); |
| | | |
| | |
| | | conditon += $" AND {timeCol} < '{endTimeInput.Text}'"; |
| | | } |
| | | conditon = string.IsNullOrEmpty(conditon) ? string.Empty : $" WHERE {conditon}"; |
| | | |
| | | |
| | | SqliteHelper helper = null; |
| | | string sql = string.Empty; |
| | | try |
| | |
| | | helper = new SqliteHelper(setting.DBFilePath); |
| | | sql = $"SELECT {fields} FROM {setting.TableName} {conditon}"; |
| | | DataTable dt = helper.GetDataTable(sql); |
| | | |
| | | HMI.UI.DpUtil.DataGridHelper.SetSelectedColumn(dataTable, null); |
| | | dataTable.ItemsSource = dt.DefaultView; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | log.Error($"Select Data Failed. SQL: {sql}", ex); |
| | | ToastHelper.Error(Window.GetWindow(this), $"查询失败!{ex.Message}"); |
| | | |
| | | } |
| | | finally |
| | | { |
| | |
| | | setting?.Condition?.Select(d => new QueryData { Key = d.Key, Name = d.Desc, Condition = "=" }).ToList()); |
| | | |
| | | var temp = dataTable.Columns[0]; |
| | | HMI.UI.DpUtil.DataGridHelper.SetSelectedColumn(dataTable, null); |
| | | dataTable.Columns.Clear(); |
| | | dataTable.Columns.Add(temp); |
| | | foreach (var data in Datas) |
| | |
| | | DataGridTextColumn textColumn = new DataGridTextColumn |
| | | { |
| | | Header = header, |
| | | Binding = new Binding(bindingPath) |
| | | , |
| | | Binding = new Binding(bindingPath), |
| | | Width = new DataGridLength(1, DataGridLengthUnitType.Star) |
| | | }; |
| | | dataTable.Columns.Add(textColumn); |
| | | } |
| | | |
| | | private void dataTable_PreviewMouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e) |
| | | { |
| | | // 获取点击的元素 |
| | | DependencyObject dep = (DependencyObject)e.OriginalSource; |
| | | |
| | | // 遍历找到 DataGridColumnHeader |
| | | while (dep != null && !(dep is DataGridColumnHeader) && !(dep is DataGridRow)) |
| | | { |
| | | dep = VisualTreeHelper.GetParent(dep); |
| | | } |
| | | HMI.UI.DpUtil.DataGridHelper.SetSelectedColumn(dataTable, null); |
| | | |
| | | if (dep is DataGridColumnHeader columnHeader) |
| | | { |
| | | // 获取列索引 |
| | | int columnIndex = columnHeader.Column.DisplayIndex; |
| | | |
| | | // 清除已有选择 |
| | | dataTable.SelectedCells.Clear(); |
| | | |
| | | // 遍历所有行,选中该列的所有单元格 |
| | | foreach (var item in dataTable.Items) |
| | | { |
| | | DataGridCellInfo cellInfo = new DataGridCellInfo(item, columnHeader.Column); |
| | | dataTable.SelectedCells.Add(cellInfo); |
| | | } |
| | | HMI.UI.DpUtil.DataGridHelper.SetSelectedColumn(dataTable, columnHeader.Column); |
| | | |
| | | e.Handled = true; // 防止默认行为 |
| | | } |
| | | else if (dep is DataGridRow row) |
| | | { |
| | | // 清除已有选择 |
| | | dataTable.SelectedCells.Clear(); |
| | | dataTable.SelectedItem = row.Item; |
| | | e.Handled = true; |
| | | } |
| | | } |
| | | |
| | | private void MenuItem_Click(object sender, RoutedEventArgs e) |
| | | { |
| | | DataGridColumn column = HMI.UI.DpUtil.DataGridHelper.GetSelectedColumn(dataTable); |
| | | |
| | | } |
| | | } |
| | | } |
| | |
| | | pu:WindowXModalDialog.ButtonPanelMargin="0,30,10,10"> |
| | | <Grid Margin="10"> |
| | | <StackPanel x:Name="formPanel"> |
| | | <pu:FormGroup ui:FormGroupHelper.IsRequired="True" Header="名称" GroupName="MyFormGroup"> |
| | | <pu:FormGroup dp:FormGroupHelper.IsRequired="True" Header="名称" GroupName="MyFormGroup"> |
| | | <TextBox Style="{StaticResource EditorTextBoxStyle}" x:Name="programInput"/> |
| | | </pu:FormGroup> |
| | | |
| | | <pu:FormGroup ui:FormGroupHelper.IsRequired="True" Header="数据文件" GroupName="MyFormGroup"> |
| | | <pu:FormGroup dp:FormGroupHelper.IsRequired="True" Header="数据文件" GroupName="MyFormGroup"> |
| | | <Grid> |
| | | <Grid.ColumnDefinitions> |
| | | <ColumnDefinition/> |
| | |
| | | </Grid> |
| | | </pu:FormGroup> |
| | | |
| | | <pu:FormGroup ui:FormGroupHelper.IsRequired="True" Header="数据表" GroupName="MyFormGroup"> |
| | | <pu:FormGroup dp:FormGroupHelper.IsRequired="True" Header="数据表" GroupName="MyFormGroup"> |
| | | <ComboBox Style="{StaticResource FormComboxStyle}" SelectedValuePath="Content" |
| | | x:Name="tableNameInput" SelectionChanged="ComboxSelectionChanged"/> |
| | | </pu:FormGroup> |
| | |
| | | using HMI.Core.Util; |
| | | using HMI.DataViewer.Entity; |
| | | using HMI.UI; |
| | | using HMI.UI.DpUtil; |
| | | using HMI.UI.Util; |
| | | using log4net; |
| | | using Microsoft.Win32; |
| | |
| | | </Grid.RowDefinitions> |
| | | |
| | | <Label Grid.Row="0" Grid.Column="0" Content="DI名称" |
| | | FontSize="{StaticResource TitleFontSize}"/> |
| | | FontSize="{StaticResource ContentFontSize}"/> |
| | | <ComboBox Grid.Row="0" Grid.Column="1" x:Name="diName" |
| | | IsEditable="True" Style="{StaticResource FormComboxStyle}"/> |
| | | |
| | |
| | | x:Name="diReset" Click="Button_Click">DI重置</Button> |
| | | |
| | | <Label Grid.Row="1" Grid.Column="0" Content="DI编号" |
| | | FontSize="{StaticResource TitleFontSize}"/> |
| | | FontSize="{StaticResource ContentFontSize}"/> |
| | | <ComboBox Grid.Row="1" Grid.Column="1" x:Name="diCode" |
| | | IsEditable="True" |
| | | Style="{StaticResource FormComboxStyle}"/> |
| | | |
| | | <Label Grid.Row="2" Grid.Column="0" Content="DI分组" |
| | | FontSize="{StaticResource TitleFontSize}"/> |
| | | FontSize="{StaticResource ContentFontSize}"/> |
| | | <ComboBox Grid.Row="2" Grid.Column="1" x:Name="diGroup" |
| | | IsEditable="True" Style="{StaticResource FormComboxStyle}"/> |
| | | |
| | |
| | | </Grid.RowDefinitions> |
| | | |
| | | <Label Grid.Row="0" Grid.Column="0" Content="DO名称" |
| | | FontSize="{StaticResource TitleFontSize}"/> |
| | | FontSize="{StaticResource ContentFontSize}"/> |
| | | <ComboBox Grid.Row="0" Grid.Column="1" x:Name="doName" |
| | | IsEditable="True" Style="{StaticResource FormComboxStyle}"/> |
| | | |
| | |
| | | >DO重置</Button> |
| | | |
| | | <Label Grid.Row="1" Grid.Column="0" Content="DO编号" |
| | | FontSize="{StaticResource TitleFontSize}"/> |
| | | FontSize="{StaticResource ContentFontSize}"/> |
| | | <ComboBox Grid.Row="1" Grid.Column="1" x:Name="doCode" |
| | | IsEditable="True" Style="{StaticResource FormComboxStyle}"/> |
| | | |
| | | <Label Grid.Row="2" Grid.Column="0" Content="DO分组" |
| | | FontSize="{StaticResource TitleFontSize}"/> |
| | | FontSize="{StaticResource ContentFontSize}"/> |
| | | <ComboBox Grid.Row="2" Grid.Column="1" x:Name="doGroup" |
| | | IsEditable="True" Style="{StaticResource FormComboxStyle}"/> |
| | | |
| | |
| | | /// <summary>The dis |
| | | /// DI口对象 |
| | | /// </summary> |
| | | private ObservableCollection<DIO> _dis = new ObservableCollection<DIO>() { |
| | | new DIO(null,null,null,false), |
| | | new DIO(null,null,null,true), |
| | | }; |
| | | private ObservableCollection<DIO> _dis = new ObservableCollection<DIO>(); |
| | | public ObservableCollection<DIO> Dis |
| | | { |
| | | get => _dis; |
| | | set { Set(ref _dis, value); } |
| | | } |
| | | |
| | | private ObservableCollection<DIO> _dos = new ObservableCollection<DIO>() { |
| | | new DIO(null,null,null,false), |
| | | new DIO(null,null,null,true), |
| | | }; |
| | | private ObservableCollection<DIO> _dos = new ObservableCollection<DIO>(); |
| | | public ObservableCollection<DIO> Dos |
| | | { |
| | | get => _dos; |
| | |
| | | xmlns:pu="https://opensource.panuon.com/wpf-ui" |
| | | xmlns:uic="clr-namespace:HMI.UI.Converter;assembly=HMI.UI" |
| | | xmlns:ui="clr-namespace:HMI.UI;assembly=HMI.UI" |
| | | xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI" |
| | | mc:Ignorable="d" |
| | | Title="Form" |
| | | SizeToContent="Height" |
| | |
| | | pu:WindowXModalDialog.ButtonPanelMargin="0,30,10,10"> |
| | | <Grid Margin="10"> |
| | | <StackPanel x:Name="formPanel"> |
| | | <pu:FormGroup ui:FormGroupHelper.IsRequired="True" |
| | | <pu:FormGroup dp:FormGroupHelper.IsRequired="True" |
| | | Header="I点读取标签" GroupName="MyFormGroup"> |
| | | <TextBox Style="{StaticResource EditorTextBoxStyle}" x:Name="iTag"/> |
| | | </pu:FormGroup> |
| | | |
| | | <pu:FormGroup ui:FormGroupHelper.IsRequired="True" |
| | | <pu:FormGroup dp:FormGroupHelper.IsRequired="True" |
| | | Header="Q点读取标签" GroupName="MyFormGroup"> |
| | | <TextBox Style="{StaticResource EditorTextBoxStyle}" x:Name="qTag"/> |
| | | </pu:FormGroup> |
| | |
| | | using HMI.Core.Util; |
| | | using HMI.IOMonitor.Entity; |
| | | using HMI.UI; |
| | | using HMI.UI.DpUtil; |
| | | using HMI.UI.Util; |
| | | using log4net; |
| | | using Panuon.WPF.UI; |
| New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?> |
| | | <Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
| | | <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> |
| | | <PropertyGroup> |
| | | <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> |
| | | <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> |
| | | <ProjectGuid>{20C23602-B029-4E21-8C11-B9E5F2223237}</ProjectGuid> |
| | | <OutputType>library</OutputType> |
| | | <RootNamespace>HMI.LogViewer</RootNamespace> |
| | | <AssemblyName>HMI.LogViewer</AssemblyName> |
| | | <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion> |
| | | <FileAlignment>512</FileAlignment> |
| | | <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> |
| | | <WarningLevel>4</WarningLevel> |
| | | <Deterministic>true</Deterministic> |
| | | </PropertyGroup> |
| | | <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> |
| | | <DebugSymbols>true</DebugSymbols> |
| | | <DebugType>full</DebugType> |
| | | <Optimize>false</Optimize> |
| | | <OutputPath>bin\Debug\</OutputPath> |
| | | <DefineConstants>DEBUG;TRACE</DefineConstants> |
| | | <ErrorReport>prompt</ErrorReport> |
| | | <WarningLevel>4</WarningLevel> |
| | | </PropertyGroup> |
| | | <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> |
| | | <DebugType>pdbonly</DebugType> |
| | | <Optimize>true</Optimize> |
| | | <OutputPath>bin\Release\</OutputPath> |
| | | <DefineConstants>TRACE</DefineConstants> |
| | | <ErrorReport>prompt</ErrorReport> |
| | | <WarningLevel>4</WarningLevel> |
| | | </PropertyGroup> |
| | | <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'"> |
| | | <DebugSymbols>true</DebugSymbols> |
| | | <OutputPath>bin\x64\Debug\</OutputPath> |
| | | <DefineConstants>DEBUG;TRACE</DefineConstants> |
| | | <DebugType>full</DebugType> |
| | | <PlatformTarget>x64</PlatformTarget> |
| | | <LangVersion>7.3</LangVersion> |
| | | <ErrorReport>prompt</ErrorReport> |
| | | </PropertyGroup> |
| | | <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'"> |
| | | <OutputPath>bin\x64\Release\</OutputPath> |
| | | <DefineConstants>TRACE</DefineConstants> |
| | | <Optimize>true</Optimize> |
| | | <DebugType>pdbonly</DebugType> |
| | | <PlatformTarget>x64</PlatformTarget> |
| | | <LangVersion>7.3</LangVersion> |
| | | <ErrorReport>prompt</ErrorReport> |
| | | </PropertyGroup> |
| | | <ItemGroup> |
| | | <Reference Include="log4net, Version=3.0.3.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL"> |
| | | <HintPath>..\WPFProject\packages\log4net.3.0.3\lib\net462\log4net.dll</HintPath> |
| | | </Reference> |
| | | <Reference Include="Panuon.WPF, Version=1.1.2.2, Culture=neutral, processorArchitecture=MSIL"> |
| | | <HintPath>..\WPFProject\packages\Panuon.WPF.1.1.2.2\lib\net472\Panuon.WPF.dll</HintPath> |
| | | </Reference> |
| | | <Reference Include="Panuon.WPF.UI, Version=1.2.4.8, Culture=neutral, processorArchitecture=MSIL"> |
| | | <HintPath>..\WPFProject\packages\Panuon.WPF.UI.1.2.4.9\lib\net472\Panuon.WPF.UI.dll</HintPath> |
| | | </Reference> |
| | | <Reference Include="System" /> |
| | | <Reference Include="System.Configuration" /> |
| | | <Reference Include="System.Data" /> |
| | | <Reference Include="System.Web" /> |
| | | <Reference Include="System.Xml" /> |
| | | <Reference Include="Microsoft.CSharp" /> |
| | | <Reference Include="System.Core" /> |
| | | <Reference Include="System.Xml.Linq" /> |
| | | <Reference Include="System.Data.DataSetExtensions" /> |
| | | <Reference Include="System.Net.Http" /> |
| | | <Reference Include="System.Xaml"> |
| | | <RequiredTargetFramework>4.0</RequiredTargetFramework> |
| | | </Reference> |
| | | <Reference Include="WindowsBase" /> |
| | | <Reference Include="PresentationCore" /> |
| | | <Reference Include="PresentationFramework" /> |
| | | </ItemGroup> |
| | | <ItemGroup> |
| | | <Page Include="LogViewer.xaml"> |
| | | <Generator>MSBuild:Compile</Generator> |
| | | <SubType>Designer</SubType> |
| | | </Page> |
| | | <Compile Include="LogViewer.xaml.cs"> |
| | | <DependentUpon>LogViewer.xaml</DependentUpon> |
| | | <SubType>Code</SubType> |
| | | </Compile> |
| | | </ItemGroup> |
| | | <ItemGroup> |
| | | <Compile Include="Properties\AssemblyInfo.cs"> |
| | | <SubType>Code</SubType> |
| | | </Compile> |
| | | <Compile Include="Properties\Resources.Designer.cs"> |
| | | <AutoGen>True</AutoGen> |
| | | <DesignTime>True</DesignTime> |
| | | <DependentUpon>Resources.resx</DependentUpon> |
| | | </Compile> |
| | | <Compile Include="Properties\Settings.Designer.cs"> |
| | | <AutoGen>True</AutoGen> |
| | | <DependentUpon>Settings.settings</DependentUpon> |
| | | <DesignTimeSharedInput>True</DesignTimeSharedInput> |
| | | </Compile> |
| | | <EmbeddedResource Include="Properties\Resources.resx"> |
| | | <Generator>ResXFileCodeGenerator</Generator> |
| | | <LastGenOutput>Resources.Designer.cs</LastGenOutput> |
| | | </EmbeddedResource> |
| | | <None Include="packages.config" /> |
| | | <None Include="Properties\Settings.settings"> |
| | | <Generator>SettingsSingleFileGenerator</Generator> |
| | | <LastGenOutput>Settings.Designer.cs</LastGenOutput> |
| | | </None> |
| | | </ItemGroup> |
| | | <ItemGroup> |
| | | <ProjectReference Include="..\HMI.Base\HMI.Base.csproj"> |
| | | <Project>{2a6f9720-a890-4036-9d73-41a0dae28341}</Project> |
| | | <Name>HMI.Base</Name> |
| | | </ProjectReference> |
| | | <ProjectReference Include="..\HMI.Core\HMI.Core.csproj"> |
| | | <Project>{3e3bf44a-0b69-45c5-9512-528cb48a7106}</Project> |
| | | <Name>HMI.Core</Name> |
| | | </ProjectReference> |
| | | <ProjectReference Include="..\HMI.UI\HMI.UI.csproj"> |
| | | <Project>{f17de6b5-af1d-48c6-94a0-6b763a6546a6}</Project> |
| | | <Name>HMI.UI</Name> |
| | | </ProjectReference> |
| | | </ItemGroup> |
| | | <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> |
| | | <PropertyGroup> |
| | | <PostBuildEvent>copy /Y "$(TargetPath)" "$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)\Plugin\$(TargetFileName)" |
| | | copy /Y "$(TargetDir)$(TargetName).pdb" "$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)\Plugin\$(TargetName).pdb"</PostBuildEvent> |
| | | </PropertyGroup> |
| | | </Project> |
| New file |
| | |
| | | <hb:PluginControl x:Class="HMI.LogViewer.LogViewer" |
| | | xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
| | | xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
| | | xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" |
| | | xmlns:d="http://schemas.microsoft.com/expression/blend/2008" |
| | | xmlns:hb="clr-namespace:HMI.Base;assembly=HMI.Base" |
| | | xmlns:local="clr-namespace:HMI.LogViewer" |
| | | xmlns:uic="clr-namespace:HMI.UI.Converter;assembly=HMI.UI" |
| | | xmlns:pw="https://opensource.panuon.com/wpf" |
| | | xmlns:pu="https://opensource.panuon.com/wpf-ui" |
| | | xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI" |
| | | mc:Ignorable="d" |
| | | Loaded="UserControl_Loaded" |
| | | Background="{StaticResource WorkspaceBackground}" |
| | | d:DesignHeight="450" d:DesignWidth="800"> |
| | | |
| | | <UserControl.Resources> |
| | | <ResourceDictionary> |
| | | <ResourceDictionary.MergedDictionaries> |
| | | <ResourceDictionary Source="/HMI.UI;component/Style/PanuonResource.xaml"/> |
| | | <ResourceDictionary Source="/HMI.UI;component/Style/FormStyle.xaml"/> |
| | | <ResourceDictionary Source="/HMI.UI;component/Style/Colors.xaml"/> |
| | | <ResourceDictionary Source="/HMI.UI;component/Resources/Font/Font.xaml"/> |
| | | </ResourceDictionary.MergedDictionaries> |
| | | <uic:PathImageConverter x:Key="path2Image"/> |
| | | <uic:DataGridRowNumberConverter x:Key="rowNumber"/> |
| | | </ResourceDictionary> |
| | | </UserControl.Resources> |
| | | |
| | | <Border Style="{StaticResource CardBoarder}"> |
| | | |
| | | |
| | | <Grid dp:GridHelper.Space="10" Cursor=""> |
| | | <Grid.RowDefinitions> |
| | | <RowDefinition Height="Auto"/> |
| | | <RowDefinition Height="Auto"/> |
| | | <RowDefinition/> |
| | | </Grid.RowDefinitions> |
| | | |
| | | <TextBlock FontSize="{StaticResource TitleFontSize}" |
| | | VerticalAlignment="Center" HorizontalAlignment="Left" Text="日志查询"/> |
| | | |
| | | <DockPanel Grid.Row="1" Cursor=""> |
| | | <StackPanel DockPanel.Dock="Right" Style="{StaticResource ButtonGroup}"> |
| | | <Button Style="{StaticResource PrimaryButton}" pu:ButtonHelper.Icon="" |
| | | x:Name="queryBtn" Click="Button_Click">查询</Button> |
| | | <Button Style="{StaticResource PrimaryButton}" pu:ButtonHelper.Icon="" |
| | | x:Name="resetBtn" Click="Button_Click" Cursor="Hand">重置</Button> |
| | | <Button x:Name="exportBtn" |
| | | Style="{StaticResource PrimaryButton}" Click="Button_Click">导出</Button> |
| | | </StackPanel> |
| | | |
| | | <StackPanel Style="{StaticResource ButtonGroup}" HorizontalAlignment="Left"> |
| | | <TextBlock Style="{StaticResource TitleBox}" FontSize="14" Text="级别"/> |
| | | <ComboBox Style="{StaticResource FormComboxStyle}" x:Name="levelInput" |
| | | Width="180" |
| | | SelectedValuePath="Content"> |
| | | <ComboBoxItem Content="info"/> |
| | | <ComboBoxItem Content="warn"/> |
| | | <ComboBoxItem Content="error"/> |
| | | </ComboBox> |
| | | |
| | | <TextBlock Style="{StaticResource TitleBox}" FontSize="14" Text="开始时间"/> |
| | | <pu:DateTimePicker Style="{StaticResource TimePicker}" x:Name="startTimeInput"/> |
| | | |
| | | <TextBlock Style="{StaticResource TitleBox}" FontSize="14" Text="结束时间"/> |
| | | <pu:DateTimePicker Style="{StaticResource TimePicker}" x:Name="endTimeInput"/> |
| | | |
| | | <TextBlock Style="{StaticResource TitleBox}" FontSize="14" Text="来源"/> |
| | | <!--<ComboBox Style="{StaticResource FormComboxStyle}" x:Name="sourceInput" Width="180"></ComboBox>--> |
| | | <TextBox Style="{StaticResource EditorTextBoxStyle}" x:Name="sourceInput" Width="180"/> |
| | | |
| | | <TextBlock Style="{StaticResource TitleBox}" FontSize="14" Text="实时刷新"/> |
| | | <CheckBox x:Name="autoRfhInput" HorizontalAlignment="Center" VerticalAlignment="Center" |
| | | IsChecked="{Binding AutoRfh,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" |
| | | /> |
| | | </StackPanel> |
| | | </DockPanel> |
| | | |
| | | |
| | | <DataGrid Grid.Row="2" x:Name="table" Style="{StaticResource DefaultDataGrid}"> |
| | | <DataGrid.RowStyle> |
| | | <Style TargetType="DataGridRow" BasedOn="{StaticResource {x:Static pu:StyleKeys.DataGridRowStyle}}"> |
| | | <Style.Triggers> |
| | | <DataTrigger Binding="{Binding type}" Value="warn"> |
| | | <Setter Property="Background" Value="{StaticResource WarningColor}"/> |
| | | <Setter Property="Foreground" Value="Black"/> |
| | | </DataTrigger> |
| | | <DataTrigger Binding="{Binding type}" Value="error"> |
| | | <Setter Property="Background" Value="{StaticResource DangerColor}"/> |
| | | <Setter Property="Foreground" Value="Black"/> |
| | | </DataTrigger> |
| | | <Trigger Property="IsSelected" Value="True"> |
| | | <Setter Property="Background" Value="Transparent"/> |
| | | </Trigger> |
| | | <Trigger Property="IsMouseOver" Value="True"> |
| | | <Setter Property="Background" Value="Transparent"/> |
| | | </Trigger> |
| | | </Style.Triggers> |
| | | </Style> |
| | | </DataGrid.RowStyle> |
| | | <DataGrid.Columns> |
| | | <DataGridTemplateColumn Header="" Width="Auto" CanUserResize="False"> |
| | | <DataGridTemplateColumn.CellTemplate> |
| | | <DataTemplate> |
| | | <CheckBox VerticalAlignment="Center" IsChecked="{Binding Selected,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/> |
| | | </DataTemplate> |
| | | </DataGridTemplateColumn.CellTemplate> |
| | | </DataGridTemplateColumn> |
| | | <DataGridTemplateColumn Header="#" CanUserResize="False"> |
| | | <DataGridTemplateColumn.CellTemplate> |
| | | <DataTemplate> |
| | | <TextBlock Text="{Binding Converter={StaticResource rowNumber}, |
| | | RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGridRow},AncestorLevel=1}}"/> |
| | | </DataTemplate> |
| | | </DataGridTemplateColumn.CellTemplate> |
| | | </DataGridTemplateColumn> |
| | | <DataGridTextColumn Width="*" Binding="{Binding type}" Header="级别" /> |
| | | <DataGridTextColumn Width="*" Binding="{Binding time}" Header="时间" /> |
| | | <DataGridTextColumn Width="*" Binding="{Binding source}" Header="来源" /> |
| | | <DataGridTextColumn Width="*" Binding="{Binding text}" Header="文本" /> |
| | | </DataGrid.Columns> |
| | | </DataGrid> |
| | | </Grid> |
| | | </Border> |
| | | </hb:PluginControl> |
| New file |
| | |
| | | using HMI.Base; |
| | | using HMI.Core.Util; |
| | | using HMI.UI.Util; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Data; |
| | | using System.IO; |
| | | using System.Timers; |
| | | using System.Windows; |
| | | using System.Windows.Controls; |
| | | |
| | | namespace HMI.LogViewer |
| | | { |
| | | /// <summary> |
| | | /// UserControl1.xaml 的交互逻辑 |
| | | /// </summary> |
| | | public partial class LogViewer : PluginControl |
| | | { |
| | | private string logDir; |
| | | private string todayLogFile; |
| | | |
| | | private bool autoRfh; |
| | | |
| | | public bool AutoRfh |
| | | { |
| | | get { return autoRfh; } |
| | | set |
| | | { |
| | | Set(ref autoRfh, value); |
| | | if (autoRfhTimer != null) autoRfhTimer.Enabled = value; |
| | | } |
| | | } |
| | | |
| | | private Timer autoRfhTimer; |
| | | |
| | | |
| | | public LogViewer() |
| | | { |
| | | string logDir = Path.Combine(PathHelper.AppFolder, "Log"); |
| | | todayLogFile = Path.Combine(logDir, $"log{DateTime.Now.ToString("yyyy-MM-dd")}.db"); |
| | | |
| | | if (!Directory.Exists(logDir)) |
| | | { |
| | | Directory.CreateDirectory(logDir); |
| | | } |
| | | this.logDir = logDir; |
| | | DataContext = this; |
| | | InitializeComponent(); |
| | | } |
| | | |
| | | public override void InitFinish() |
| | | { |
| | | base.InitFinish(); |
| | | string baseFile = Path.Combine(logDir, "log.db"); |
| | | |
| | | try |
| | | { |
| | | if (!File.Exists(baseFile)) |
| | | { |
| | | SqliteHelper.CreateDatabase(baseFile); |
| | | } |
| | | SqliteHelper sqliteHelper = new SqliteHelper(baseFile); |
| | | sqliteHelper.ExecuteSql(@"CREATE TABLE IF NOT EXISTS log ( |
| | | id INTEGER PRIMARY KEY AUTOINCREMENT, |
| | | type TEXT NOT NULL, |
| | | text TEXT NOT NULL, |
| | | source TEXT, |
| | | time TIME |
| | | );"); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | log.Error("Create Log File Failed.", ex); |
| | | } |
| | | } |
| | | |
| | | |
| | | private void UserControl_Loaded(object sender, RoutedEventArgs e) |
| | | { |
| | | autoRfhTimer = new Timer |
| | | { |
| | | Enabled = false, |
| | | Interval = 1000 |
| | | }; |
| | | autoRfhTimer.Elapsed += AutoRfhTimer_Elapsed; |
| | | Loaded -= UserControl_Loaded; |
| | | } |
| | | |
| | | private void AutoRfhTimer_Elapsed(object sender, ElapsedEventArgs e) |
| | | { |
| | | Refresh100items(); |
| | | } |
| | | |
| | | private void Button_Click(object sender, RoutedEventArgs e) |
| | | { |
| | | Button btn = sender as Button; |
| | | switch (btn.Name) |
| | | { |
| | | case "queryBtn": |
| | | QueryLog(); |
| | | break; |
| | | case "resetBtn": |
| | | QueryReset(); |
| | | break; |
| | | case "exportBtn": |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | } |
| | | |
| | | private void QueryLog() |
| | | { |
| | | try |
| | | { |
| | | queryBtn.IsEnabled = false; |
| | | autoRfhInput.IsEnabled = false; |
| | | Filtrate(); |
| | | queryBtn.IsEnabled = true; |
| | | autoRfhInput.IsEnabled = true; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | log.Error("Log Query Failed.", ex); |
| | | this.Error($"查询失败!{ex.Message}"); |
| | | } |
| | | } |
| | | |
| | | private void QueryReset() |
| | | { |
| | | levelInput.Text = null; |
| | | startTimeInput.SelectedDateTime = null; |
| | | endTimeInput.SelectedDateTime = null; |
| | | startTimeInput.Text = null; |
| | | table.ItemsSource = null; |
| | | } |
| | | |
| | | private void Filtrate() |
| | | { |
| | | string str = LoadSql(); |
| | | DataTable dt = new DataTable(); |
| | | var files = Directory.GetFiles(logDir, "*.db"); |
| | | foreach (string file in files) |
| | | { |
| | | SqliteHelper sql = new SqliteHelper(file); |
| | | dt.Merge(sql.GetDataTable(str)); |
| | | sql.Close(); |
| | | } |
| | | |
| | | dt.DefaultView.Sort = "time Desc"; |
| | | table.ItemsSource = dt.DefaultView; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 加载界面判断数据库语句 |
| | | /// </summary> |
| | | /// <returns> str数据库的语句 </returns> |
| | | private string LoadSql() |
| | | { |
| | | string sql = " select type,time,source,text from log"; |
| | | |
| | | List<string> datas = new List<string>(); |
| | | if (!string.IsNullOrEmpty(levelInput.Text)) |
| | | { |
| | | datas.Add($"type='{levelInput.Text}'"); |
| | | } |
| | | if (!string.IsNullOrEmpty(startTimeInput.Text)) |
| | | { |
| | | datas.Add($"time>='{startTimeInput.Text}'"); |
| | | } |
| | | if (!string.IsNullOrEmpty(endTimeInput.Text)) |
| | | { |
| | | datas.Add($"time<='{endTimeInput.Text}'"); |
| | | } |
| | | if (!string.IsNullOrEmpty(sourceInput.Text)) |
| | | { |
| | | datas.Add($"source='{sourceInput.Text}'"); |
| | | } |
| | | |
| | | string condition = string.Join(" AND ", datas); |
| | | condition = string.IsNullOrEmpty(condition) ? string.Empty : $" WHERE {condition}"; |
| | | |
| | | sql = $"{sql}{condition} order by time desc"; |
| | | return sql; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 刷新100条数据 |
| | | /// </summary> |
| | | private void Refresh100items() |
| | | { |
| | | try |
| | | { |
| | | if (!File.Exists(todayLogFile)) return; |
| | | string str = "select type,time,source,text from log order by time desc limit 100"; |
| | | SqliteHelper sql = new SqliteHelper(todayLogFile); |
| | | var dt = sql.GetDataTable(str); |
| | | this.Dispatcher.BeginInvoke((Action)delegate () |
| | | { |
| | | table.ItemsSource = dt.DefaultView; |
| | | }); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | log.Error("Log Auto Refresh Failed.", ex); |
| | | this.Error($"自动刷新失败!{ex.Message}"); |
| | | } |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | using System.Reflection; |
| | | using System.Resources; |
| | | using System.Runtime.CompilerServices; |
| | | using System.Runtime.InteropServices; |
| | | using System.Windows; |
| | | |
| | | // 有关程序集的一般信息由以下 |
| | | // 控制。更改这些特性值可修改 |
| | | // 与程序集关联的信息。 |
| | | [assembly: AssemblyTitle("HMI.LogViewer")] |
| | | [assembly: AssemblyDescription("")] |
| | | [assembly: AssemblyConfiguration("")] |
| | | [assembly: AssemblyCompany("")] |
| | | [assembly: AssemblyProduct("HMI.LogViewer")] |
| | | [assembly: AssemblyCopyright("Copyright © 2025")] |
| | | [assembly: AssemblyTrademark("")] |
| | | [assembly: AssemblyCulture("")] |
| | | |
| | | // 将 ComVisible 设置为 false 会使此程序集中的类型 |
| | | //对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 |
| | | //请将此类型的 ComVisible 特性设置为 true。 |
| | | [assembly: ComVisible(false)] |
| | | |
| | | //若要开始生成可本地化的应用程序,请设置 |
| | | //.csproj 文件中的 <UICulture>CultureYouAreCodingWith</UICulture> |
| | | //在 <PropertyGroup> 中。例如,如果你使用的是美国英语。 |
| | | //使用的是美国英语,请将 <UICulture> 设置为 en-US。 然后取消 |
| | | //对以下 NeutralResourceLanguage 特性的注释。 更新 |
| | | //以下行中的“en-US”以匹配项目文件中的 UICulture 设置。 |
| | | |
| | | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] |
| | | |
| | | |
| | | [assembly:ThemeInfo( |
| | | ResourceDictionaryLocation.None, //主题特定资源词典所处位置 |
| | | //(未在页面中找到资源时使用, |
| | | //或应用程序资源字典中找到时使用) |
| | | ResourceDictionaryLocation.SourceAssembly //常规资源词典所处位置 |
| | | //(未在页面中找到资源时使用, |
| | | //、应用程序或任何主题专用资源字典中找到时使用) |
| | | )] |
| | | |
| | | |
| | | // 程序集的版本信息由下列四个值组成: |
| | | // |
| | | // 主版本 |
| | | // 次版本 |
| | | // 生成号 |
| | | // 修订号 |
| | | // |
| | | [assembly: AssemblyVersion("1.0.0.0")] |
| | | [assembly: AssemblyFileVersion("1.0.0.0")] |
| New file |
| | |
| | | //------------------------------------------------------------------------------ |
| | | // <auto-generated> |
| | | // 此代码由工具生成。 |
| | | // 运行时版本: 4.0.30319.42000 |
| | | // |
| | | // 对此文件的更改可能导致不正确的行为,如果 |
| | | // 重新生成代码,则所做更改将丢失。 |
| | | // </auto-generated> |
| | | //------------------------------------------------------------------------------ |
| | | |
| | | namespace HMI.LogViewer.Properties { |
| | | |
| | | |
| | | /// <summary> |
| | | /// 强类型资源类,用于查找本地化字符串等。 |
| | | /// </summary> |
| | | // 此类是由 StronglyTypedResourceBuilder |
| | | // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 |
| | | // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen |
| | | // (以 /str 作为命令选项),或重新生成 VS 项目。 |
| | | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] |
| | | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] |
| | | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] |
| | | internal class Resources { |
| | | |
| | | private static global::System.Resources.ResourceManager resourceMan; |
| | | |
| | | private static global::System.Globalization.CultureInfo resourceCulture; |
| | | |
| | | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] |
| | | internal Resources() { |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 返回此类使用的缓存 ResourceManager 实例。 |
| | | /// </summary> |
| | | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] |
| | | internal static global::System.Resources.ResourceManager ResourceManager { |
| | | get { |
| | | if ((resourceMan == null)) { |
| | | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("HMI.LogViewer.Properties.Resources", typeof(Resources).Assembly); |
| | | resourceMan = temp; |
| | | } |
| | | return resourceMan; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 重写当前线程的 CurrentUICulture 属性,对 |
| | | /// 使用此强类型资源类的所有资源查找执行重写。 |
| | | /// </summary> |
| | | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] |
| | | internal static global::System.Globalization.CultureInfo Culture { |
| | | get { |
| | | return resourceCulture; |
| | | } |
| | | set { |
| | | resourceCulture = value; |
| | | } |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?> |
| | | <root> |
| | | <!-- |
| | | Microsoft ResX Schema |
| | | |
| | | Version 2.0 |
| | | |
| | | The primary goals of this format is to allow a simple XML format |
| | | that is mostly human readable. The generation and parsing of the |
| | | various data types are done through the TypeConverter classes |
| | | associated with the data types. |
| | | |
| | | Example: |
| | | |
| | | ... ado.net/XML headers & schema ... |
| | | <resheader name="resmimetype">text/microsoft-resx</resheader> |
| | | <resheader name="version">2.0</resheader> |
| | | <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> |
| | | <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> |
| | | <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> |
| | | <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> |
| | | <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> |
| | | <value>[base64 mime encoded serialized .NET Framework object]</value> |
| | | </data> |
| | | <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> |
| | | <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> |
| | | <comment>This is a comment</comment> |
| | | </data> |
| | | |
| | | There are any number of "resheader" rows that contain simple |
| | | name/value pairs. |
| | | |
| | | Each data row contains a name, and value. The row also contains a |
| | | type or mimetype. Type corresponds to a .NET class that support |
| | | text/value conversion through the TypeConverter architecture. |
| | | Classes that don't support this are serialized and stored with the |
| | | mimetype set. |
| | | |
| | | The mimetype is used for serialized objects, and tells the |
| | | ResXResourceReader how to depersist the object. This is currently not |
| | | extensible. For a given mimetype the value must be set accordingly: |
| | | |
| | | Note - application/x-microsoft.net.object.binary.base64 is the format |
| | | that the ResXResourceWriter will generate, however the reader can |
| | | read any of the formats listed below. |
| | | |
| | | mimetype: application/x-microsoft.net.object.binary.base64 |
| | | value : The object must be serialized with |
| | | : System.Serialization.Formatters.Binary.BinaryFormatter |
| | | : and then encoded with base64 encoding. |
| | | |
| | | mimetype: application/x-microsoft.net.object.soap.base64 |
| | | value : The object must be serialized with |
| | | : System.Runtime.Serialization.Formatters.Soap.SoapFormatter |
| | | : and then encoded with base64 encoding. |
| | | |
| | | mimetype: application/x-microsoft.net.object.bytearray.base64 |
| | | value : The object must be serialized into a byte array |
| | | : using a System.ComponentModel.TypeConverter |
| | | : and then encoded with base64 encoding. |
| | | --> |
| | | <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> |
| | | <xsd:element name="root" msdata:IsDataSet="true"> |
| | | <xsd:complexType> |
| | | <xsd:choice maxOccurs="unbounded"> |
| | | <xsd:element name="metadata"> |
| | | <xsd:complexType> |
| | | <xsd:sequence> |
| | | <xsd:element name="value" type="xsd:string" minOccurs="0" /> |
| | | </xsd:sequence> |
| | | <xsd:attribute name="name" type="xsd:string" /> |
| | | <xsd:attribute name="type" type="xsd:string" /> |
| | | <xsd:attribute name="mimetype" type="xsd:string" /> |
| | | </xsd:complexType> |
| | | </xsd:element> |
| | | <xsd:element name="assembly"> |
| | | <xsd:complexType> |
| | | <xsd:attribute name="alias" type="xsd:string" /> |
| | | <xsd:attribute name="name" type="xsd:string" /> |
| | | </xsd:complexType> |
| | | </xsd:element> |
| | | <xsd:element name="data"> |
| | | <xsd:complexType> |
| | | <xsd:sequence> |
| | | <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> |
| | | <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> |
| | | </xsd:sequence> |
| | | <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" /> |
| | | <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> |
| | | <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> |
| | | </xsd:complexType> |
| | | </xsd:element> |
| | | <xsd:element name="resheader"> |
| | | <xsd:complexType> |
| | | <xsd:sequence> |
| | | <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> |
| | | </xsd:sequence> |
| | | <xsd:attribute name="name" type="xsd:string" use="required" /> |
| | | </xsd:complexType> |
| | | </xsd:element> |
| | | </xsd:choice> |
| | | </xsd:complexType> |
| | | </xsd:element> |
| | | </xsd:schema> |
| | | <resheader name="resmimetype"> |
| | | <value>text/microsoft-resx</value> |
| | | </resheader> |
| | | <resheader name="version"> |
| | | <value>2.0</value> |
| | | </resheader> |
| | | <resheader name="reader"> |
| | | <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> |
| | | </resheader> |
| | | <resheader name="writer"> |
| | | <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> |
| | | </resheader> |
| | | </root> |
| New file |
| | |
| | | //------------------------------------------------------------------------------ |
| | | // <auto-generated> |
| | | // This code was generated by a tool. |
| | | // Runtime Version:4.0.30319.42000 |
| | | // |
| | | // Changes to this file may cause incorrect behavior and will be lost if |
| | | // the code is regenerated. |
| | | // </auto-generated> |
| | | //------------------------------------------------------------------------------ |
| | | |
| | | namespace HMI.LogViewer.Properties |
| | | { |
| | | |
| | | |
| | | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] |
| | | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] |
| | | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase |
| | | { |
| | | |
| | | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); |
| | | |
| | | public static Settings Default |
| | | { |
| | | get |
| | | { |
| | | return defaultInstance; |
| | | } |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | <?xml version='1.0' encoding='utf-8'?> |
| | | <SettingsFile xmlns="uri:settings" CurrentProfile="(Default)"> |
| | | <Profiles> |
| | | <Profile Name="(Default)" /> |
| | | </Profiles> |
| | | <Settings /> |
| | | </SettingsFile> |
| New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?> |
| | | <packages> |
| | | <package id="log4net" version="3.0.3" targetFramework="net472" /> |
| | | <package id="Panuon.WPF" version="1.1.2.2" targetFramework="net472" /> |
| | | <package id="Panuon.WPF.UI" version="1.2.4.9" targetFramework="net472" /> |
| | | </packages> |
| | |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | using HMI.Core.Entity; |
| | | |
| | | namespace HMI.ParameterManage.Entity |
| | | { |
| | | public class ParameterData |
| | | public class ParameterData : SelectBase |
| | | { |
| | | public string Id { get; set; } |
| | | public string Name { get; set; } |
| | |
| | | |
| | | using HMI.Core.Entity; |
| | | using System.Xml.Serialization; |
| | | |
| | | namespace HMI.ParameterManage.Entity |
| | | { |
| | | public class ProductData |
| | | public class ProductData:SelectBase |
| | | { |
| | | [XmlIgnore] |
| | | public string Id { get; set; } |
| | | public string Name { get; set; } |
| | | public bool IsMaster { get; set; } |
| | |
| | | <Compile Include="ProductModal.xaml.cs"> |
| | | <DependentUpon>ProductModal.xaml</DependentUpon> |
| | | </Compile> |
| | | <Compile Include="Model\XmlModel.cs" /> |
| | | <Page Include="ParameterManage.xaml"> |
| | | <Generator>MSBuild:Compile</Generator> |
| | | <SubType>Designer</SubType> |
| | | </Page> |
| | | <Compile Include="ControlModel.cs" /> |
| | | <Compile Include="Model\SqlModel.cs" /> |
| | | <Compile Include="Entity\ParameterData.cs" /> |
| | | <Compile Include="Entity\ProductData.cs" /> |
| | | <Compile Include="ParameterManage.xaml.cs"> |
| File was renamed from HMI.ParameterManage/ControlModel.cs |
| | |
| | | using System.Collections.ObjectModel; |
| | | using System.Data; |
| | | using System.IO; |
| | | using HMI.Core.Entity; |
| | | using HMI.Core.Util; |
| | | using HMI.ParameterManage.Entity; |
| | | |
| | | namespace HMI.ParameterManage |
| | | namespace HMI.ParameterManage.Model |
| | | { |
| | | public class ControlModel : NotifyBase |
| | | |
| | | public class SqlModel : NotifyBase |
| | | { |
| | | public ControlModel(SqliteHelper sqliteHelper) |
| | | public SqlModel(string baseFolder) |
| | | { |
| | | SqliteHelper = sqliteHelper; |
| | | string dbpath = Path.Combine(baseFolder, "ParameterManage.db"); |
| | | if (!File.Exists(dbpath)) |
| | | { |
| | | SqliteHelper.CreateDatabase(dbpath); |
| | | } |
| | | SqliteHelper = new SqliteHelper(dbpath); |
| | | SqliteHelper.ExecuteSql(@"CREATE TABLE IF NOT EXISTS product ( |
| | | id INTEGER PRIMARY KEY AUTOINCREMENT, |
| | | name TEXT NOT NULL, |
| | | isMaster INTEGER, |
| | | parentId INTEGER, |
| | | UNIQUE(name) |
| | | ); |
| | | CREATE TABLE IF NOT EXISTS parameter ( |
| | | id INTEGER PRIMARY KEY AUTOINCREMENT, |
| | | name TEXT NOT NULL, |
| | | value TEXT, |
| | | unit TEXT, |
| | | description TEXT, |
| | | pGroup TEXT, |
| | | productName TEXT, |
| | | UNIQUE(productName,name) |
| | | );"); |
| | | } |
| | | |
| | | public SqliteHelper SqliteHelper { get; private set; } |
| New file |
| | |
| | | using HMI.Core.Entity; |
| | | using HMI.Core.Util; |
| | | using HMI.ParameterManage.Entity; |
| | | using System.Collections.ObjectModel; |
| | | using System.IO; |
| | | using System.Linq; |
| | | |
| | | namespace HMI.ParameterManage.Model |
| | | { |
| | | public class XmlModel : NotifyBase |
| | | { |
| | | private string ProductSettingFile; |
| | | private string ParameterSettingFolder; |
| | | |
| | | public XmlModel(string baseFolder) |
| | | { |
| | | ProductSettingFile = Path.Combine(baseFolder, "Product.setting"); |
| | | ParameterSettingFolder = Path.Combine(baseFolder, "Parameter"); |
| | | if (!Directory.Exists(ParameterSettingFolder)) |
| | | { |
| | | Directory.CreateDirectory(ParameterSettingFolder); |
| | | } |
| | | } |
| | | |
| | | private ObservableCollection<ProductData> products; |
| | | |
| | | public ObservableCollection<ProductData> Products |
| | | { |
| | | get { return products; } |
| | | set { Set(ref products, value); } |
| | | } |
| | | |
| | | private ObservableCollection<ParameterData> parameters; |
| | | |
| | | public ObservableCollection<ParameterData> Parameters |
| | | { |
| | | get { return parameters; } |
| | | set { Set(ref parameters, value); } |
| | | } |
| | | |
| | | private ProductData selectedProduct; |
| | | |
| | | public ProductData SelectedProduct |
| | | { |
| | | get { return selectedProduct; } |
| | | set |
| | | { |
| | | Set(ref selectedProduct, value); |
| | | LoadParameters(); |
| | | } |
| | | } |
| | | |
| | | private ParameterData selectedParameter; |
| | | |
| | | public ParameterData SelectedParameter |
| | | { |
| | | get { return selectedParameter; } |
| | | set |
| | | { |
| | | Set(ref selectedParameter, value); |
| | | } |
| | | } |
| | | |
| | | public bool ValidateProductName(object value, out string msg) |
| | | { |
| | | msg = null; |
| | | string name = value.ToString(); |
| | | if (Products == null) return true; |
| | | var temp = Products.FirstOrDefault(p => p.Name == name); |
| | | if (temp != null && temp != SelectedProduct) |
| | | { |
| | | msg = "产品名称不能重复"; |
| | | return false; |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | public bool ValidateParameterName(object value, out string msg) |
| | | { |
| | | msg = null; |
| | | string name = value.ToString(); |
| | | if (Products == null) return true; |
| | | var temp = Parameters.FirstOrDefault(p => p.Name == name); |
| | | if (temp != null && temp != SelectedParameter) |
| | | { |
| | | msg = "参数名称不能重复"; |
| | | return false; |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | public void LoadProducts() |
| | | { |
| | | ObservableCollection<ProductData> products; |
| | | if (File.Exists(ProductSettingFile)) |
| | | { |
| | | products = XmlHelper.DeserializeFromXml<ObservableCollection<ProductData>>(ProductSettingFile); |
| | | } |
| | | else |
| | | { |
| | | products = new ObservableCollection<ProductData>(); |
| | | } |
| | | Products = products; |
| | | } |
| | | |
| | | public void LoadParameters() |
| | | { |
| | | ObservableCollection<ParameterData> parameters = new ObservableCollection<ParameterData>(); |
| | | if (SelectedProduct != null) |
| | | { |
| | | string fileName = $"Parameter_{SelectedProduct.Name}.setting"; |
| | | string parameterSettingFile = Path.Combine(ParameterSettingFolder, fileName); |
| | | if (File.Exists(parameterSettingFile)) |
| | | { |
| | | parameters = XmlHelper.DeserializeFromXml<ObservableCollection<ParameterData>>(parameterSettingFile); |
| | | } |
| | | } |
| | | Parameters = parameters; |
| | | } |
| | | |
| | | public void SaveOrUpdateData(ProductData data) |
| | | { |
| | | int index = Products.IndexOf(data); |
| | | if (index > -1) |
| | | { |
| | | UpdateData(index, data); |
| | | } |
| | | else |
| | | { |
| | | InsertData(data); |
| | | } |
| | | } |
| | | |
| | | public void SaveOrUpdateParameter(ParameterData data) |
| | | { |
| | | int index = Parameters.IndexOf(data); |
| | | if (index > -1) |
| | | { |
| | | UpdateParameter(index, data); |
| | | } |
| | | else |
| | | { |
| | | InsertParameter(data); |
| | | } |
| | | } |
| | | |
| | | public void InsertData(ProductData data) |
| | | { |
| | | var temp = XmlHelper.DeepClone(Products); |
| | | temp.Add(data); |
| | | XmlHelper.SerializeToXml(ProductSettingFile, temp); |
| | | } |
| | | |
| | | public void UpdateData(int index, ProductData data) |
| | | { |
| | | var temp = XmlHelper.DeepClone(Products); |
| | | temp[index] = data; |
| | | XmlHelper.SerializeToXml(ProductSettingFile, temp); |
| | | } |
| | | |
| | | public void InsertParameter(ParameterData data) |
| | | { |
| | | var temp = XmlHelper.DeepClone(Parameters); |
| | | temp.Add(data); |
| | | string fileName = Path.Combine(ParameterSettingFolder, $"Parameter_{SelectedProduct.Name}.setting"); |
| | | XmlHelper.SerializeToXml(fileName, temp); |
| | | } |
| | | |
| | | public void UpdateParameter(int index, ParameterData data) |
| | | { |
| | | var temp = XmlHelper.DeepClone(Parameters); |
| | | temp[index] = data; |
| | | string fileName = Path.Combine(ParameterSettingFolder, $"Parameter_{SelectedProduct.Name}.setting"); |
| | | XmlHelper.SerializeToXml(fileName, temp); |
| | | } |
| | | |
| | | public void DeleteProduct(ProductData data) |
| | | { |
| | | int index = Products.IndexOf(data); |
| | | if (index > -1) |
| | | { |
| | | var temp = Products.Where(p => p != data).ToList(); |
| | | XmlHelper.SerializeToXml(ProductSettingFile, temp); |
| | | } |
| | | } |
| | | public void DeleteProducts() |
| | | { |
| | | var temp = Products.Where(p => !p.IsSelected).ToList(); |
| | | XmlHelper.SerializeToXml(ProductSettingFile, temp); |
| | | } |
| | | |
| | | public void DeleteParameter(ParameterData data) |
| | | { |
| | | int index = Parameters.IndexOf(data); |
| | | if (index > -1) |
| | | { |
| | | var temp = Parameters.Where(p => p != data).ToList(); |
| | | string fileName = Path.Combine(ParameterSettingFolder, $"Parameter_{SelectedProduct.Name}.setting"); |
| | | XmlHelper.SerializeToXml(fileName, temp); |
| | | } |
| | | } |
| | | |
| | | public void DeleteParameters() |
| | | { |
| | | var temp = Parameters.Where(p => !p.IsSelected).ToList(); |
| | | string fileName = Path.Combine(ParameterSettingFolder, $"Parameter_{SelectedProduct.Name}.setting"); |
| | | XmlHelper.SerializeToXml(fileName, temp); |
| | | } |
| | | } |
| | | } |
| | |
| | | d:DesignHeight="450" d:DesignWidth="800"> |
| | | <Grid> |
| | | <Grid.ColumnDefinitions> |
| | | <ColumnDefinition Width="2*"/> |
| | | <ColumnDefinition Width="8*"/> |
| | | <ColumnDefinition Width="3*"/> |
| | | <ColumnDefinition Width="7*"/> |
| | | </Grid.ColumnDefinitions> |
| | | <Border Style="{StaticResource CardBoarder}" Margin="0,0,2,0"> |
| | | <StackPanel> |
| | | <DockPanel Margin="0,0,0,10" Cursor=""> |
| | | <Button DockPanel.Dock="Right" x:Name="delBatchBtn" pu:ButtonHelper.Icon="" Style="{StaticResource DangerButton}">删除</Button> |
| | | <Button DockPanel.Dock="Right" Style="{StaticResource PrimaryButton}" |
| | | pu:ButtonHelper.Icon="" Margin="0,0,10,0" x:Name="refreshBtn" Click="Button_Click">刷新</Button> |
| | | <Button DockPanel.Dock="Right" Style="{StaticResource PrimaryButton}" |
| | | pu:ButtonHelper.Icon="" Margin="0,0,10,0" x:Name="addBtn" Click="Button_Click">新增</Button> |
| | | <Grid dp:GridHelper.Space="10"> |
| | | <Grid.RowDefinitions> |
| | | <RowDefinition Height="Auto"/> |
| | | <RowDefinition /> |
| | | </Grid.RowDefinitions> |
| | | <DockPanel> |
| | | <StackPanel DockPanel.Dock="Right" Style="{StaticResource ButtonGroup}"> |
| | | <Button Style="{StaticResource PrimaryButton}" |
| | | pu:ButtonHelper.Icon="" x:Name="addBtn" Click="Button_Click">新增</Button> |
| | | <Button Style="{StaticResource PrimaryButton}" |
| | | pu:ButtonHelper.Icon="" x:Name="refreshBtn" Click="Button_Click">刷新</Button> |
| | | <Button x:Name="delBatchBtn" |
| | | pu:ButtonHelper.Icon="" Style="{StaticResource DangerButton}" |
| | | Click="Button_Click">删除</Button> |
| | | </StackPanel> |
| | | <TextBlock DockPanel.Dock="Left" FontSize="{StaticResource TitleFontSize}" |
| | | VerticalAlignment="Center" HorizontalAlignment="Left" Text="产品列表"/> |
| | | VerticalAlignment="Center" HorizontalAlignment="Left" Text="产品列表"/> |
| | | </DockPanel> |
| | | |
| | | <DataGrid Grid.Column="1" x:Name="table" Style="{StaticResource DefaultDataGrid}" |
| | | |
| | | <DataGrid Grid.Row="1" x:Name="productTable" Style="{StaticResource DefaultDataGrid}" |
| | | SelectedItem="{Binding SelectedProduct}" ItemsSource="{Binding Products}"> |
| | | <DataGrid.Columns> |
| | | <DataGridTemplateColumn Width="Auto" CanUserResize="False"> |
| | | <DataGridTemplateColumn.CellTemplate> |
| | | <DataTemplate> |
| | | <CheckBox VerticalAlignment="Center" |
| | | IsChecked="{Binding Selected,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/> |
| | | IsChecked="{Binding IsSelected,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/> |
| | | </DataTemplate> |
| | | </DataGridTemplateColumn.CellTemplate> |
| | | </DataGridTemplateColumn> |
| | |
| | | </DataGridTemplateColumn> |
| | | </DataGrid.Columns> |
| | | </DataGrid> |
| | | </StackPanel> |
| | | </Grid> |
| | | </Border> |
| | | |
| | | <Border Grid.Column="1" Style="{StaticResource CardBoarder}" Margin="2,0,0,0"> |
| | | <StackPanel> |
| | | <DockPanel Margin="0,0,0,10" > |
| | | <Button DockPanel.Dock="Right" pu:ButtonHelper.Icon="" Style="{StaticResource DangerButton}">删除</Button> |
| | | <Button DockPanel.Dock="Right" Style="{StaticResource PrimaryButton}" |
| | | pu:ButtonHelper.Icon="" Margin="0,0,10,0" x:Name="refreshParameterBtn" Click="Button_Click">刷新</Button> |
| | | <Button DockPanel.Dock="Right" Style="{StaticResource PrimaryButton}" |
| | | pu:ButtonHelper.Icon="" Margin="0,0,10,0" x:Name="addParameterBtn" Click="Button_Click">新增</Button> |
| | | <Grid dp:GridHelper.Space="10"> |
| | | <Grid.RowDefinitions> |
| | | <RowDefinition Height="Auto"/> |
| | | <RowDefinition /> |
| | | </Grid.RowDefinitions> |
| | | <DockPanel> |
| | | <StackPanel DockPanel.Dock="Right" Style="{StaticResource ButtonGroup}"> |
| | | <Button Style="{StaticResource PrimaryButton}" |
| | | pu:ButtonHelper.Icon="" x:Name="addParameterBtn" Click="Button_Click">新增</Button> |
| | | <Button Style="{StaticResource PrimaryButton}" |
| | | pu:ButtonHelper.Icon="" x:Name="refreshParameterBtn" Click="Button_Click">刷新</Button> |
| | | <Button pu:ButtonHelper.Icon="" x:Name="deleteBatchParameterBtn" |
| | | Style="{StaticResource DangerButton}" Click="Button_Click">删除</Button> |
| | | </StackPanel> |
| | | <TextBlock DockPanel.Dock="Left" FontSize="{StaticResource TitleFontSize}" |
| | | VerticalAlignment="Center" HorizontalAlignment="Left" Text="产品列表"/> |
| | | <TextBlock DockPanel.Dock="Left" FontSize="{StaticResource TitleFontSize}" |
| | | VerticalAlignment="Center" HorizontalAlignment="Left" Text="产品参数"/> |
| | | VerticalAlignment="Center" HorizontalAlignment="Left" Text="产品参数"/> |
| | | </DockPanel> |
| | | |
| | | <DataGrid x:Name="roleTable" Style="{StaticResource DefaultDataGrid}" SelectionMode="Single" |
| | | ItemsSource="{Binding Parameters}"> |
| | | |
| | | <DataGrid Grid.Row="1" x:Name="parameterTable" Style="{StaticResource DefaultDataGrid}" SelectionMode="Single" |
| | | SelectedItem="{Binding SelectedParameter}" |
| | | ItemsSource="{Binding Parameters}"> |
| | | <DataGrid.Columns> |
| | | <DataGridTemplateColumn Header="" Width="Auto" CanUserResize="False"> |
| | | <DataGridTemplateColumn.CellTemplate> |
| | | <DataTemplate> |
| | | <CheckBox VerticalAlignment="Center" |
| | | HorizontalAlignment="Center" IsChecked="{Binding Selected,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/> |
| | | HorizontalAlignment="Center" IsChecked="{Binding IsSelected,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/> |
| | | </DataTemplate> |
| | | </DataGridTemplateColumn.CellTemplate> |
| | | </DataGridTemplateColumn> |
| | | |
| | | <DataGridTextColumn Header="#" Binding="{Binding Converter={StaticResource rowNumber}, |
| | | RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGridRow},AncestorLevel=1}}" |
| | | CanUserResize="False"/> |
| | | RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGridRow},AncestorLevel=1}}" |
| | | CanUserResize="False"/> |
| | | <DataGridTextColumn Width="*" Binding="{Binding Name}" Header="名称" /> |
| | | <DataGridTextColumn Width="*" Binding="{Binding Value}" Header="值" /> |
| | | <DataGridTextColumn Width="*" Binding="{Binding Unit}" Header="单位" /> |
| | |
| | | <DataTemplate> |
| | | <StackPanel Orientation="Horizontal"> |
| | | <Button x:Name="editParameterBtn" Style="{StaticResource RowLink}" Margin="0,0,10,0" |
| | | DataContext="{Binding }" |
| | | Click="Button_Click">编辑</Button> |
| | | DataContext="{Binding }" |
| | | Click="Button_Click">编辑</Button> |
| | | <Button x:Name="delParameterBtn" Style="{StaticResource DangerLinkButton}" |
| | | DataContext="{Binding }" |
| | | Click="Button_Click">删除</Button> |
| | | DataContext="{Binding }" |
| | | Click="Button_Click">删除</Button> |
| | | </StackPanel> |
| | | </DataTemplate> |
| | | </DataGridTemplateColumn.CellTemplate> |
| | | </DataGridTemplateColumn> |
| | | </DataGrid.Columns> |
| | | </DataGrid> |
| | | </StackPanel> |
| | | </Grid> |
| | | </Border> |
| | | </Grid> |
| | | </hb:PluginControl> |
| | |
| | | using System.IO; |
| | | using System.Linq; |
| | | using System.Windows; |
| | | using System.Windows.Controls; |
| | | using System.Windows.Markup; |
| | | using HMI.Base; |
| | | using HMI.Core.Util; |
| | | using HMI.ParameterManage.Entity; |
| | | using HMI.ParameterManage.Model; |
| | | using HMI.UI.Util; |
| | | |
| | | namespace HMI.ParameterManage |
| | |
| | | /// </summary> |
| | | public partial class ParameterManage : PluginControl |
| | | { |
| | | private ControlModel Model; |
| | | private SqliteHelper SqliteHelper; |
| | | private XmlModel Model; |
| | | |
| | | public ParameterManage() |
| | | { |
| | |
| | | |
| | | public override void InitFinish() |
| | | { |
| | | string dbpath = Path.Combine(BaseFolder, "ParameterManage.db"); |
| | | if (!File.Exists(dbpath)) |
| | | { |
| | | SqliteHelper.CreateDatabase(dbpath); |
| | | } |
| | | SqliteHelper = new SqliteHelper(dbpath); |
| | | SqliteHelper.ExecuteSql(@"CREATE TABLE IF NOT EXISTS product ( |
| | | id INTEGER PRIMARY KEY AUTOINCREMENT, |
| | | name TEXT NOT NULL, |
| | | isMaster INTEGER, |
| | | parentId INTEGER, |
| | | UNIQUE(name) |
| | | ); |
| | | CREATE TABLE IF NOT EXISTS parameter ( |
| | | id INTEGER PRIMARY KEY AUTOINCREMENT, |
| | | name TEXT NOT NULL, |
| | | value TEXT, |
| | | unit TEXT, |
| | | description TEXT, |
| | | pGroup TEXT, |
| | | productName TEXT, |
| | | UNIQUE(productName,name) |
| | | ); |
| | | "); |
| | | Model = new ControlModel(SqliteHelper); |
| | | Model = new XmlModel(BaseFolder); |
| | | DataContext = Model; |
| | | } |
| | | |
| | |
| | | switch (btn.Name) |
| | | { |
| | | case "addBtn": |
| | | OpenAddDialog(); |
| | | OpenProductDialog(null); |
| | | break; |
| | | case "editProductBtn": |
| | | OpenProductDialog((ProductData)btn.DataContext); |
| | | break; |
| | | case "delProductBtn": |
| | | TryDeleteProduct((ProductData)btn.DataContext); |
| | | break; |
| | | case "delBatchBtn": |
| | | TryDeleteProducts(); |
| | | break; |
| | | case "refrshBtn": |
| | | Model.LoadProducts(); |
| | |
| | | case "editParameterBtn": |
| | | OpenAddParameterDialog((ParameterData)btn.DataContext); |
| | | break; |
| | | case "delParameterBtn": |
| | | TryDeleteParameter((ParameterData)btn.DataContext); |
| | | break; |
| | | case "deleteBatchParameterBtn": |
| | | TryDeleteParameters(); |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | } |
| | | |
| | | private void OpenAddDialog() |
| | | private void OpenProductDialog(ProductData data) |
| | | { |
| | | var win = new ProductModal |
| | | var win = new ProductModal(Model) |
| | | { |
| | | Title = "新增产品", |
| | | Title = data == null ? "新增产品" : "编辑产品", |
| | | Owner = Window.GetWindow(this), |
| | | sqliteHelper = SqliteHelper |
| | | }; |
| | | if (win.Open(new ProductData()) == true) |
| | | if (win.Open(data ?? new ProductData()) == true) |
| | | { |
| | | Model.LoadProducts(); |
| | | } |
| | |
| | | ToastHelper.Warning(Window.GetWindow(this), "请先选择一项产品"); |
| | | return; |
| | | } |
| | | var win = new ParameterModal |
| | | var win = new ParameterModal(Model) |
| | | { |
| | | Title = data == null ? "新增参数" : "编辑参数", |
| | | Owner = Window.GetWindow(this), |
| | | sqliteHelper = SqliteHelper |
| | | }; |
| | | if (win.Open(data ?? new ParameterData { ProductName = Model.SelectedProduct.Name }) == true) |
| | | { |
| | |
| | | } |
| | | } |
| | | |
| | | private void TryDeleteProduct(ProductData data) |
| | | { |
| | | if (MsgBoxHelper.WarnMessage(Window.GetWindow(this), $"确定要删除产品[{data.Name}]吗?该操作无法撤销") |
| | | == MessageBoxResult.OK) |
| | | { |
| | | Model.DeleteProduct(data); |
| | | Model.LoadProducts(); |
| | | } |
| | | } |
| | | |
| | | private void TryDeleteProducts() |
| | | { |
| | | var temp = Model.Products.Where(p => p.IsSelected).Count(); |
| | | if (temp <= 0) |
| | | { |
| | | this.Warning("请选择要删除的产品"); |
| | | return; |
| | | } |
| | | if (MsgBoxHelper.WarnMessage(Window.GetWindow(this), $"确定要删除选中的[{temp}]条产品吗?该操作无法撤销") |
| | | == MessageBoxResult.OK) |
| | | { |
| | | Model.DeleteProducts(); |
| | | Model.LoadProducts(); |
| | | } |
| | | } |
| | | |
| | | private void TryDeleteParameter(ParameterData data) |
| | | { |
| | | if (MsgBoxHelper.WarnMessage(Window.GetWindow(this), $"确定要删除参数[{data.Name}]吗?该操作无法撤销") == MessageBoxResult.OK) |
| | | { |
| | | Model.DeleteParameter(data); |
| | | Model.LoadParameters(); |
| | | } |
| | | } |
| | | |
| | | private void TryDeleteParameters() |
| | | { |
| | | var temp = Model.Parameters.Where(p => p.IsSelected).Count(); |
| | | if (temp <= 0) |
| | | { |
| | | this.Warning("请选择要删除的参数"); |
| | | return; |
| | | } |
| | | if (MsgBoxHelper.WarnMessage(Window.GetWindow(this), $"确定要删除选中的[{temp}]条参数吗?该操作无法撤销") |
| | | == MessageBoxResult.OK) |
| | | { |
| | | Model.DeleteParameters(); |
| | | Model.LoadParameters(); |
| | | } |
| | | } |
| | | |
| | | } |
| | | } |
| | |
| | | xmlns:pu="https://opensource.panuon.com/wpf-ui" |
| | | xmlns:uic="clr-namespace:HMI.UI.Converter;assembly=HMI.UI" |
| | | xmlns:ui="clr-namespace:HMI.UI;assembly=HMI.UI" |
| | | xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI" |
| | | mc:Ignorable="d" |
| | | Title="Form" |
| | | SizeToContent="Height" |
| | |
| | | pu:WindowXModalDialog.ButtonPanelMargin="0,30,10,10"> |
| | | <Grid Margin="10"> |
| | | <StackPanel x:Name="formPanel"> |
| | | <pu:FormGroup x:Name="FgProductName" ui:FormGroupHelper.IsRequired="True" |
| | | <pu:FormGroup x:Name="FgProductName" dp:FormGroupHelper.IsRequired="True" |
| | | Header="产品名称" GroupName="MyFormGroup"> |
| | | <TextBox x:Name="TbProductName" IsReadOnly="True" Style="{StaticResource EditorTextBoxStyle}" /> |
| | | </pu:FormGroup> |
| | | |
| | | <pu:FormGroup x:Name="FgName" ui:FormGroupHelper.IsRequired="True" |
| | | ui:FormGroupHelper.ValidateMethod="ValidateName" |
| | | <pu:FormGroup x:Name="FgName" dp:FormGroupHelper.IsRequired="True" |
| | | dp:FormGroupHelper.ValidateMethod="ValidateName" |
| | | Header="参数名称" GroupName="MyFormGroup"> |
| | | <TextBox x:Name="TbName" Style="{StaticResource EditorTextBoxStyle}" /> |
| | | </pu:FormGroup> |
| | | |
| | | <pu:FormGroup x:Name="FgValue" Style="{StaticResource RequiredInputFormGroupStyle}" |
| | | ui:FormGroupHelper.IsRequired="True" |
| | | dp:FormGroupHelper.IsRequired="True" |
| | | Header="参数值" GroupName="MyFormGroup"> |
| | | <TextBox x:Name="TbValue" Style="{StaticResource EditorTextBoxStyle}" /> |
| | | </pu:FormGroup> |
| | |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Collections.ObjectModel; |
| | | using System.ComponentModel; |
| | | using System.Linq; |
| | | using System.Reflection; |
| | | using System.Windows; |
| | | using Microsoft.Win32; |
| | | using Panuon.WPF.UI; |
| | | using HMI.Core.Annotation; |
| | | using HMI.Core.Entity; |
| | | using HMI.Core.Exceptions; |
| | | using HMI.Core.Util; |
| | | using HMI.Core.Util; |
| | | using HMI.ParameterManage.Entity; |
| | | using HMI.UI; |
| | | using HMI.ParameterManage.Model; |
| | | using HMI.UI.DpUtil; |
| | | using Panuon.WPF.UI; |
| | | using System; |
| | | using System.ComponentModel; |
| | | using System.Windows.Interop; |
| | | |
| | | namespace HMI.ParameterManage |
| | | { |
| | |
| | | /// </summary> |
| | | public partial class ParameterModal : WindowX |
| | | { |
| | | public ParameterModal() |
| | | private XmlModel DataModel; |
| | | public ParameterModal(XmlModel model) |
| | | { |
| | | DataModel = model; |
| | | this.DataContext = this; |
| | | InitializeComponent(); |
| | | } |
| | | |
| | | public ParameterData Data { get; set; } |
| | | |
| | | public SqliteHelper sqliteHelper { get; set; } |
| | | |
| | | private bool _isProcessing; |
| | | |
| | |
| | | return; |
| | | } |
| | | |
| | | SaveOrUpdateData(); |
| | | DataModel.SaveOrUpdateParameter(Data); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | |
| | | |
| | | public bool ValidateName(object value, out string err) |
| | | { |
| | | err = null; |
| | | string segment = string.IsNullOrEmpty(Data.Id) ? "" : $" AND id!='{Data.Id}'"; |
| | | string sql = $"SELECT 1 FROM parameter WHERE name='{TbName.Text}' AND productName='{Data.ProductName}'{segment};"; |
| | | if (sqliteHelper.HasData(sql)) |
| | | { |
| | | err = "参数名称不能重复"; |
| | | return false; |
| | | } |
| | | return true; |
| | | return DataModel.ValidateParameterName(value, out err); |
| | | } |
| | | |
| | | private bool ValidateForm() |
| | |
| | | TbDescription.Text = Data.Description; |
| | | TbPGroup.Text = Data.PGroup; |
| | | return this.ShowDialog(); |
| | | } |
| | | |
| | | private void SaveOrUpdateData() |
| | | { |
| | | if (string.IsNullOrEmpty(Data.Id)) |
| | | { |
| | | InsertData(Data); |
| | | } |
| | | else |
| | | { |
| | | UpdateData(Data); |
| | | } |
| | | } |
| | | |
| | | public void InsertData(ParameterData data) |
| | | { |
| | | string sql = $@"INSERT INTO parameter (name,value,unit,description,productName,pGroup) |
| | | VALUES |
| | | ('{data.Name}','{data.Value}','{data.Unit}','{data.Description}','{data.ProductName}','{data.PGroup}');"; |
| | | sqliteHelper.ExecuteSql(sql); |
| | | } |
| | | |
| | | public void UpdateData(ParameterData data) |
| | | { |
| | | string sql = $@"UPDATE parameter SET name='{data.Name}',value='{data.Value}',unit='{data.Unit}', |
| | | description='{data.Description}',productName='{data.ProductName}',pGroup='{data.PGroup}' WHERE id='{data.Id}';"; |
| | | sqliteHelper.ExecuteSql(sql); |
| | | } |
| | | } |
| | | } |
| | |
| | | xmlns:pw="https://opensource.panuon.com/wpf" |
| | | xmlns:pu="https://opensource.panuon.com/wpf-ui" |
| | | xmlns:uic="clr-namespace:HMI.UI.Converter;assembly=HMI.UI" |
| | | xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI" |
| | | mc:Ignorable="d" |
| | | Title="Form" |
| | | SizeToContent="Height" |
| | |
| | | </Window.Resources> |
| | | |
| | | <Grid Margin="10"> |
| | | <StackPanel> |
| | | <StackPanel x:Name="formPanel"> |
| | | <pu:FormGroup x:Name="FgName" Style="{StaticResource RequiredInputFormGroupStyle}" |
| | | Header="产品名称" GroupName="MyFormGroup"> |
| | | Header="产品名称" GroupName="MyFormGroup" |
| | | dp:FormGroupHelper.IsRequired="True" |
| | | dp:FormGroupHelper.ValidateMethod="ValidateName" |
| | | > |
| | | <TextBox x:Name="TbName" Style="{StaticResource EditorTextBoxStyle}" /> |
| | | </pu:FormGroup> |
| | | |
| | |
| | | using HMI.Core.Util; |
| | | using HMI.ParameterManage.Entity; |
| | | using HMI.UI; |
| | | using HMI.ParameterManage.Model; |
| | | using HMI.UI.DpUtil; |
| | | |
| | | namespace HMI.ParameterManage |
| | | { |
| | |
| | | /// </summary> |
| | | public partial class ProductModal : WindowX |
| | | { |
| | | public ProductModal() |
| | | |
| | | private XmlModel DataModel; |
| | | |
| | | public ProductModal(XmlModel dataModel) |
| | | { |
| | | DataModel = dataModel; |
| | | this.DataContext = this; |
| | | InitializeComponent(); |
| | | } |
| | | |
| | | public ProductData Data { get; set; } |
| | | |
| | | public SqliteHelper sqliteHelper { get; set; } |
| | | |
| | | private bool _isProcessing; |
| | | |
| | |
| | | return; |
| | | } |
| | | |
| | | SaveOrUpdateData(); |
| | | DataModel.SaveOrUpdateData(Data); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | |
| | | base.OnClosing(e); |
| | | } |
| | | |
| | | private bool ValidateName(object value, out string msg) |
| | | { |
| | | return DataModel.ValidateProductName(value, out msg); |
| | | } |
| | | |
| | | private bool ValidateForm() |
| | | { |
| | | try |
| | | bool flag = FormGroupHelper.ValidateForm(formPanel); |
| | | if (flag) |
| | | { |
| | | |
| | | // |
| | | |
| | | FormValidateException ex = new FormValidateException(); |
| | | string segment = string.IsNullOrEmpty(Data.Id) ? "" : $" AND id!='{Data.Id}'"; |
| | | string sql = $"SELECT 1 FROM product WHERE name='{TbName.Text}'{segment};"; |
| | | if (string.IsNullOrEmpty(TbName.Text)) |
| | | { |
| | | ex.Result.Add(new FormGroupValidateResult("请输入产品名称", FgName)); |
| | | } |
| | | else if (sqliteHelper.HasData(sql)) |
| | | { |
| | | ex.Result.Add(new FormGroupValidateResult("产品名称不能重复", FgName)); |
| | | } |
| | | else |
| | | { |
| | | FgName.ValidateResult = ValidateResult.None; |
| | | FgName.Message = null; |
| | | } |
| | | |
| | | if (!ex.Success) |
| | | { |
| | | throw ex; |
| | | } |
| | | Data.Name = TbName.Text; |
| | | Data.IsMaster = TbIsMaster.IsChecked == true; |
| | | } |
| | | catch (FormValidateException ex) |
| | | { |
| | | foreach (var data in ex.Result) |
| | | { |
| | | var fg = (FormGroup)data.Sender; |
| | | fg.ValidateResult = ValidateResult.Error; |
| | | fg.Message = data.Message; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | Data.Name = TbName.Text; |
| | | Data.IsMaster = TbIsMaster.IsChecked == true; |
| | | Data.ParentId = TbParentId.Text; |
| | | return true; |
| | | return flag; |
| | | } |
| | | |
| | | public bool? Open(ProductData data) |
| | |
| | | TbParentId.Text = Data.ParentId; |
| | | |
| | | return this.ShowDialog(); |
| | | } |
| | | |
| | | private void SaveOrUpdateData() |
| | | { |
| | | if (string.IsNullOrEmpty(Data.Id)) |
| | | { |
| | | InsertData(Data); |
| | | } |
| | | else |
| | | { |
| | | UpdateData(Data); |
| | | } |
| | | } |
| | | |
| | | public void InsertData(ProductData data) |
| | | { |
| | | string sql = $@"INSERT INTO product (name,isMaster,parentId) |
| | | VALUES |
| | | ('{data.Name}',{(data.IsMaster ? 1 : 0)} ,{data.ParentId} );"; |
| | | sqliteHelper.ExecuteSql(sql); |
| | | } |
| | | |
| | | |
| | | |
| | | public void UpdateData(ProductData data) |
| | | { |
| | | string sql = $@"UPDATE product SET name='{data.Name}',isMaster='{(data.IsMaster ? 1 : 0)}',parentId = {data.ParentId} |
| | | WHERE id='{data.Id}';"; |
| | | sqliteHelper.ExecuteSql(sql); |
| | | } |
| | | } |
| | | } |
| | |
| | | xmlns:uic="clr-namespace:HMI.UI.Converter;assembly=HMI.UI" |
| | | xmlns:pw="https://opensource.panuon.com/wpf" |
| | | xmlns:pu="https://opensource.panuon.com/wpf-ui" |
| | | xmlns:dp="clr-namespace:HMI.UI;assembly=HMI.UI" |
| | | xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI" |
| | | Loaded="UserControl_Loaded" |
| | | Background="{StaticResource WorkspaceBackground}" |
| | | d:DesignHeight="450" d:DesignWidth="800"> |
| | |
| | | |
| | | <Grid> |
| | | <Border Style="{StaticResource CardBoarder}"> |
| | | <Grid> |
| | | <Grid dp:GridHelper.Space="10"> |
| | | <Grid.RowDefinitions> |
| | | <RowDefinition Height="Auto"/> |
| | | <RowDefinition /> |
| | | <RowDefinition Height="Auto"/> |
| | | </Grid.RowDefinitions> |
| | | <TextBlock VerticalAlignment="Center" Text="系统设置" Margin="0,0,0,10" |
| | | FontSize="{StaticResource TitleFontSize}" /> |
| | | <TabControl Grid.Row="1" |
| | | |
| | | <TextBlock VerticalAlignment="Center" Text="系统设置" FontSize="{StaticResource TitleFontSize}" /> |
| | | <TabControl Grid.Row="1" x:Name="tabControl" |
| | | BorderBrush="{StaticResource CommonBoarder}" |
| | | ItemsSource="{Binding TabItems}"> |
| | | |
| | | <TabControl.Resources> |
| | | <Style TargetType="TabControl" BasedOn="{StaticResource {x:Static pu:StyleKeys.TabControlStyle}}"> |
| | | <Setter Property="Template"> |
| | | <Setter.Value> |
| | | <ControlTemplate TargetType="TabControl"> |
| | | <Border BorderBrush="Black" BorderThickness="1"> |
| | | <TabControl.Resources> |
| | | <Style TargetType="TabControl" BasedOn="{StaticResource {x:Static pu:StyleKeys.TabControlStyle}}"> |
| | | <Setter Property="Template"> |
| | | <Setter.Value> |
| | | <ControlTemplate TargetType="TabControl"> |
| | | <Border BorderBrush="Black" BorderThickness="1"> |
| | | <ContentPresenter/> |
| | | </Border> |
| | | </ControlTemplate> |
| | | </Setter.Value> |
| | | </Setter> |
| | | </Style> |
| | | </TabControl.Resources> |
| | | |
| | | </ControlTemplate> |
| | | </Setter.Value> |
| | | </Setter> |
| | | </Style> |
| | | </TabControl.Resources> |
| | | </TabControl> |
| | | <StackPanel Grid.Row="2" Style="{StaticResource ButtonGroup}"> |
| | | <Button Style="{StaticResource PrimaryButton}" x:Name="resetBtn" Click="Button_Click">重置</Button> |
| | | <Button Style="{StaticResource PrimaryButton}" x:Name="saveBtn" Click="Button_Click">保存</Button> |
| | | </StackPanel> |
| | | </Grid> |
| | | </Border> |
| | | </Grid> |
| | |
| | | using System.Collections.ObjectModel; |
| | | using System; |
| | | using System.Collections.ObjectModel; |
| | | using System.ComponentModel; |
| | | using System.Runtime.CompilerServices; |
| | | using System.Windows; |
| | | using System.Windows.Controls; |
| | | using HMI.Base; |
| | | using HMI.Core.Api; |
| | | using HMI.UI.Util; |
| | | using log4net; |
| | | |
| | | namespace HMI.SettingControl |
| | |
| | | } |
| | | Loaded -= UserControl_Loaded; |
| | | } |
| | | |
| | | private void Button_Click(object sender, RoutedEventArgs e) |
| | | { |
| | | Button btn = sender as Button; |
| | | switch (btn.Name) |
| | | { |
| | | case "resetBtn": |
| | | ResetCurrentConfig(); |
| | | break; |
| | | case "saveBtn": |
| | | SaveAllConfig(); |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | } |
| | | |
| | | private void SaveAllConfig() |
| | | { |
| | | foreach (var d in tabControl.ItemsSource) |
| | | { |
| | | if (!(d is TabItem tabItem)) continue; |
| | | if (tabItem.Content is IConfigManager manager) |
| | | { |
| | | try |
| | | { |
| | | manager.SaveConfig(); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | MsgBoxHelper.Error(this, $"保存{tabItem.Header}配置失败!{ex.Message}"); |
| | | } |
| | | } |
| | | } |
| | | this.Success("保存成功"); |
| | | } |
| | | |
| | | private void SaveCurrentConfig() |
| | | { |
| | | var content = tabControl.SelectedItem as TabItem; |
| | | if (content is IConfigManager manager) |
| | | { |
| | | try |
| | | { |
| | | manager.SaveConfig(); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | MsgBoxHelper.Error(this, $"保存配置失败!{ex.Message}"); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private void ResetCurrentConfig() |
| | | { |
| | | var tabItem = tabControl.SelectedItem as TabItem; |
| | | if (tabItem.Content is IConfigManager manager) |
| | | { |
| | | try |
| | | { |
| | | manager.ResetConfig(); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | MsgBoxHelper.Error(this, $"保存配置失败!{ex.Message}"); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | </pu:FormGroup> |
| | | </StackPanel> |
| | | </GroupBox> |
| | | |
| | | <DockPanel Grid.Row="3" LastChildFill="False"> |
| | | <Button DockPanel.Dock="Right" Style="{StaticResource PrimaryButton}" Click="Button_Click">保存</Button> |
| | | </DockPanel> |
| | | </Grid> |
| | | </UserControl> |
| | |
| | | using System; |
| | | using System.Windows.Controls; |
| | | using HMI.Core.Api; |
| | | using HMI.Core.Setting; |
| | | using HMI.Core.Util; |
| | | using HMI.UI.Util; |
| | |
| | | /// <summary> |
| | | /// SystemConfig.xaml 的交互逻辑 |
| | | /// </summary> |
| | | public partial class SystemConfig : UserControl |
| | | public partial class SystemConfig : UserControl, IConfigManager |
| | | { |
| | | public SystemConfig() |
| | | { |
| | |
| | | InitializeComponent(); |
| | | } |
| | | |
| | | public object GetConfig() |
| | | { |
| | | return SystemSetting.Instance; |
| | | } |
| | | |
| | | public void ResetConfig() |
| | | { |
| | | var model = new SystemSettingModel(); |
| | | BeanUtil.Copy(SystemSetting.Instance, model); |
| | | DataContext = model; |
| | | } |
| | | |
| | | public void SaveConfig() |
| | | { |
| | | SystemSettingModel settingModel = (SystemSettingModel)DataContext; |
| | | XmlHelper.SerializeToXml(PathHelper.ConfigFolder + "\\SystemConfig.xml", settingModel); |
| | | SystemSetting.ReLoad(); |
| | | } |
| | | |
| | | private void Button_Click(object sender, System.Windows.RoutedEventArgs e) |
| | | { |
| | | try |
| | | { |
| | | SystemSettingModel settingModel = (SystemSettingModel)DataContext; |
| | | XmlHelper.SerializeToXml(PathHelper.ConfigFolder + "\\SystemConfig.xml", settingModel); |
| | | SystemSetting.ReLoad(); |
| | | this.Success("保存成功"); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| New file |
| | |
| | | using System.Windows; |
| | | using System.Windows.Controls; |
| | | |
| | | namespace HMI.UI.DpUtil |
| | | { |
| | | public class DataGridHelper |
| | | { |
| | | public static DataGridColumn GetSelectedColumn(DataGrid obj) |
| | | { |
| | | return (DataGridColumn)obj.GetValue(SelectedColumnProperty); |
| | | } |
| | | public static void SetSelectedColumn(DataGrid obj, DataGridColumn value) |
| | | { |
| | | obj.SetValue(SelectedColumnProperty, value); |
| | | } |
| | | public static readonly DependencyProperty SelectedColumnProperty = |
| | | DependencyProperty.RegisterAttached("SelectedColumn", typeof(DataGridColumn), typeof(Grid), |
| | | new PropertyMetadata(null)); |
| | | } |
| | | } |
| | |
| | | using System; |
| | | using System.ComponentModel; |
| | | using Panuon.WPF.UI; |
| | | using System.Windows; |
| | | using System.Windows.Controls; |
| | | using Panuon.WPF.UI; |
| | | using Panuon.WPF.UI.Configurations; |
| | | |
| | | namespace HMI.UI |
| | | namespace HMI.UI.DpUtil |
| | | { |
| | | public class FormGroupHelper |
| | | { |
| | |
| | | <ItemGroup> |
| | | <Compile Include="Converter\DataGridRowNumberConverter.cs" /> |
| | | <Compile Include="Converter\PathImageConverter.cs" /> |
| | | <Compile Include="DpUtil\DataGridHelper.cs" /> |
| | | <Compile Include="DpUtil\FormGroupHelper.cs" /> |
| | | <Compile Include="DpUtil\GridHelper.cs" /> |
| | | <Compile Include="DpUtil\StackPanelHelper.cs" /> |
| | |
| | | <Setter Property="VerticalContentAlignment" Value="Center"/> |
| | | <Style.Triggers> |
| | | <Trigger Property="IsReadOnly" Value="True"> |
| | | <Setter Property="Background" Value="LightGray"/> |
| | | <Setter Property="Background" Value="#e8e8e8"/> |
| | | </Trigger> |
| | | </Style.Triggers> |
| | | </Style> |
| | |
| | | <Setter Property="ItemsHoverBackground" Value="{StaticResource SecondPrimaryColor}"/> |
| | | <Setter Property="ItemsHoverForeground" Value="{StaticResource SecondPrimaryColorContract}"/> |
| | | <Setter Property="TextStringFormat" Value="yyyy-MM-dd HH:mm:ss"/> |
| | | <Setter Property="Width" Value="180"/> |
| | | <Setter Property="Mode" Value="DateTime"/> |
| | | <Setter Property="SelectedDateTime" Value="{x:Null}"/> |
| | | </Style> |
| | | |
| | | </ResourceDictionary> |
| | |
| | | |
| | | <sys:Double x:Key="TitleFontSize">20</sys:Double> |
| | | <sys:Double x:Key="ContentFontSize">16</sys:Double> |
| | | <sys:Double x:Key="ContentFontSize2">14</sys:Double> |
| | | |
| | | <Style x:Key="PrimaryButton" TargetType="Button" BasedOn="{StaticResource {x:Static pu:StyleKeys.ButtonStyle}}"> |
| | | <Setter Property="Background" Value="{StaticResource PrimaryColor}"/> |
| | |
| | | |
| | | <Style x:Key="DangerLinkButton" TargetType="Button" BasedOn="{StaticResource LinkButton}"> |
| | | <Setter Property="Foreground" Value="{StaticResource DangerColor}"/> |
| | | </Style> |
| | | |
| | | <Style x:Key="CommonToggle" TargetType="ToggleButton" BasedOn="{StaticResource {x:Static pu:StyleKeys.ToggleButtonStyle}}"> |
| | | <Setter Property="Background" Value="#FFF"/> |
| | | <Setter Property="Foreground" Value="Black"/> |
| | | <Setter Property="BorderBrush" Value="LightGray"/> |
| | | <Setter Property="Cursor" Value="Hand"/> |
| | | </Style> |
| | | |
| | | <Style x:Key="CommonMenu" TargetType="Menu" BasedOn="{StaticResource {x:Static pu:StyleKeys.MenuStyle}}"> |
| | | <Setter Property="Background" Value="{StaticResource PrimaryColor}"/> |
| | | <Setter Property="Foreground" Value="#FFF"/> |
| | | <Setter Property="pu:IconHelper.FontFamily" Value="{StaticResource iconfont}"/> |
| | | <Setter Property="pu:IconHelper.Margin" Value="0,0,10,0"/> |
| | | <Setter Property="BorderThickness" Value="0"/> |
| | | <Setter Property="Cursor" Value="Hand"/> |
| | | </Style> |
| | | |
| | | <Style x:Key="CardBoarder" TargetType="Border"> |
| | |
| | | <Setter Property="VerticalAlignment" Value="Center"/> |
| | | <Setter Property="FontSize" Value="{StaticResource TitleFontSize}"/> |
| | | </Style> |
| | | |
| | | <Style x:Key="FormHeader" TargetType="TextBlock"> |
| | | <Setter Property="VerticalAlignment" Value="Center"/> |
| | | <Setter Property="HorizontalAlignment" Value="Center"/> |
| | | <Setter Property="FontSize" Value="{StaticResource ContentFontSize2}"/> |
| | | </Style> |
| | | </ResourceDictionary> |
| | |
| | | ToastPosition position = ToastPosition.Top, double offset = 0, int durationMs = 3000, |
| | | ToastWindow targetWindow = ToastWindow.ActiveWindow) |
| | | { |
| | | ToastHelper.Error(Window.GetWindow(control), message, icon, position, offset, durationMs, targetWindow); |
| | | Application.Current.Dispatcher.Invoke(() => |
| | | { |
| | | ToastHelper.Error(Window.GetWindow(control), message, icon, position, offset, durationMs, targetWindow); |
| | | }); |
| | | } |
| | | |
| | | public static void Info(this UserControl control, |
| New file |
| | |
| | | <UserControl x:Class="Plugin.TestResult_WPF.Chart" |
| | | 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.TestResult_WPF" |
| | | xmlns:ScottPlot="clr-namespace:ScottPlot.WPF;assembly=ScottPlot.WPF" |
| | | mc:Ignorable="d" |
| | | Loaded="UserControl_Loaded" |
| | | Unloaded="UserControl_Unloaded" |
| | | SizeChanged="UserControl_SizeChanged" |
| | | d:DesignHeight="450" d:DesignWidth="800"> |
| | | <ScottPlot:WpfPlot x:Name="chart" /> |
| | | </UserControl> |
| New file |
| | |
| | | using ScottPlot; |
| | | using ScottPlot.Plottables; |
| | | using ScottPlot.TickGenerators; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Timers; |
| | | using System.Windows.Controls; |
| | | |
| | | namespace Plugin.TestResult_WPF |
| | | { |
| | | /// <summary> |
| | | /// Chart.xaml 的交互逻辑 |
| | | /// </summary> |
| | | public partial class Chart : UserControl |
| | | { |
| | | private readonly int maxSize; |
| | | |
| | | private readonly Queue<long> xData; |
| | | private readonly Queue<double> yData; |
| | | |
| | | private readonly Dictionary<string, Queue<long>> xValues; |
| | | private readonly Dictionary<string, Queue<double>> yValues; |
| | | |
| | | readonly DataLogger singleLogger; |
| | | |
| | | private readonly string title; |
| | | private readonly bool multi; |
| | | private readonly int refreshInterval; |
| | | |
| | | private double maxYValue = -1; |
| | | private double minYValue = double.MaxValue; |
| | | |
| | | private Timer timer; |
| | | |
| | | private readonly Dictionary<string, DataLogger> loggers = new Dictionary<string, DataLogger>(); |
| | | |
| | | private DataLogger InitLogger() |
| | | { |
| | | DataLogger logger = chart.Plot.Add.DataLogger(); |
| | | //logger.ViewSlide(maxSize * 5); |
| | | logger.ViewFull(); |
| | | //logger.Add(new Coordinates(DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), 0)); |
| | | return logger; |
| | | } |
| | | |
| | | public Chart(string title, bool multi, int maxSize, int refreshInterval) |
| | | { |
| | | this.title = title; |
| | | this.maxSize = maxSize; |
| | | this.multi = multi; |
| | | this.refreshInterval = refreshInterval; |
| | | |
| | | |
| | | InitializeComponent(); |
| | | if (this.multi) |
| | | { |
| | | xValues = new Dictionary<string, Queue<long>>(); |
| | | yValues = new Dictionary<string, Queue<double>>(); |
| | | //chart.Plot.ShowLegend(Alignment.UpperLeft, Orientation.Vertical); |
| | | var legend = chart.Plot.ShowLegend(Edge.Top); |
| | | legend.Alignment = Alignment.UpperLeft; |
| | | legend.Padding = new PixelPadding(0); |
| | | |
| | | |
| | | chart.Plot.Axes.Left.TickLabelStyle.FontSize = 12; |
| | | chart.Plot.Axes.Bottom.TickLabelStyle.FontSize = 12; |
| | | chart.Plot.Axes.Left.Label.FontSize = 15; |
| | | } |
| | | else |
| | | { |
| | | singleLogger = InitLogger(); |
| | | singleLogger.Color = Colors.Red; |
| | | xData = new Queue<long>(maxSize); |
| | | yData = new Queue<double>(maxSize); |
| | | chart.Plot.Axes.Left.TickLabelStyle.FontSize = (float)FontSizeConverter.CountFontSize(12, ActualHeight, 92); |
| | | chart.Plot.Axes.Bottom.TickLabelStyle.FontSize = (float)FontSizeConverter.CountFontSize(12, ActualHeight, 92); |
| | | chart.Plot.Axes.Left.Label.FontSize = (float)FontSizeConverter.CountFontSize(15, ActualHeight, 92); |
| | | } |
| | | |
| | | /// 禁用鼠标 |
| | | chart.UserInputProcessor.Disable(); |
| | | //chart.Plot.Layout.Frameless(); |
| | | |
| | | |
| | | //Streamer1 = chart.Plot.Add.DataStreamer(maxSize); |
| | | //Streamer1.ViewScrollLeft(); |
| | | //Streamer1.Color = Colors.Green; |
| | | |
| | | //chart.Plot.Add.Scatter(xData.ToArray(), yData.ToArray()); |
| | | |
| | | |
| | | |
| | | |
| | | //string CustomFormatter(DateTime dt) |
| | | //{ |
| | | // return dt.ToString("HH:mm:ss.fff"); |
| | | //} |
| | | //var axis = chart.Plot.Axes.DateTimeTicksBottom(); |
| | | //var tickGen = (DateTimeAutomatic)axis.TickGenerator; |
| | | //tickGen.LabelFormatter = CustomFormatter; |
| | | |
| | | //chart.Plot.Axes.Bottom.TickGenerator = new DateTimeAutomatic(); |
| | | //chart.Plot.Axes.DateTimeTicksBottom(); |
| | | //chart.Plot.RenderManager.RenderStarting += (s, e) => |
| | | //{ |
| | | // try |
| | | // { |
| | | // Tick[] ticks = chart.Plot.Axes.Bottom.TickGenerator.Ticks; |
| | | // for (int i = 0; i < ticks.Length; i++) |
| | | // { |
| | | // long ms = ticks[i].Position < 0 ? 0 : (long)ticks[i].Position; |
| | | // DateTime dt = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1)).AddMilliseconds(ms); |
| | | // string label = $"{dt:hh:mm:ss.fff}"; |
| | | // ticks[i] = new Tick(ticks[i].Position, label); |
| | | // } |
| | | // } |
| | | // catch (Exception ex) |
| | | // { |
| | | |
| | | // } |
| | | //}; |
| | | |
| | | string CustomFormatter(double position) |
| | | { |
| | | if (position > 0) |
| | | return TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1)).AddMilliseconds(position).ToString("HH:mm:ss"); |
| | | return ""; |
| | | } |
| | | EvenlySpacedMinorTickGenerator minorTickGen = new EvenlySpacedMinorTickGenerator(10); |
| | | NumericAutomatic myTickGenerator = new NumericAutomatic() |
| | | { |
| | | LabelFormatter = CustomFormatter, |
| | | MinorTickGenerator = minorTickGen |
| | | }; |
| | | chart.Plot.Axes.Bottom.TickGenerator = myTickGenerator; |
| | | if (!string.IsNullOrEmpty(this.title)) |
| | | { |
| | | chart.Plot.Axes.Left.Label.Text = this.title; |
| | | chart.Plot.Axes.Left.Label.Bold = false; |
| | | chart.Plot.Font.Automatic(); |
| | | //RefreshData(); |
| | | } |
| | | |
| | | /// 设置刷新定时器 |
| | | //refreshTimer = new System.Timers.Timer() { Interval = this.refreshInterval, AutoReset = true }; |
| | | //refreshTimer.Elapsed += RefreshTimer_Elapsed; |
| | | |
| | | //chart.Plot.DataBackground.Color = new Color(0, 0, 0); |
| | | //chart.Plot.Grid.MajorLineColor = Colors.Green.WithOpacity(.6); |
| | | //chart.Plot.Grid.MajorLineWidth = 1; |
| | | //chart.Plot.Grid.MinorLineColor = Colors.Gray.WithOpacity(.3); |
| | | //chart.Plot.Grid.MinorLineWidth = 1; |
| | | |
| | | //chart.Plot.Axes.Bottom.TickLabelStyle.IsVisible = false; |
| | | //chart.Plot.Axes.Bottom.MajorTickStyle.Length = 0; |
| | | //chart.Plot.Axes.Left.TickLabelStyle.IsVisible = false; |
| | | //chart.Plot.Axes.Left.MajorTickStyle.Length = 0; |
| | | |
| | | //chart.Plot.Axes.Bottom.FrameLineStyle.Width = 0; |
| | | //chart.Plot.Axes.Left.FrameLineStyle.Width = 0; |
| | | //chart.Plot.Axes.Top.FrameLineStyle.Width = 0; |
| | | //chart.Plot.Axes.Right.FrameLineStyle.Width = 0; |
| | | |
| | | timer = new Timer(); |
| | | timer.Interval = this.refreshInterval; |
| | | timer.Elapsed += Timer_Elapsed; |
| | | } |
| | | |
| | | private void Timer_Elapsed(object sender, ElapsedEventArgs e) |
| | | { |
| | | if (maxYValue > 0) |
| | | { |
| | | RefreshData(); |
| | | } |
| | | } |
| | | |
| | | public void RefreshData() |
| | | { |
| | | /// 限制y轴 |
| | | if (maxYValue > -1) |
| | | { |
| | | chart.Plot.Axes.SetLimitsY(minYValue > 5 ? minYValue - 5 : 0, maxYValue + 5); |
| | | } |
| | | else |
| | | { |
| | | chart.Plot.Axes.SetLimitsY(0, 100); |
| | | } |
| | | chart.Refresh(); |
| | | } |
| | | |
| | | public void Clear() |
| | | { |
| | | this.maxYValue = -1; |
| | | this.minYValue = double.MaxValue; |
| | | if (this.multi) |
| | | { |
| | | foreach (var name in loggers.Keys) |
| | | { |
| | | loggers[name].Clear(); |
| | | xValues[name].Clear(); |
| | | yValues[name].Clear(); |
| | | } |
| | | chart.Refresh(); |
| | | return; |
| | | } |
| | | singleLogger.Clear(); |
| | | xData.Clear(); |
| | | yData.Clear(); |
| | | chart.Refresh(); |
| | | } |
| | | |
| | | public void AddData(double y) |
| | | { |
| | | if (this.multi) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | this.maxYValue = y > maxYValue ? y : maxYValue; |
| | | this.minYValue = y < minYValue ? y : minYValue; |
| | | |
| | | var nowTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); |
| | | InsertData(xData, yData, nowTime, y); |
| | | |
| | | singleLogger.Add(new Coordinates(nowTime, y)); |
| | | //Streamer1.Add(new Coordinates(DateTimeOffset.Now.ToUnixTimeSeconds(), y)); |
| | | |
| | | chart.Plot.GetPlottables<Marker>() |
| | | .ToList() |
| | | .ForEach(m => m.X -= 1); |
| | | chart.Plot.GetPlottables<Marker>() |
| | | .Where(m => m.X < 0) |
| | | .ToList() |
| | | .ForEach(m => chart.Plot.Remove(m)); |
| | | //RefreshData(); |
| | | } |
| | | |
| | | private void InsertData(Queue<long> xAxis, Queue<double> yAxis, long x, double y) |
| | | { |
| | | if (xAxis.Count >= maxSize) |
| | | { |
| | | xAxis.Dequeue(); |
| | | yAxis.Dequeue(); |
| | | } |
| | | xAxis.Enqueue(x); |
| | | yAxis.Enqueue(y); |
| | | } |
| | | |
| | | public void AddData(string name, double y) |
| | | { |
| | | if (!this.multi) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | this.maxYValue = y > maxYValue ? y : maxYValue; |
| | | this.minYValue = y < minYValue ? y : minYValue; |
| | | |
| | | if (loggers.ContainsKey(name)) |
| | | { |
| | | var logger = loggers[name]; |
| | | var x = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); |
| | | logger.Add(new Coordinates(x, y)); |
| | | InsertData(xValues[name], yValues[name], x, y); |
| | | } |
| | | else |
| | | { |
| | | var logger = InitLogger(); |
| | | logger.LegendText = name; |
| | | loggers.Add(name, logger); |
| | | var xAxis = new Queue<long>(maxSize); |
| | | var yAxis = new Queue<double>(maxSize); |
| | | |
| | | xValues.Add(name, xAxis); |
| | | yValues.Add(name, yAxis); |
| | | |
| | | var x = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); |
| | | logger.Add(new Coordinates(x, y)); |
| | | InsertData(xAxis, yAxis, x, y); |
| | | } |
| | | |
| | | //Streamer1.Add(new Coordinates(DateTimeOffset.Now.ToUnixTimeSeconds(), y)); |
| | | |
| | | chart.Plot.GetPlottables<Marker>() |
| | | .ToList() |
| | | .ForEach(m => m.X -= 1); |
| | | chart.Plot.GetPlottables<Marker>() |
| | | .Where(m => m.X < 0) |
| | | .ToList() |
| | | .ForEach(m => chart.Plot.Remove(m)); |
| | | //RefreshData(); |
| | | } |
| | | |
| | | private void UserControl_Loaded(object sender, System.Windows.RoutedEventArgs e) |
| | | { |
| | | //refreshTimer.Start(); |
| | | timer?.Start(); |
| | | } |
| | | |
| | | private void UserControl_Unloaded(object sender, System.Windows.RoutedEventArgs e) |
| | | { |
| | | timer?.Stop(); |
| | | } |
| | | |
| | | private void UserControl_SizeChanged(object sender, System.Windows.SizeChangedEventArgs e) |
| | | { |
| | | if (this.multi) return; |
| | | chart.Plot.Axes.Left.Label.FontSize = (float)FontSizeConverter.CountFontSize(15, ActualHeight, 92); |
| | | chart.Plot.Axes.Left.TickLabelStyle.FontSize = (float)FontSizeConverter.CountFontSize(10, ActualHeight, 92); |
| | | chart.Plot.Axes.Bottom.TickLabelStyle.FontSize = (float)FontSizeConverter.CountFontSize(10, ActualHeight, 92); |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | <Window x:Class="Plugin.TestResult_WPF.ChartWindow" |
| | | xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
| | | xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
| | | xmlns:d="http://schemas.microsoft.com/expression/blend/2008" |
| | | xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" |
| | | xmlns:local="clr-namespace:Plugin.TestResult_WPF" |
| | | mc:Ignorable="d" |
| | | Unloaded="Window_Unloaded" |
| | | Title="{Binding title}" Height="450" Width="800"> |
| | | <UniformGrid x:Name="mainGrid" Columns="1"> |
| | | |
| | | </UniformGrid> |
| | | </Window> |
| New file |
| | |
| | | using System.ComponentModel; |
| | | using System.Runtime.CompilerServices; |
| | | using System.Windows; |
| | | |
| | | namespace Plugin.TestResult_WPF |
| | | { |
| | | /// <summary> |
| | | /// ChartWindow.xaml 的交互逻辑 |
| | | /// </summary> |
| | | public partial class ChartWindow : Window, INotifyPropertyChanged |
| | | { |
| | | #region ... |
| | | public event PropertyChangedEventHandler PropertyChanged; |
| | | |
| | | public virtual void RaisePropertyChanged(string name) |
| | | { |
| | | PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); |
| | | } |
| | | |
| | | public void RaiseAndSetIfchanged<T>(ref T old, T @new, [CallerMemberName] string propertyName = null) |
| | | { |
| | | old = @new; |
| | | if (propertyName != null) RaisePropertyChanged(propertyName); |
| | | } |
| | | #endregion |
| | | private string _title; |
| | | public string title |
| | | { |
| | | get => _title; |
| | | set => RaiseAndSetIfchanged(ref _title, value); |
| | | } |
| | | |
| | | public ChartWindow(string title) |
| | | { |
| | | this.title = $"{title}详细曲线"; |
| | | this.DataContext = this; |
| | | InitializeComponent(); |
| | | } |
| | | |
| | | private void Window_Unloaded(object sender, RoutedEventArgs e) |
| | | { |
| | | this.mainGrid.Children.Clear(); |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Drawing; |
| | | using System.Globalization; |
| | | using System.Windows.Data; |
| | | |
| | | namespace Plugin.TestResult_WPF.Constant |
| | | { |
| | | public class CommonStatus |
| | | { |
| | | public static readonly string OK = "ok"; |
| | | public static readonly string NG = "ng"; |
| | | public static readonly string WAITING = "waiting"; |
| | | public static readonly string CHECKINFAILED = "checkInFailed"; |
| | | public static readonly string CHECK_IN = "checkIn"; |
| | | public static readonly string TESTING = "testing"; |
| | | public static readonly string ALERT = "alert"; |
| | | public static readonly string READY = "ready"; |
| | | |
| | | private static string[] cache = new string[] { "ok", "ng", "waiting", "checkInFailed", "checkIn", "testing", "alert", "ready" }; |
| | | |
| | | public static readonly Dictionary<string, string> STATUS_MAP = new Dictionary<string, string>() { |
| | | { "ok","正常"}, |
| | | { "ng","异常"}, |
| | | { "waiting","等待中"}, |
| | | { "checkInFailed","CheckIn失败"}, |
| | | { "checkIn","CheckIn"}, |
| | | { "testing","测试中"}, |
| | | { "alert","报警"}, |
| | | { "ready","准备就绪"}, |
| | | }; |
| | | |
| | | public static readonly Dictionary<string, SolidBrush> COLOR_MAP = new Dictionary<string, SolidBrush>() { |
| | | { "ok",new SolidBrush(Color.FromArgb(0,0,0,0))}, |
| | | { "ng",new SolidBrush(Color.FromArgb(0,0,0,0))}, |
| | | { "waiting",new SolidBrush(Color.FromArgb(0,0,0,0))}, |
| | | { "testing",new SolidBrush(Color.FromArgb(0,0,0,0))}, |
| | | { "checkInFailed",new SolidBrush(Color.FromArgb(0,0,0,0))}, |
| | | { "checkIn",new SolidBrush(Color.FromArgb(0,0,0,0))}, |
| | | }; |
| | | |
| | | public static string GetRandomStatus() |
| | | { |
| | | return cache[new Random().Next(cache.Length)]; |
| | | } |
| | | |
| | | public static string GetStatusDescription(string status) |
| | | { |
| | | if (STATUS_MAP.ContainsKey(status)) return STATUS_MAP[status]; |
| | | return ""; |
| | | } |
| | | } |
| | | |
| | | public class StatusColorConverter : IValueConverter |
| | | { |
| | | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) |
| | | { |
| | | if (value is string status) |
| | | { |
| | | |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) |
| | | { |
| | | throw new NotImplementedException(); |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | <UserControl x:Class="Plugin.TestResult_WPF.DataTable" |
| | | 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.TestResult_WPF" |
| | | mc:Ignorable="d" |
| | | Background="#FFF" |
| | | BorderBrush="Black" |
| | | BorderThickness="1" |
| | | x:Name="control" |
| | | Loaded="UserControl_Loaded" |
| | | d:DesignHeight="450" d:DesignWidth="800"> |
| | | <UserControl.Resources> |
| | | <local:FontSizeConverter x:Key="FontSizeConverter"/> |
| | | </UserControl.Resources> |
| | | <Grid x:Name="grid"> |
| | | <Grid.RowDefinitions> |
| | | <RowDefinition Height="Auto"/> |
| | | <RowDefinition Height="8.5*"/> |
| | | <RowDefinition Height="1.5*"/> |
| | | <RowDefinition Height="Auto"/> |
| | | <RowDefinition Height="Auto"/> |
| | | </Grid.RowDefinitions> |
| | | <Grid x:Name="infoGrid" Grid.Row="0" |
| | | Background="LightBlue"> |
| | | <Grid.ColumnDefinitions> |
| | | <ColumnDefinition Width="Auto"/> |
| | | <ColumnDefinition/> |
| | | </Grid.ColumnDefinitions> |
| | | <Label Grid.Row="0" Grid.Column="0" Grid.RowSpan="1" FontSize="20" FontWeight="Bold" |
| | | Padding="0,0,20,0" |
| | | BorderThickness="0,0,0,1" |
| | | BorderBrush="Black" |
| | | VerticalContentAlignment="Center" Background="Transparent" Content="{Binding title}"/> |
| | | <local:InfoTable x:Name="infoTable" Grid.Row="0" Grid.Column="1" |
| | | FontSize="{Binding ActualWidth,RelativeSource={RelativeSource AncestorType=UserControl}, |
| | | Converter={StaticResource FontSizeConverter}, ConverterParameter='15,940'}" |
| | | ></local:InfoTable> |
| | | </Grid> |
| | | |
| | | <UniformGrid x:Name="mainGrid" Grid.Row="1" Columns="6" local:GridProperties.ShowBorder="True" |
| | | local:GridProperties.InnerBorderIgnore="All"> |
| | | </UniformGrid> |
| | | |
| | | <!--<local:Chart Grid.Row="2" x:Name="chart" BorderThickness="0,1,0,1" BorderBrush="Black" |
| | | MouseDoubleClick="chart_MouseDoubleClick"/>--> |
| | | |
| | | <StatusBar Grid.Row="3"> |
| | | <StatusBar.ItemsPanel> |
| | | <ItemsPanelTemplate> |
| | | <DockPanel/> |
| | | </ItemsPanelTemplate> |
| | | </StatusBar.ItemsPanel> |
| | | <StatusBarItem DockPanel.Dock="Right"> |
| | | <StackPanel Orientation="Horizontal"> |
| | | <Ellipse Width="10" Height="10"> |
| | | <Ellipse.Style> |
| | | <Style TargetType="Ellipse"> |
| | | <Setter Property="Fill" Value="Gray"/> |
| | | <Style.Triggers> |
| | | <DataTrigger Binding="{Binding TcpServerStatus,ElementName=control}" Value="ERROR"> |
| | | <Setter Property="Fill" Value="Red"/> |
| | | </DataTrigger> |
| | | <DataTrigger Binding="{Binding TcpServerStatus,ElementName=control}" Value="RUNNING"> |
| | | <Setter Property="Fill" Value="Green"/> |
| | | </DataTrigger> |
| | | </Style.Triggers> |
| | | </Style> |
| | | </Ellipse.Style> |
| | | </Ellipse> |
| | | <TextBlock Text="{Binding TcpServerInfo}"/> |
| | | <Button Padding="0" Margin="0" BorderThickness="0" Click="Button_Click">🔄</Button> |
| | | </StackPanel> |
| | | </StatusBarItem> |
| | | |
| | | <StatusBarItem > |
| | | <TextBox IsReadOnly="True" Background="Transparent" BorderThickness="0" Text="{Binding statusText}"/> |
| | | </StatusBarItem> |
| | | </StatusBar> |
| | | |
| | | <Button Grid.Row="4" Margin="0" Click="SetStationGlobal_Click" BorderThickness="0,1,0,0">启动</Button> |
| | | </Grid> |
| | | </UserControl> |
| New file |
| | |
| | | using Plugin.TestResult_WPF.Model; |
| | | using SuperSocket.SocketBase.Protocol; |
| | | using System; |
| | | using System.ComponentModel; |
| | | using System.Net; |
| | | using System.Net.Sockets; |
| | | using System.Runtime.CompilerServices; |
| | | using System.Threading; |
| | | using System.Windows; |
| | | using System.Windows.Controls; |
| | | |
| | | namespace Plugin.TestResult_WPF |
| | | { |
| | | /// <summary> |
| | | /// DataTable.xaml 的交互逻辑 |
| | | /// </summary> |
| | | public partial class DataTable : UserControl, INotifyPropertyChanged |
| | | { |
| | | #region ... |
| | | public event PropertyChangedEventHandler PropertyChanged; |
| | | |
| | | public virtual void RaisePropertyChanged(string name) |
| | | { |
| | | PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); |
| | | } |
| | | |
| | | public void RaiseAndSetIfchanged<T>(ref T old, T @new, [CallerMemberName] string propertyName = null) |
| | | { |
| | | old = @new; |
| | | if (propertyName != null) RaisePropertyChanged(propertyName); |
| | | } |
| | | #endregion |
| | | |
| | | private string _title; |
| | | |
| | | public string title |
| | | { |
| | | get { return _title; } |
| | | set => RaiseAndSetIfchanged(ref _title, value); |
| | | } |
| | | |
| | | private string _statusText; |
| | | |
| | | public string statusText |
| | | { |
| | | get { return _statusText; } |
| | | set => RaiseAndSetIfchanged(ref _statusText, value); |
| | | } |
| | | |
| | | private string tcpServerStatus; |
| | | |
| | | public string TcpServerStatus |
| | | { |
| | | get { return tcpServerStatus; } |
| | | set { RaiseAndSetIfchanged(ref tcpServerStatus, value); } |
| | | } |
| | | |
| | | private string tcpServerInfo = "未启动"; |
| | | |
| | | public string TcpServerInfo |
| | | { |
| | | get { return tcpServerInfo; } |
| | | set { RaiseAndSetIfchanged(ref tcpServerInfo, value); } |
| | | } |
| | | |
| | | |
| | | private readonly int index; |
| | | private readonly int cellCount; |
| | | private readonly string chartTitle; |
| | | private readonly TestResultView parent; |
| | | |
| | | private BaseConfig config; |
| | | private Chart chart; |
| | | private Chart multiChart; |
| | | private SingleCell[] cells; |
| | | |
| | | private TcpServer tcpServer; |
| | | |
| | | public DataTable(TestResultView parent,int index, string title, BaseConfig config) |
| | | { |
| | | this.config = config; |
| | | this.index = index; |
| | | this.parent = parent; |
| | | this.title = title; |
| | | this.cellCount = config.PositionCount; |
| | | this.cells = new SingleCell[cellCount]; |
| | | this.chartTitle = config.MainChartTitle; |
| | | DataContext = this; |
| | | InitializeComponent(); |
| | | this.chart = new Chart(this.chartTitle, false, config.MaxSize, config.RefreshInterval); |
| | | this.multiChart = new Chart(config.DetailChartTitle, true, config.MaxSize, config.RefreshInterval); |
| | | this.grid.Children.Add(this.chart); |
| | | Grid.SetRow(this.chart, 2); |
| | | this.chart.MouseDoubleClick += chart_MouseDoubleClick; |
| | | |
| | | for (int i = 0; i < this.cellCount; i++) |
| | | { |
| | | var cell = new SingleCell(title, i, config.CellListMaxSize); |
| | | mainGrid.Children.Add(cell); |
| | | cells[i] = cell; |
| | | } |
| | | } |
| | | |
| | | public int GetSize() |
| | | { |
| | | return this.cellCount; |
| | | } |
| | | |
| | | public SingleCell GetSingleCell(int index) |
| | | { |
| | | return cells[index]; |
| | | } |
| | | |
| | | public void SetStatusText(string statusText) |
| | | { |
| | | this.statusText = statusText; |
| | | } |
| | | |
| | | public void SetTemperature(double t) |
| | | { |
| | | infoTable.temperature = t; |
| | | chart.AddData(t); |
| | | } |
| | | |
| | | public void SetTemperature(string name, double t) |
| | | { |
| | | multiChart.AddData(name, t); |
| | | } |
| | | |
| | | public void SetStatus(string status) |
| | | { |
| | | infoTable.status = status; |
| | | } |
| | | |
| | | public void SetOkCount(int count) |
| | | { |
| | | infoTable.okCount = count; |
| | | } |
| | | |
| | | public void SetNgCount(int count) |
| | | { |
| | | infoTable.ngCount = count; |
| | | } |
| | | |
| | | public void SetStartTime(string startTime) |
| | | { |
| | | infoTable.startTimeStr = startTime; |
| | | } |
| | | |
| | | public void SetEndTime(string endTime) |
| | | { |
| | | infoTable.endTimeStr = endTime; |
| | | } |
| | | |
| | | public void SetConsumeTime(double consumeTime) |
| | | { |
| | | infoTable.consumeTime = consumeTime; |
| | | } |
| | | |
| | | private ChartWindow window; |
| | | |
| | | private void chart_MouseDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e) |
| | | { |
| | | /// 打开多个温度曲线 |
| | | if (window == null) |
| | | { |
| | | window = new ChartWindow(title); |
| | | window.Owner = Window.GetWindow(this); |
| | | window.Closed += Window_Closed; |
| | | window.mainGrid.Children.Add(multiChart); |
| | | window.Show(); |
| | | } |
| | | else |
| | | { |
| | | window.Activate(); |
| | | } |
| | | } |
| | | |
| | | private void Window_Closed(object sender, EventArgs e) |
| | | { |
| | | window = null; |
| | | } |
| | | |
| | | private void SetStationGlobal_Click(object sender, RoutedEventArgs e) |
| | | { |
| | | ClearChartData(); |
| | | parent.SetStartFlag(this.index, true); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 清空两个图表数据 |
| | | /// </summary> |
| | | public void ClearChartData() |
| | | { |
| | | chart.Clear(); |
| | | multiChart.Clear(); |
| | | } |
| | | |
| | | private void StartTcpServer() |
| | | { |
| | | try |
| | | { |
| | | if (tcpServer == null) |
| | | { |
| | | tcpServer = new TcpServer(); |
| | | tcpServer.NewRequestReceived += TcpServer_NewRequestReceived; |
| | | if (!tcpServer.Setup(config.PortStart + index)) |
| | | { |
| | | ChangeTcpServerStatus("ERROR", "服务设置异常"); |
| | | return; |
| | | } |
| | | if (!tcpServer.Start()) |
| | | { |
| | | ChangeTcpServerStatus("ERROR", "服务启动异常"); |
| | | return; |
| | | } |
| | | ChangeTcpServerStatus("RUNNING", "服务运行中"); |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | ChangeTcpServerStatus("ERROR", $"服务异常:{ex.Message}"); |
| | | tcpServer?.Stop(); |
| | | tcpServer = null; |
| | | } |
| | | } |
| | | |
| | | private void StopTcpServer() |
| | | { |
| | | if (tcpServer == null) return; |
| | | try |
| | | { |
| | | tcpServer.Stop(); |
| | | tcpServer = null; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | |
| | | } |
| | | } |
| | | |
| | | private void ChangeTcpServerStatus(string status, string info) |
| | | { |
| | | Dispatcher.Invoke(() => |
| | | { |
| | | TcpServerStatus = status; |
| | | TcpServerInfo = info; |
| | | }); |
| | | } |
| | | |
| | | private void TcpServer_NewRequestReceived(TcpSession session, StringRequestInfo requestInfo) |
| | | { |
| | | string msg = requestInfo.Body; |
| | | string[] datas_10015 = msg.Split(';'); |
| | | int cellIndex = int.Parse(datas_10015[1]); |
| | | |
| | | string strs = datas_10015[2]; |
| | | string[] values = strs.Split(','); |
| | | |
| | | //string step = datas_10015[2]; |
| | | //string result = datas_10015[3]; |
| | | GetSingleCell(cellIndex).SetInfos(new Info |
| | | { |
| | | step = values[0], |
| | | value = values[1], |
| | | result = values[2], |
| | | range = values[3], |
| | | condition = values[4], |
| | | updateTime = values[5] |
| | | }); |
| | | session.Send("1"); |
| | | } |
| | | |
| | | private void UserControl_Loaded(object sender, RoutedEventArgs e) |
| | | { |
| | | StartTcpServer(); |
| | | Loaded -= UserControl_Loaded; |
| | | } |
| | | |
| | | private void Button_Click(object sender, RoutedEventArgs e) |
| | | { |
| | | StartTcpServer(); |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | <UserControl x:Class="Plugin.TestResult_WPF.InfoTable" |
| | | 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.TestResult_WPF" |
| | | mc:Ignorable="d" |
| | | d:DesignHeight="450" d:DesignWidth="800"> |
| | | <UserControl.Resources> |
| | | <Style TargetType="Label"> |
| | | <Setter Property="VerticalContentAlignment" Value="Center"/> |
| | | <Setter Property="FontWeight" Value="Bold"/> |
| | | </Style> |
| | | <Style TargetType="TextBox"> |
| | | <Setter Property="VerticalContentAlignment" Value="Center"/> |
| | | <Setter Property="FontWeight" Value="Bold"/> |
| | | <Setter Property="IsReadOnly" Value="True"/> |
| | | <Setter Property="BorderThickness" Value="0"/> |
| | | </Style> |
| | | </UserControl.Resources> |
| | | <Grid x:Name="infoGrid" Grid.Row="0" local:GridProperties.ShowBorder="True" local:GridProperties.InnerBorderIgnore="Top,Right"> |
| | | <Grid.RowDefinitions> |
| | | <RowDefinition/> |
| | | <RowDefinition/> |
| | | </Grid.RowDefinitions> |
| | | <Grid.ColumnDefinitions> |
| | | <ColumnDefinition Width="1*"/> |
| | | <ColumnDefinition Width="2*"/> |
| | | <ColumnDefinition Width="1.5*"/> |
| | | <ColumnDefinition Width="2*"/> |
| | | <ColumnDefinition Width="1.5*"/> |
| | | <ColumnDefinition Width="2*"/> |
| | | </Grid.ColumnDefinitions> |
| | | <Label Grid.Row="0" Grid.Column="0">温度</Label> |
| | | <Label Grid.Row="0" Grid.Column="1" Background="Yellow" Content="{Binding temperatureStr}"/> |
| | | <Label Grid.Row="0" Grid.Column="2">状态</Label> |
| | | <Label Grid.Row="0" Grid.Column="3" Content="{Binding statusStr}"> |
| | | <Label.Style> |
| | | <Style TargetType="Label"> |
| | | <Setter Property="FontWeight" Value="Bold"/> |
| | | <Setter Property="VerticalContentAlignment" Value="Center"/> |
| | | <Style.Triggers> |
| | | <DataTrigger Binding="{Binding status}" Value="ok"> |
| | | <Setter Property="Background" Value="#FF0F8853"/> |
| | | </DataTrigger> |
| | | <DataTrigger Binding="{Binding status}" Value="ng"> |
| | | <Setter Property="Background" Value="#fd6b6d"/> |
| | | </DataTrigger> |
| | | <DataTrigger Binding="{Binding status}" Value="checkInFailed"> |
| | | <Setter Property="Background" Value="#ffac00"/> |
| | | </DataTrigger> |
| | | <DataTrigger Binding="{Binding status}" Value="checkIn"> |
| | | <Setter Property="Background" Value="#FF00E2FF"/> |
| | | </DataTrigger> |
| | | <DataTrigger Binding="{Binding status}" Value="testing"> |
| | | <Setter Property="Background" Value="#1296db"/> |
| | | </DataTrigger> |
| | | <DataTrigger Binding="{Binding status}" Value="waiting"> |
| | | <Setter Property="Background" Value="#6e6e6e"/> |
| | | </DataTrigger> |
| | | <DataTrigger Binding="{Binding status}" Value="alert"> |
| | | <Setter Property="Background" Value="#e04733"/> |
| | | </DataTrigger> |
| | | <DataTrigger Binding="{Binding status}" Value="ready"> |
| | | <Setter Property="Background" Value="#FF08FF00"/> |
| | | </DataTrigger> |
| | | </Style.Triggers> |
| | | </Style> |
| | | </Label.Style> |
| | | </Label> |
| | | <Label Grid.Row="0" Grid.Column="4">老化数量</Label> |
| | | <Label Grid.Row="0" Grid.Column="5" Background="Yellow" Content="{Binding countStr}"/> |
| | | |
| | | <Label Grid.Row="1" Grid.Column="0">开始时间</Label> |
| | | <Label Grid.Row="1" Grid.Column="1" Background="Yellow" Content="{Binding startTimeStr}"/> |
| | | <Label Grid.Row="1" Grid.Column="2">已老化时间</Label> |
| | | <Label Grid.Row="1" Grid.Column="3" Background="Yellow" Content="{Binding consumeTimeStr}"/> |
| | | <Label Grid.Row="1" Grid.Column="4">预计结束时间</Label> |
| | | <Label Grid.Row="1" Grid.Column="5" Background="Yellow" Content="{Binding endTimeStr}"/> |
| | | </Grid> |
| | | </UserControl> |
| New file |
| | |
| | | using Plugin.TestResult_WPF.Constant; |
| | | using System; |
| | | using System.ComponentModel; |
| | | using System.Runtime.CompilerServices; |
| | | using System.Windows.Controls; |
| | | |
| | | namespace Plugin.TestResult_WPF |
| | | { |
| | | /// <summary> |
| | | /// InfoTable.xaml 的交互逻辑 |
| | | /// </summary> |
| | | public partial class InfoTable : UserControl, INotifyPropertyChanged |
| | | { |
| | | |
| | | #region ... |
| | | public event PropertyChangedEventHandler PropertyChanged; |
| | | |
| | | public virtual void RaisePropertyChanged(string name) |
| | | { |
| | | PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); |
| | | } |
| | | |
| | | public void RaiseAndSetIfchanged<T>(ref T old, T @new, [CallerMemberName] string propertyName = null) |
| | | { |
| | | old = @new; |
| | | if (propertyName != null) RaisePropertyChanged(propertyName); |
| | | } |
| | | #endregion |
| | | |
| | | private double _temperature; |
| | | public double temperature |
| | | { |
| | | get => _temperature; |
| | | set |
| | | { |
| | | RaiseAndSetIfchanged(ref _temperature, value); |
| | | RaisePropertyChanged("temperatureStr"); |
| | | } |
| | | } |
| | | |
| | | public string temperatureStr |
| | | { |
| | | get => $"{_temperature.ToString("f2")}℃"; |
| | | } |
| | | |
| | | private string _status; |
| | | public string status |
| | | { |
| | | get => _status; |
| | | set |
| | | { |
| | | RaiseAndSetIfchanged(ref _status, value); |
| | | RaisePropertyChanged("statusStr"); |
| | | } |
| | | } |
| | | |
| | | public string statusStr |
| | | { |
| | | get => status != null && CommonStatus.STATUS_MAP.ContainsKey(status) ? CommonStatus.STATUS_MAP[status] : ""; |
| | | } |
| | | |
| | | private int _okCount; |
| | | public int okCount |
| | | { |
| | | get => _okCount; |
| | | set |
| | | { |
| | | RaiseAndSetIfchanged(ref _okCount, value); |
| | | RefreshCount(); |
| | | } |
| | | } |
| | | |
| | | private int _ngCount; |
| | | |
| | | public int ngCount |
| | | { |
| | | get => _ngCount; |
| | | set |
| | | { |
| | | RaiseAndSetIfchanged(ref _ngCount, value); |
| | | RefreshCount(); |
| | | } |
| | | } |
| | | |
| | | private int _allCount; |
| | | |
| | | public int allCount |
| | | { |
| | | get => _allCount; |
| | | set |
| | | { |
| | | RaiseAndSetIfchanged(ref _allCount, value); |
| | | } |
| | | } |
| | | |
| | | public string countStr |
| | | { |
| | | get => $"OK:{okCount},NG:{ngCount},ALL:{allCount}"; |
| | | } |
| | | |
| | | private string _startTimeStr; |
| | | public string startTimeStr |
| | | { |
| | | get => _startTimeStr; |
| | | set |
| | | { |
| | | RaiseAndSetIfchanged(ref _startTimeStr, value); |
| | | } |
| | | } |
| | | |
| | | private double _consumeTime; |
| | | public double consumeTime |
| | | { |
| | | get => _consumeTime; |
| | | set |
| | | { |
| | | RaiseAndSetIfchanged(ref _consumeTime, value); |
| | | RaisePropertyChanged("consumeTimeStr"); |
| | | } |
| | | } |
| | | |
| | | public string consumeTimeStr |
| | | { |
| | | get |
| | | { |
| | | if (consumeTime < 60) return $"{consumeTime.ToString("f2")}s"; |
| | | else if (consumeTime < 3600) return $"{Math.Floor(consumeTime / 60)}m{(consumeTime % 60).ToString("f2")}s"; |
| | | return $"{Math.Floor(consumeTime / 3600)}h{Math.Floor((consumeTime % 3600) / 60)}m{(consumeTime % 60).ToString("f2")}s"; |
| | | } |
| | | } |
| | | |
| | | private string _endTimeStr; |
| | | |
| | | public string endTimeStr |
| | | { |
| | | get => _endTimeStr; |
| | | set => RaiseAndSetIfchanged(ref _endTimeStr, value); |
| | | } |
| | | |
| | | |
| | | private void RefreshCount() |
| | | { |
| | | this.allCount = this.okCount + this.ngCount; |
| | | RaisePropertyChanged("countStr"); |
| | | } |
| | | |
| | | public InfoTable() |
| | | { |
| | | this.DataContext = this; |
| | | InitializeComponent(); |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | <Window x:Class="Plugin.TestResult_WPF.InfoWindow" |
| | | xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
| | | xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
| | | xmlns:d="http://schemas.microsoft.com/expression/blend/2008" |
| | | xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" |
| | | xmlns:local="clr-namespace:Plugin.TestResult_WPF" |
| | | mc:Ignorable="d" |
| | | Title="{Binding title}" Height="500" Width="800"> |
| | | <DataGrid ItemsSource="{Binding dataSource}" AutoGenerateColumns="False" |
| | | CanUserAddRows="False" |
| | | CanUserDeleteRows="False" |
| | | IsReadOnly="True" |
| | | ColumnWidth="*" |
| | | FontSize="16" |
| | | > |
| | | <DataGrid.Columns> |
| | | <DataGridTextColumn Header="测试项名称" Binding="{Binding step}"/> |
| | | <DataGridTextColumn Header="测试值" Binding="{Binding value}"/> |
| | | <DataGridTextColumn Header="测试结果" Binding="{Binding result}"/> |
| | | <DataGridTextColumn Header="测试范围" Binding="{Binding range}"/> |
| | | <DataGridTextColumn Header="测试条件" Binding="{Binding condition}"/> |
| | | <DataGridTextColumn Header="更新时间" Binding="{Binding updateTime}"/> |
| | | </DataGrid.Columns> |
| | | </DataGrid> |
| | | </Window> |
| New file |
| | |
| | | using Plugin.TestResult_WPF.Model; |
| | | using System.Collections.ObjectModel; |
| | | using System.ComponentModel; |
| | | using System.Runtime.CompilerServices; |
| | | using System.Windows; |
| | | |
| | | namespace Plugin.TestResult_WPF |
| | | { |
| | | /// <summary> |
| | | /// InfoWindow.xaml 的交互逻辑 |
| | | /// </summary> |
| | | public partial class InfoWindow : Window, INotifyPropertyChanged |
| | | { |
| | | |
| | | #region ... |
| | | public event PropertyChangedEventHandler PropertyChanged; |
| | | |
| | | public virtual void RaisePropertyChanged(string name) |
| | | { |
| | | PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); |
| | | } |
| | | |
| | | public void RaiseAndSetIfchanged<T>(ref T old, T @new, [CallerMemberName] string propertyName = null) |
| | | { |
| | | old = @new; |
| | | if (propertyName != null) RaisePropertyChanged(propertyName); |
| | | } |
| | | #endregion |
| | | |
| | | private string _title; |
| | | public string title |
| | | { |
| | | get => _title; |
| | | set => RaiseAndSetIfchanged(ref _title, value); |
| | | } |
| | | |
| | | private ObservableCollection<Info> _dataSource; |
| | | |
| | | public ObservableCollection<Info> dataSource |
| | | { |
| | | get => _dataSource == null ? new ObservableCollection<Info>() : _dataSource; |
| | | set => RaiseAndSetIfchanged(ref _dataSource, value); |
| | | } |
| | | |
| | | public InfoWindow(string title, ObservableCollection<Info> infos) |
| | | { |
| | | this.title = title; |
| | | this.dataSource = infos; |
| | | this.DataContext = this; |
| | | InitializeComponent(); |
| | | } |
| | | |
| | | public void UpdateSource(ObservableCollection<Info> infos) |
| | | { |
| | | this.dataSource = infos; |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | using System.Collections; |
| | | using System.Configuration; |
| | | using System.Runtime.CompilerServices; |
| | | |
| | | namespace Plugin.TestResult_WPF.Model |
| | | { |
| | | public class BaseConfig |
| | | { |
| | | private static Hashtable customConfig = (Hashtable)ConfigurationManager.GetSection("TestResultConfig"); |
| | | /// <summary> |
| | | /// 首页布局行数 |
| | | /// </summary> |
| | | private int row = 1; |
| | | public int Row |
| | | { |
| | | get |
| | | { |
| | | var data = GetValue(); |
| | | return data == null ? row : int.Parse(data); |
| | | } |
| | | } |
| | | |
| | | private string GetValue([CallerMemberName] string propertyName = null) |
| | | { |
| | | return (customConfig != null && customConfig.ContainsKey(propertyName)) ? customConfig[propertyName].ToString() : null; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 首页布局列数 |
| | | /// </summary> |
| | | private int column = 2; |
| | | public int Column |
| | | { |
| | | get |
| | | { |
| | | var data = GetValue(); |
| | | return data == null ? column : int.Parse(data); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 炉数 -1 就是row*column |
| | | /// </summary> |
| | | private int cellCount = -1; |
| | | public int CellCount |
| | | { |
| | | get |
| | | { |
| | | var data = GetValue(); |
| | | return data == null ? cellCount : int.Parse(data); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 每个炉子的点位数 |
| | | /// </summary> |
| | | private int positionCount = 54; |
| | | public int PositionCount |
| | | { |
| | | get |
| | | { |
| | | var data = GetValue(); |
| | | return data == null ? positionCount : int.Parse(data); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 曲线最多保存多少数据 |
| | | /// </summary> |
| | | private int maxSize = 10000; |
| | | public int MaxSize |
| | | { |
| | | get |
| | | { |
| | | var data = GetValue(); |
| | | return data == null ? maxSize : int.Parse(data); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 图表刷新频率 ms |
| | | /// </summary> |
| | | private int refreshInterval = 500; |
| | | public int RefreshInterval |
| | | { |
| | | get |
| | | { |
| | | var data = GetValue(); |
| | | return data == null ? refreshInterval : int.Parse(data); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 炉子名称 |
| | | /// </summary> |
| | | private string nameStr = "A,B,C,D,E,F,G"; |
| | | public string NameStr |
| | | { |
| | | get |
| | | { |
| | | var data = GetValue(); |
| | | return data == null ? nameStr : data; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 默认展示的图表标题 |
| | | /// </summary> |
| | | private string mainChartTitle = "平均温度"; |
| | | public string MainChartTitle |
| | | { |
| | | get |
| | | { |
| | | var data = GetValue(); |
| | | return data == null ? mainChartTitle : data; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 双击打开的详细图表标题 |
| | | /// </summary> |
| | | private string detailChartTitle = "详细温度"; |
| | | public string DetailChartTitle |
| | | { |
| | | get |
| | | { |
| | | var data = GetValue(); |
| | | return data == null ? detailChartTitle : data; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 穴位Step列表最大容量 |
| | | /// </summary> |
| | | private int cellListMaxSize = 10000; |
| | | public int CellListMaxSize |
| | | { |
| | | get |
| | | { |
| | | var data = GetValue(); |
| | | return data == null ? cellListMaxSize : int.Parse(data); |
| | | } |
| | | } |
| | | |
| | | private int portStart = 6660; |
| | | public int PortStart |
| | | { |
| | | get |
| | | { |
| | | var data = GetValue(); |
| | | return data == null ? portStart : int.Parse(data); |
| | | } |
| | | } |
| | | |
| | | public bool testing = false; |
| | | } |
| | | } |
| New file |
| | |
| | | using System.ComponentModel; |
| | | using System.Runtime.CompilerServices; |
| | | |
| | | namespace Plugin.TestResult_WPF.Model |
| | | { |
| | | public class BaseModel : INotifyPropertyChanged |
| | | { |
| | | public event PropertyChangedEventHandler PropertyChanged; |
| | | |
| | | public virtual void RaisePropertyChanged(string name) |
| | | { |
| | | PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); |
| | | } |
| | | |
| | | public void RaiseAndSetIfchanged<T>(ref T old, T @new, [CallerMemberName] string propertyName = null) |
| | | { |
| | | old = @new; |
| | | if (propertyName != null) RaisePropertyChanged(propertyName); |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | namespace Plugin.TestResult_WPF.Model |
| | | { |
| | | public class CellInfo |
| | | { |
| | | public string MachineName { get; set; } |
| | | public string OvenName { get; set; } |
| | | public int Index { get; set; } |
| | | } |
| | | } |
| New file |
| | |
| | | namespace Plugin.TestResult_WPF.Model |
| | | { |
| | | public class DataTableModel : BaseModel |
| | | { |
| | | |
| | | } |
| | | } |
| New file |
| | |
| | | namespace Plugin.TestResult_WPF.Model |
| | | { |
| | | public class Info : BaseModel |
| | | { |
| | | private string _step; |
| | | |
| | | public string step |
| | | { |
| | | get => _step; |
| | | |
| | | set => RaiseAndSetIfchanged(ref _step, value); |
| | | } |
| | | |
| | | private string _value; |
| | | |
| | | public string value |
| | | { |
| | | get => _value; |
| | | |
| | | set => RaiseAndSetIfchanged(ref _value, value); |
| | | } |
| | | |
| | | private string _result; |
| | | |
| | | public string result |
| | | { |
| | | get => _result; |
| | | |
| | | set => RaiseAndSetIfchanged(ref _result, value); |
| | | } |
| | | |
| | | private string _range; |
| | | |
| | | public string range |
| | | { |
| | | get => _range; |
| | | |
| | | set => RaiseAndSetIfchanged(ref _range, value); |
| | | } |
| | | |
| | | private string _condition; |
| | | |
| | | public string condition |
| | | { |
| | | get => _condition; |
| | | |
| | | set => RaiseAndSetIfchanged(ref _condition, value); |
| | | } |
| | | |
| | | private string _updateTime; |
| | | |
| | | public string updateTime |
| | | { |
| | | get => _updateTime; |
| | | |
| | | set => RaiseAndSetIfchanged(ref _updateTime, value); |
| | | } |
| | | |
| | | } |
| | | } |
| New file |
| | |
| | | using ScottPlot.Colormaps; |
| | | using SuperSocket.SocketBase; |
| | | using SuperSocket.SocketBase.Protocol; |
| | | using System; |
| | | using System.Text; |
| | | |
| | | namespace Plugin.TestResult_WPF.Model |
| | | { |
| | | public class DTReceiveFilter : ReceiveFilterBase<StringRequestInfo> |
| | | { |
| | | public override StringRequestInfo Filter(byte[] readBuffer, int offset, int length, bool toBeCopied, out int rest) |
| | | { |
| | | rest = 0; |
| | | StringBuilder sb = new StringBuilder(); |
| | | int i = offset; |
| | | while (i < readBuffer.Length) |
| | | { |
| | | byte b = readBuffer[i++]; |
| | | if (b == '\n') |
| | | { |
| | | break; |
| | | } |
| | | sb.Append((char)b); |
| | | } |
| | | return new StringRequestInfo(DateTime.Now + "", sb.ToString(), null); |
| | | } |
| | | } |
| | | |
| | | public class TcpServer : AppServer<TcpSession> |
| | | { |
| | | public TcpServer() : base(new DefaultReceiveFilterFactory<DTReceiveFilter, StringRequestInfo>()) |
| | | { |
| | | |
| | | } |
| | | } |
| | | |
| | | public class TcpSession : AppSession<TcpSession, StringRequestInfo> |
| | | { |
| | | |
| | | } |
| | | } |
| New file |
| | |
| | | <configuration> |
| | | <dllmap os="linux" dll="opengl32.dll" target="libGL.so.1"/> |
| | | <dllmap os="linux" dll="glu32.dll" target="libGLU.so.1"/> |
| | | <dllmap os="linux" dll="openal32.dll" target="libopenal.so.1"/> |
| | | <dllmap os="linux" dll="alut.dll" target="libalut.so.0"/> |
| | | <dllmap os="linux" dll="opencl.dll" target="libOpenCL.so"/> |
| | | <dllmap os="linux" dll="libX11" target="libX11.so.6"/> |
| | | <dllmap os="linux" dll="libXi" target="libXi.so.6"/> |
| | | <dllmap os="linux" dll="SDL2.dll" target="libSDL2-2.0.so.0"/> |
| | | <dllmap os="osx" dll="opengl32.dll" target="/System/Library/Frameworks/OpenGL.framework/OpenGL"/> |
| | | <dllmap os="osx" dll="openal32.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" /> |
| | | <dllmap os="osx" dll="alut.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" /> |
| | | <dllmap os="osx" dll="libGLES.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" /> |
| | | <dllmap os="osx" dll="libGLESv1_CM.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" /> |
| | | <dllmap os="osx" dll="libGLESv2.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" /> |
| | | <dllmap os="osx" dll="opencl.dll" target="/System/Library/Frameworks/OpenCL.framework/OpenCL"/> |
| | | <dllmap os="osx" dll="SDL2.dll" target="libSDL2.dylib"/> |
| | | <!-- XQuartz compatibility (X11 on Mac) --> |
| | | <dllmap os="osx" dll="libGL.so.1" target="/usr/X11/lib/libGL.dylib"/> |
| | | <dllmap os="osx" dll="libX11" target="/usr/X11/lib/libX11.dylib"/> |
| | | <dllmap os="osx" dll="libXcursor.so.1" target="/usr/X11/lib/libXcursor.dylib"/> |
| | | <dllmap os="osx" dll="libXi" target="/usr/X11/lib/libXi.dylib"/> |
| | | <dllmap os="osx" dll="libXinerama" target="/usr/X11/lib/libXinerama.dylib"/> |
| | | <dllmap os="osx" dll="libXrandr.so.2" target="/usr/X11/lib/libXrandr.dylib"/> |
| | | </configuration> |
| New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?> |
| | | <Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
| | | <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> |
| | | <PropertyGroup> |
| | | <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> |
| | | <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> |
| | | <ProjectGuid>{7375B74C-B6BF-4814-9838-E1CAACAD1897}</ProjectGuid> |
| | | <OutputType>library</OutputType> |
| | | <RootNamespace>Plugin.TestResult</RootNamespace> |
| | | <AssemblyName>Plugin.TestResult</AssemblyName> |
| | | <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion> |
| | | <FileAlignment>512</FileAlignment> |
| | | <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> |
| | | <WarningLevel>4</WarningLevel> |
| | | <Deterministic>true</Deterministic> |
| | | <NuGetPackageImportStamp> |
| | | </NuGetPackageImportStamp> |
| | | </PropertyGroup> |
| | | <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> |
| | | <DebugSymbols>true</DebugSymbols> |
| | | <DebugType>full</DebugType> |
| | | <Optimize>false</Optimize> |
| | | <OutputPath>bin\Debug\</OutputPath> |
| | | <DefineConstants>DEBUG;TRACE</DefineConstants> |
| | | <ErrorReport>prompt</ErrorReport> |
| | | <WarningLevel>4</WarningLevel> |
| | | </PropertyGroup> |
| | | <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> |
| | | <DebugType>pdbonly</DebugType> |
| | | <Optimize>true</Optimize> |
| | | <OutputPath>bin\Release\</OutputPath> |
| | | <DefineConstants>TRACE</DefineConstants> |
| | | <ErrorReport>prompt</ErrorReport> |
| | | <WarningLevel>4</WarningLevel> |
| | | </PropertyGroup> |
| | | <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'"> |
| | | <DebugSymbols>true</DebugSymbols> |
| | | <OutputPath>bin\x64\Debug\</OutputPath> |
| | | <DefineConstants>DEBUG;TRACE</DefineConstants> |
| | | <DebugType>full</DebugType> |
| | | <PlatformTarget>x64</PlatformTarget> |
| | | <LangVersion>7.3</LangVersion> |
| | | <ErrorReport>prompt</ErrorReport> |
| | | </PropertyGroup> |
| | | <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'"> |
| | | <OutputPath>bin\x64\Release\</OutputPath> |
| | | <DefineConstants>TRACE</DefineConstants> |
| | | <Optimize>true</Optimize> |
| | | <DebugType>pdbonly</DebugType> |
| | | <PlatformTarget>x64</PlatformTarget> |
| | | <LangVersion>7.3</LangVersion> |
| | | <ErrorReport>prompt</ErrorReport> |
| | | </PropertyGroup> |
| | | <ItemGroup> |
| | | <Reference Include="CommonLibs"> |
| | | <HintPath>..\Libs\CommonLibs.dll</HintPath> |
| | | </Reference> |
| | | <Reference Include="GLWpfControl, Version=3.3.0.0, Culture=neutral, processorArchitecture=MSIL"> |
| | | <HintPath>..\WPFProject\packages\OpenTK.GLWpfControl.3.3.0\lib\net452\GLWpfControl.dll</HintPath> |
| | | </Reference> |
| | | <Reference Include="HarfBuzzSharp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL"> |
| | | <HintPath>..\WPFProject\packages\HarfBuzzSharp.7.3.0.3\lib\net462\HarfBuzzSharp.dll</HintPath> |
| | | </Reference> |
| | | <Reference Include="NationalInstruments.TestStand.Interop.AdapterAPI, Version=20.0.0.49158, Culture=neutral, PublicKeyToken=ad9244eb3b825cd8, processorArchitecture=MSIL"> |
| | | <SpecificVersion>False</SpecificVersion> |
| | | <EmbedInteropTypes>True</EmbedInteropTypes> |
| | | <HintPath>..\Libs\NationalInstruments.TestStand.Interop.AdapterAPI.dll</HintPath> |
| | | </Reference> |
| | | <Reference Include="NationalInstruments.TestStand.Interop.API, Version=20.0.0.49158, Culture=neutral, PublicKeyToken=ad9244eb3b825cd8, processorArchitecture=MSIL"> |
| | | <SpecificVersion>False</SpecificVersion> |
| | | <EmbedInteropTypes>True</EmbedInteropTypes> |
| | | <HintPath>..\Libs\NationalInstruments.TestStand.Interop.API.dll</HintPath> |
| | | </Reference> |
| | | <Reference Include="NationalInstruments.TestStand.Interop.SequenceAnalyzer, Version=20.0.0.49158, Culture=neutral, PublicKeyToken=ad9244eb3b825cd8, processorArchitecture=MSIL"> |
| | | <SpecificVersion>False</SpecificVersion> |
| | | <EmbedInteropTypes>True</EmbedInteropTypes> |
| | | <HintPath>..\Libs\NationalInstruments.TestStand.Interop.SequenceAnalyzer.dll</HintPath> |
| | | </Reference> |
| | | <Reference Include="NationalInstruments.TestStand.Interop.UI, Version=20.0.0.49158, Culture=neutral, PublicKeyToken=ad9244eb3b825cd8, processorArchitecture=MSIL"> |
| | | <SpecificVersion>False</SpecificVersion> |
| | | <EmbedInteropTypes>True</EmbedInteropTypes> |
| | | <HintPath>..\Libs\NationalInstruments.TestStand.Interop.UI.dll</HintPath> |
| | | </Reference> |
| | | <Reference Include="NationalInstruments.TestStand.Interop.UI.AxControls, Version=20.0.0.49158, Culture=neutral, PublicKeyToken=ad9244eb3b825cd8, processorArchitecture=MSIL"> |
| | | <SpecificVersion>False</SpecificVersion> |
| | | <HintPath>..\Libs\NationalInstruments.TestStand.Interop.UI.AxControls.dll</HintPath> |
| | | </Reference> |
| | | <Reference Include="NationalInstruments.TestStand.Interop.UI.Support, Version=20.0.0.49158, Culture=neutral, PublicKeyToken=ad9244eb3b825cd8, processorArchitecture=MSIL"> |
| | | <SpecificVersion>False</SpecificVersion> |
| | | <EmbedInteropTypes>True</EmbedInteropTypes> |
| | | <HintPath>..\Libs\NationalInstruments.TestStand.Interop.UI.Support.dll</HintPath> |
| | | </Reference> |
| | | <Reference Include="NationalInstruments.TestStand.Utility"> |
| | | <HintPath>..\Libs\NationalInstruments.TestStand.Utility.dll</HintPath> |
| | | </Reference> |
| | | <Reference Include="OpenTK, Version=3.3.1.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL"> |
| | | <HintPath>..\WPFProject\packages\OpenTK.3.3.1\lib\net20\OpenTK.dll</HintPath> |
| | | </Reference> |
| | | <Reference Include="ParameterHelper"> |
| | | <HintPath>..\Libs\ParameterHelper.dll</HintPath> |
| | | </Reference> |
| | | <Reference Include="ScottPlot, Version=5.0.47.0, Culture=neutral, PublicKeyToken=86698dc10387c39e, processorArchitecture=MSIL"> |
| | | <HintPath>..\WPFProject\packages\ScottPlot.5.0.47\lib\net462\ScottPlot.dll</HintPath> |
| | | </Reference> |
| | | <Reference Include="ScottPlot.WPF, Version=5.0.47.0, Culture=neutral, PublicKeyToken=86698dc10387c39e, processorArchitecture=MSIL"> |
| | | <HintPath>..\WPFProject\packages\ScottPlot.WPF.5.0.47\lib\net462\ScottPlot.WPF.dll</HintPath> |
| | | </Reference> |
| | | <Reference Include="SkiaSharp, Version=2.88.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL"> |
| | | <HintPath>..\WPFProject\packages\SkiaSharp.2.88.9\lib\net462\SkiaSharp.dll</HintPath> |
| | | </Reference> |
| | | <Reference Include="SkiaSharp.HarfBuzz, Version=2.88.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL"> |
| | | <HintPath>..\WPFProject\packages\SkiaSharp.HarfBuzz.2.88.9\lib\net462\SkiaSharp.HarfBuzz.dll</HintPath> |
| | | </Reference> |
| | | <Reference Include="SkiaSharp.Views.Desktop.Common, Version=2.88.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL"> |
| | | <HintPath>..\WPFProject\packages\SkiaSharp.Views.Desktop.Common.2.88.9\lib\net462\SkiaSharp.Views.Desktop.Common.dll</HintPath> |
| | | </Reference> |
| | | <Reference Include="SkiaSharp.Views.WPF, Version=2.88.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL"> |
| | | <HintPath>..\WPFProject\packages\SkiaSharp.Views.WPF.2.88.9\lib\net462\SkiaSharp.Views.WPF.dll</HintPath> |
| | | </Reference> |
| | | <Reference Include="SuperSocket.Facility"> |
| | | <HintPath>..\Libs\SuperSocket.Facility.dll</HintPath> |
| | | </Reference> |
| | | <Reference Include="SuperSocket.SocketBase"> |
| | | <HintPath>..\Libs\SuperSocket.SocketBase.dll</HintPath> |
| | | </Reference> |
| | | <Reference Include="SuperSocket.SocketEngine"> |
| | | <HintPath>..\Libs\SuperSocket.SocketEngine.dll</HintPath> |
| | | </Reference> |
| | | <Reference Include="SupersocketCommon"> |
| | | <HintPath>..\Libs\SupersocketCommon.dll</HintPath> |
| | | </Reference> |
| | | <Reference Include="System" /> |
| | | <Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL"> |
| | | <HintPath>..\WPFProject\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll</HintPath> |
| | | </Reference> |
| | | <Reference Include="System.Configuration" /> |
| | | <Reference Include="System.Data" /> |
| | | <Reference Include="System.Drawing" /> |
| | | <Reference Include="System.Drawing.Common, Version=4.0.0.2, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL"> |
| | | <HintPath>..\WPFProject\packages\System.Drawing.Common.4.7.3\lib\net461\System.Drawing.Common.dll</HintPath> |
| | | </Reference> |
| | | <Reference Include="System.Memory, Version=4.0.1.2, Culture=neutral, processorArchitecture=MSIL"> |
| | | <HintPath>..\WPFProject\packages\System.Memory.4.5.5\lib\net461\System.Memory.dll</HintPath> |
| | | <SpecificVersion>False</SpecificVersion> |
| | | </Reference> |
| | | <Reference Include="System.Numerics" /> |
| | | <Reference Include="System.Numerics.Vectors, Version=4.1.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> |
| | | <HintPath>..\WPFProject\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll</HintPath> |
| | | </Reference> |
| | | <Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> |
| | | <HintPath>..\WPFProject\packages\System.Runtime.CompilerServices.Unsafe.4.5.3\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath> |
| | | </Reference> |
| | | <Reference Include="System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL"> |
| | | <HintPath>..\WPFProject\packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll</HintPath> |
| | | </Reference> |
| | | <Reference Include="System.Windows.Forms" /> |
| | | <Reference Include="System.Xml" /> |
| | | <Reference Include="Microsoft.CSharp" /> |
| | | <Reference Include="System.Core" /> |
| | | <Reference Include="System.Xml.Linq" /> |
| | | <Reference Include="System.Data.DataSetExtensions" /> |
| | | <Reference Include="System.Net.Http" /> |
| | | <Reference Include="System.Xaml"> |
| | | <RequiredTargetFramework>4.0</RequiredTargetFramework> |
| | | </Reference> |
| | | <Reference Include="WindowsBase" /> |
| | | <Reference Include="PresentationCore" /> |
| | | <Reference Include="PresentationFramework" /> |
| | | <Reference Include="WindowsFormsIntegration" /> |
| | | </ItemGroup> |
| | | <ItemGroup> |
| | | <Compile Include="ChartWindow.xaml.cs"> |
| | | <DependentUpon>ChartWindow.xaml</DependentUpon> |
| | | </Compile> |
| | | <Compile Include="Constant\CommonConstant.cs" /> |
| | | <Compile Include="Model\BaseConfig.cs" /> |
| | | <Compile Include="Model\CellInfo.cs" /> |
| | | <Compile Include="Model\Info.cs" /> |
| | | <Compile Include="Model\TcpServer.cs" /> |
| | | <Compile Include="Scanner.xaml.cs"> |
| | | <DependentUpon>Scanner.xaml</DependentUpon> |
| | | </Compile> |
| | | <Compile Include="Util\CommonCodeParser.cs" /> |
| | | <Compile Include="Util\FontSizeConverter.cs" /> |
| | | <Compile Include="ViewControl.xaml.cs"> |
| | | <DependentUpon>ViewControl.xaml</DependentUpon> |
| | | </Compile> |
| | | <Page Include="Chart.xaml"> |
| | | <SubType>Designer</SubType> |
| | | <Generator>MSBuild:Compile</Generator> |
| | | </Page> |
| | | <Page Include="ChartWindow.xaml"> |
| | | <SubType>Designer</SubType> |
| | | <Generator>MSBuild:Compile</Generator> |
| | | </Page> |
| | | <Page Include="DataTable.xaml"> |
| | | <SubType>Designer</SubType> |
| | | <Generator>MSBuild:Compile</Generator> |
| | | </Page> |
| | | <Page Include="InfoTable.xaml"> |
| | | <SubType>Designer</SubType> |
| | | <Generator>MSBuild:Compile</Generator> |
| | | </Page> |
| | | <Page Include="InfoWindow.xaml"> |
| | | <SubType>Designer</SubType> |
| | | <Generator>MSBuild:Compile</Generator> |
| | | </Page> |
| | | <Page Include="Scanner.xaml"> |
| | | <SubType>Designer</SubType> |
| | | <Generator>MSBuild:Compile</Generator> |
| | | </Page> |
| | | <Page Include="SingleCell.xaml"> |
| | | <SubType>Designer</SubType> |
| | | <Generator>MSBuild:Compile</Generator> |
| | | </Page> |
| | | <Page Include="TestResultView.xaml"> |
| | | <Generator>MSBuild:Compile</Generator> |
| | | <SubType>Designer</SubType> |
| | | </Page> |
| | | <Compile Include="Chart.xaml.cs"> |
| | | <DependentUpon>Chart.xaml</DependentUpon> |
| | | </Compile> |
| | | <Compile Include="DataTable.xaml.cs"> |
| | | <DependentUpon>DataTable.xaml</DependentUpon> |
| | | </Compile> |
| | | <Compile Include="Util\DpUtil.cs" /> |
| | | <Compile Include="InfoTable.xaml.cs"> |
| | | <DependentUpon>InfoTable.xaml</DependentUpon> |
| | | </Compile> |
| | | <Compile Include="InfoWindow.xaml.cs"> |
| | | <DependentUpon>InfoWindow.xaml</DependentUpon> |
| | | </Compile> |
| | | <Compile Include="Model\BaseModel.cs" /> |
| | | <Compile Include="Model\DataTableModel.cs" /> |
| | | <Compile Include="SingleCell.xaml.cs"> |
| | | <DependentUpon>SingleCell.xaml</DependentUpon> |
| | | </Compile> |
| | | <Compile Include="TestResultView.xaml.cs"> |
| | | <DependentUpon>TestResultView.xaml</DependentUpon> |
| | | <SubType>Code</SubType> |
| | | </Compile> |
| | | <Page Include="ViewControl.xaml"> |
| | | <SubType>Designer</SubType> |
| | | <Generator>MSBuild:Compile</Generator> |
| | | </Page> |
| | | </ItemGroup> |
| | | <ItemGroup> |
| | | <Compile Include="Properties\AssemblyInfo.cs"> |
| | | <SubType>Code</SubType> |
| | | </Compile> |
| | | <Compile Include="Properties\Resources.Designer.cs"> |
| | | <AutoGen>True</AutoGen> |
| | | <DesignTime>True</DesignTime> |
| | | <DependentUpon>Resources.resx</DependentUpon> |
| | | </Compile> |
| | | <Compile Include="Properties\Settings.Designer.cs"> |
| | | <AutoGen>True</AutoGen> |
| | | <DependentUpon>Settings.settings</DependentUpon> |
| | | <DesignTimeSharedInput>True</DesignTimeSharedInput> |
| | | </Compile> |
| | | <EmbeddedResource Include="Properties\Resources.resx"> |
| | | <Generator>ResXFileCodeGenerator</Generator> |
| | | <LastGenOutput>Resources.Designer.cs</LastGenOutput> |
| | | </EmbeddedResource> |
| | | <None Include="OpenTK.dll.config" /> |
| | | <None Include="packages.config" /> |
| | | <None Include="Properties\Settings.settings"> |
| | | <Generator>SettingsSingleFileGenerator</Generator> |
| | | <LastGenOutput>Settings.Designer.cs</LastGenOutput> |
| | | </None> |
| | | </ItemGroup> |
| | | <ItemGroup> |
| | | <Resource Include="Resource\checkInFailed2.png" /> |
| | | <Resource Include="Resource\ng2.png" /> |
| | | <Resource Include="Resource\ok2.png" /> |
| | | <Resource Include="Resource\testing2.png" /> |
| | | <Resource Include="Resource\waiting2.png" /> |
| | | </ItemGroup> |
| | | <ItemGroup> |
| | | <Resource Include="Resource\alert.png" /> |
| | | </ItemGroup> |
| | | <ItemGroup> |
| | | <Resource Include="Resource\checkIn.png" /> |
| | | </ItemGroup> |
| | | <ItemGroup> |
| | | <Resource Include="Resource\ready.png" /> |
| | | </ItemGroup> |
| | | <ItemGroup> |
| | | <Resource Include="Resource\barcode.png" /> |
| | | </ItemGroup> |
| | | <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> |
| | | <Import Project="..\WPFProject\packages\HarfBuzzSharp.NativeAssets.macOS.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.macOS.targets" Condition="Exists('..\WPFProject\packages\HarfBuzzSharp.NativeAssets.macOS.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.macOS.targets')" /> |
| | | <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> |
| | | <PropertyGroup> |
| | | <ErrorText>这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。</ErrorText> |
| | | </PropertyGroup> |
| | | <Error Condition="!Exists('..\WPFProject\packages\HarfBuzzSharp.NativeAssets.macOS.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.macOS.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\WPFProject\packages\HarfBuzzSharp.NativeAssets.macOS.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.macOS.targets'))" /> |
| | | <Error Condition="!Exists('..\WPFProject\packages\HarfBuzzSharp.NativeAssets.Win32.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.Win32.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\WPFProject\packages\HarfBuzzSharp.NativeAssets.Win32.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.Win32.targets'))" /> |
| | | <Error Condition="!Exists('..\WPFProject\packages\SkiaSharp.NativeAssets.macOS.2.88.9\build\net462\SkiaSharp.NativeAssets.macOS.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\WPFProject\packages\SkiaSharp.NativeAssets.macOS.2.88.9\build\net462\SkiaSharp.NativeAssets.macOS.targets'))" /> |
| | | <Error Condition="!Exists('..\WPFProject\packages\SkiaSharp.NativeAssets.Win32.2.88.9\build\net462\SkiaSharp.NativeAssets.Win32.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\WPFProject\packages\SkiaSharp.NativeAssets.Win32.2.88.9\build\net462\SkiaSharp.NativeAssets.Win32.targets'))" /> |
| | | <Error Condition="!Exists('..\WPFProject\packages\HarfBuzzSharp.NativeAssets.Linux.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.Linux.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\WPFProject\packages\HarfBuzzSharp.NativeAssets.Linux.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.Linux.targets'))" /> |
| | | <Error Condition="!Exists('..\WPFProject\packages\SkiaSharp.NativeAssets.Linux.NoDependencies.2.88.9\build\net462\SkiaSharp.NativeAssets.Linux.NoDependencies.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\WPFProject\packages\SkiaSharp.NativeAssets.Linux.NoDependencies.2.88.9\build\net462\SkiaSharp.NativeAssets.Linux.NoDependencies.targets'))" /> |
| | | </Target> |
| | | <Import Project="..\WPFProject\packages\HarfBuzzSharp.NativeAssets.Win32.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.Win32.targets" Condition="Exists('..\WPFProject\packages\HarfBuzzSharp.NativeAssets.Win32.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.Win32.targets')" /> |
| | | <Import Project="..\WPFProject\packages\SkiaSharp.NativeAssets.macOS.2.88.9\build\net462\SkiaSharp.NativeAssets.macOS.targets" Condition="Exists('..\WPFProject\packages\SkiaSharp.NativeAssets.macOS.2.88.9\build\net462\SkiaSharp.NativeAssets.macOS.targets')" /> |
| | | <Import Project="..\WPFProject\packages\SkiaSharp.NativeAssets.Win32.2.88.9\build\net462\SkiaSharp.NativeAssets.Win32.targets" Condition="Exists('..\WPFProject\packages\SkiaSharp.NativeAssets.Win32.2.88.9\build\net462\SkiaSharp.NativeAssets.Win32.targets')" /> |
| | | <Import Project="..\WPFProject\packages\HarfBuzzSharp.NativeAssets.Linux.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.Linux.targets" Condition="Exists('..\WPFProject\packages\HarfBuzzSharp.NativeAssets.Linux.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.Linux.targets')" /> |
| | | <Import Project="..\WPFProject\packages\SkiaSharp.NativeAssets.Linux.NoDependencies.2.88.9\build\net462\SkiaSharp.NativeAssets.Linux.NoDependencies.targets" Condition="Exists('..\WPFProject\packages\SkiaSharp.NativeAssets.Linux.NoDependencies.2.88.9\build\net462\SkiaSharp.NativeAssets.Linux.NoDependencies.targets')" /> |
| | | <PropertyGroup> |
| | | <PostBuildEvent>copy /Y "$(TargetPath)" "$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)\Plugin\$(TargetFileName)" |
| | | copy /Y "$(TargetDir)$(TargetName).pdb" "$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)\Plugin\$(TargetName).pdb"</PostBuildEvent> |
| | | </PropertyGroup> |
| | | </Project> |
| New file |
| | |
| | | using System.Reflection; |
| | | using System.Runtime.InteropServices; |
| | | using System.Windows; |
| | | |
| | | // 有关程序集的一般信息由以下 |
| | | // 控制。更改这些特性值可修改 |
| | | // 与程序集关联的信息。 |
| | | [assembly: AssemblyTitle("Plugin.TestResult_WPF")] |
| | | [assembly: AssemblyDescription("")] |
| | | [assembly: AssemblyConfiguration("")] |
| | | [assembly: AssemblyCompany("")] |
| | | [assembly: AssemblyProduct("Plugin.TestResult_WPF")] |
| | | [assembly: AssemblyCopyright("Copyright © 2024")] |
| | | [assembly: AssemblyTrademark("")] |
| | | [assembly: AssemblyCulture("")] |
| | | |
| | | // 将 ComVisible 设置为 false 会使此程序集中的类型 |
| | | //对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 |
| | | //请将此类型的 ComVisible 特性设置为 true。 |
| | | [assembly: ComVisible(false)] |
| | | |
| | | //若要开始生成可本地化的应用程序,请设置 |
| | | //.csproj 文件中的 <UICulture>CultureYouAreCodingWith</UICulture> |
| | | //在 <PropertyGroup> 中。例如,如果你使用的是美国英语。 |
| | | //使用的是美国英语,请将 <UICulture> 设置为 en-US。 然后取消 |
| | | //对以下 NeutralResourceLanguage 特性的注释。 更新 |
| | | //以下行中的“en-US”以匹配项目文件中的 UICulture 设置。 |
| | | |
| | | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] |
| | | |
| | | |
| | | [assembly: ThemeInfo( |
| | | ResourceDictionaryLocation.None, //主题特定资源词典所处位置 |
| | | //(未在页面中找到资源时使用, |
| | | //或应用程序资源字典中找到时使用) |
| | | ResourceDictionaryLocation.SourceAssembly //常规资源词典所处位置 |
| | | //(未在页面中找到资源时使用, |
| | | //、应用程序或任何主题专用资源字典中找到时使用) |
| | | )] |
| | | |
| | | |
| | | // 程序集的版本信息由下列四个值组成: |
| | | // |
| | | // 主版本 |
| | | // 次版本 |
| | | // 生成号 |
| | | // 修订号 |
| | | // |
| | | //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值 |
| | | //通过使用 "*",如下所示: |
| | | // [assembly: AssemblyVersion("1.0.*")] |
| | | [assembly: AssemblyVersion("1.0.0.0")] |
| | | [assembly: AssemblyFileVersion("1.0.0.0")] |
| New file |
| | |
| | | //------------------------------------------------------------------------------ |
| | | // <auto-generated> |
| | | // 此代码由工具生成。 |
| | | // 运行时版本: 4.0.30319.42000 |
| | | // |
| | | // 对此文件的更改可能导致不正确的行为,如果 |
| | | // 重新生成代码,则所做更改将丢失。 |
| | | // </auto-generated> |
| | | //------------------------------------------------------------------------------ |
| | | |
| | | namespace Plugin.TestResult_WPF.Properties { |
| | | |
| | | |
| | | /// <summary> |
| | | /// 强类型资源类,用于查找本地化字符串等。 |
| | | /// </summary> |
| | | // 此类是由 StronglyTypedResourceBuilder |
| | | // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 |
| | | // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen |
| | | // (以 /str 作为命令选项),或重新生成 VS 项目。 |
| | | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] |
| | | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] |
| | | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] |
| | | internal class Resources { |
| | | |
| | | private static global::System.Resources.ResourceManager resourceMan; |
| | | |
| | | private static global::System.Globalization.CultureInfo resourceCulture; |
| | | |
| | | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] |
| | | internal Resources() { |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 返回此类使用的缓存 ResourceManager 实例。 |
| | | /// </summary> |
| | | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] |
| | | internal static global::System.Resources.ResourceManager ResourceManager { |
| | | get { |
| | | if ((resourceMan == null)) { |
| | | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Plugin.TestResult_WPF.Properties.Resources", typeof(Resources).Assembly); |
| | | resourceMan = temp; |
| | | } |
| | | return resourceMan; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 重写当前线程的 CurrentUICulture 属性,对 |
| | | /// 使用此强类型资源类的所有资源查找执行重写。 |
| | | /// </summary> |
| | | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] |
| | | internal static global::System.Globalization.CultureInfo Culture { |
| | | get { |
| | | return resourceCulture; |
| | | } |
| | | set { |
| | | resourceCulture = value; |
| | | } |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?> |
| | | <root> |
| | | <!-- |
| | | Microsoft ResX Schema |
| | | |
| | | Version 2.0 |
| | | |
| | | The primary goals of this format is to allow a simple XML format |
| | | that is mostly human readable. The generation and parsing of the |
| | | various data types are done through the TypeConverter classes |
| | | associated with the data types. |
| | | |
| | | Example: |
| | | |
| | | ... ado.net/XML headers & schema ... |
| | | <resheader name="resmimetype">text/microsoft-resx</resheader> |
| | | <resheader name="version">2.0</resheader> |
| | | <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> |
| | | <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> |
| | | <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> |
| | | <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> |
| | | <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> |
| | | <value>[base64 mime encoded serialized .NET Framework object]</value> |
| | | </data> |
| | | <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> |
| | | <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> |
| | | <comment>This is a comment</comment> |
| | | </data> |
| | | |
| | | There are any number of "resheader" rows that contain simple |
| | | name/value pairs. |
| | | |
| | | Each data row contains a name, and value. The row also contains a |
| | | type or mimetype. Type corresponds to a .NET class that support |
| | | text/value conversion through the TypeConverter architecture. |
| | | Classes that don't support this are serialized and stored with the |
| | | mimetype set. |
| | | |
| | | The mimetype is used for serialized objects, and tells the |
| | | ResXResourceReader how to depersist the object. This is currently not |
| | | extensible. For a given mimetype the value must be set accordingly: |
| | | |
| | | Note - application/x-microsoft.net.object.binary.base64 is the format |
| | | that the ResXResourceWriter will generate, however the reader can |
| | | read any of the formats listed below. |
| | | |
| | | mimetype: application/x-microsoft.net.object.binary.base64 |
| | | value : The object must be serialized with |
| | | : System.Serialization.Formatters.Binary.BinaryFormatter |
| | | : and then encoded with base64 encoding. |
| | | |
| | | mimetype: application/x-microsoft.net.object.soap.base64 |
| | | value : The object must be serialized with |
| | | : System.Runtime.Serialization.Formatters.Soap.SoapFormatter |
| | | : and then encoded with base64 encoding. |
| | | |
| | | mimetype: application/x-microsoft.net.object.bytearray.base64 |
| | | value : The object must be serialized into a byte array |
| | | : using a System.ComponentModel.TypeConverter |
| | | : and then encoded with base64 encoding. |
| | | --> |
| | | <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> |
| | | <xsd:element name="root" msdata:IsDataSet="true"> |
| | | <xsd:complexType> |
| | | <xsd:choice maxOccurs="unbounded"> |
| | | <xsd:element name="metadata"> |
| | | <xsd:complexType> |
| | | <xsd:sequence> |
| | | <xsd:element name="value" type="xsd:string" minOccurs="0" /> |
| | | </xsd:sequence> |
| | | <xsd:attribute name="name" type="xsd:string" /> |
| | | <xsd:attribute name="type" type="xsd:string" /> |
| | | <xsd:attribute name="mimetype" type="xsd:string" /> |
| | | </xsd:complexType> |
| | | </xsd:element> |
| | | <xsd:element name="assembly"> |
| | | <xsd:complexType> |
| | | <xsd:attribute name="alias" type="xsd:string" /> |
| | | <xsd:attribute name="name" type="xsd:string" /> |
| | | </xsd:complexType> |
| | | </xsd:element> |
| | | <xsd:element name="data"> |
| | | <xsd:complexType> |
| | | <xsd:sequence> |
| | | <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> |
| | | <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> |
| | | </xsd:sequence> |
| | | <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" /> |
| | | <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> |
| | | <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> |
| | | </xsd:complexType> |
| | | </xsd:element> |
| | | <xsd:element name="resheader"> |
| | | <xsd:complexType> |
| | | <xsd:sequence> |
| | | <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> |
| | | </xsd:sequence> |
| | | <xsd:attribute name="name" type="xsd:string" use="required" /> |
| | | </xsd:complexType> |
| | | </xsd:element> |
| | | </xsd:choice> |
| | | </xsd:complexType> |
| | | </xsd:element> |
| | | </xsd:schema> |
| | | <resheader name="resmimetype"> |
| | | <value>text/microsoft-resx</value> |
| | | </resheader> |
| | | <resheader name="version"> |
| | | <value>2.0</value> |
| | | </resheader> |
| | | <resheader name="reader"> |
| | | <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> |
| | | </resheader> |
| | | <resheader name="writer"> |
| | | <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> |
| | | </resheader> |
| | | </root> |
| New file |
| | |
| | | //------------------------------------------------------------------------------ |
| | | // <auto-generated> |
| | | // This code was generated by a tool. |
| | | // Runtime Version:4.0.30319.42000 |
| | | // |
| | | // Changes to this file may cause incorrect behavior and will be lost if |
| | | // the code is regenerated. |
| | | // </auto-generated> |
| | | //------------------------------------------------------------------------------ |
| | | |
| | | namespace Plugin.TestResult_WPF.Properties |
| | | { |
| | | |
| | | |
| | | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] |
| | | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] |
| | | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase |
| | | { |
| | | |
| | | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); |
| | | |
| | | public static Settings Default |
| | | { |
| | | get |
| | | { |
| | | return defaultInstance; |
| | | } |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | <?xml version='1.0' encoding='utf-8'?> |
| | | <SettingsFile xmlns="uri:settings" CurrentProfile="(Default)"> |
| | | <Profiles> |
| | | <Profile Name="(Default)" /> |
| | | </Profiles> |
| | | <Settings /> |
| | | </SettingsFile> |
| New file |
| | |
| | | <Window x:Class="Plugin.TestResult_WPF.Scanner" |
| | | xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
| | | xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
| | | xmlns:d="http://schemas.microsoft.com/expression/blend/2008" |
| | | xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" |
| | | xmlns:local="clr-namespace:Plugin.TestResult_WPF" |
| | | WindowStartupLocation="CenterScreen" |
| | | Closing="Window_Closing" |
| | | mc:Ignorable="d" |
| | | Title="{Binding title}" Height="450" Width="800"> |
| | | <Window.Resources> |
| | | <local:FontSizeConverter x:Key="FontSizeConverter"/> |
| | | <Style TargetType="Label"> |
| | | <Setter Property="HorizontalAlignment" Value="Right"/> |
| | | <Setter Property="FontSize" Value="{Binding ActualWidth,RelativeSource={RelativeSource AncestorType=Window}, |
| | | Converter={StaticResource FontSizeConverter}, ConverterParameter='100,1920'}" /> |
| | | </Style> |
| | | <Style TargetType="TextBox"> |
| | | <Setter Property="FontSize" Value="{Binding ActualWidth,RelativeSource={RelativeSource AncestorType=Window}, |
| | | Converter={StaticResource FontSizeConverter}, ConverterParameter='100,1920'}" /> |
| | | </Style> |
| | | <Style TargetType="Button"> |
| | | <Setter Property="FontSize" Value="{Binding ActualWidth,RelativeSource={RelativeSource AncestorType=Window}, |
| | | Converter={StaticResource FontSizeConverter}, ConverterParameter='100,1920'}" /> |
| | | </Style> |
| | | </Window.Resources> |
| | | |
| | | <Grid> |
| | | <Grid.RowDefinitions> |
| | | <RowDefinition Height="Auto"/> |
| | | <RowDefinition /> |
| | | <!--<RowDefinition />--> |
| | | <RowDefinition /> |
| | | <RowDefinition Height="Auto"/> |
| | | </Grid.RowDefinitions> |
| | | <Grid.ColumnDefinitions> |
| | | <ColumnDefinition Width="Auto"/> |
| | | <ColumnDefinition /> |
| | | </Grid.ColumnDefinitions> |
| | | <Label Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" HorizontalContentAlignment="Center" HorizontalAlignment="Stretch">请依次扫下列条码</Label> |
| | | <Label Grid.Row="1" Grid.Column="0">储位条码</Label> |
| | | <!--<Label Grid.Row="2" Grid.Column="0">夹具条码</Label>--> |
| | | <Label Grid.Row="2" Grid.Column="0">产品条码</Label> |
| | | |
| | | <TextBox Grid.Row="1" Grid.Column="1" x:Name="positionText" TextWrapping="NoWrap"/> |
| | | <!--<TextBox Grid.Row="2" Grid.Column="1"/>--> |
| | | <TextBox Grid.Row="2" Grid.Column="1" x:Name="snrText"/> |
| | | |
| | | <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Grid.Row="4" Grid.Column="0" Grid.ColumnSpan="2"> |
| | | <Button Margin="20" Padding="15" Click="Con_Click">继续扫描</Button> |
| | | <Button Margin="20" Padding="15" Click="Ok_Click">扫描完成</Button> |
| | | </StackPanel> |
| | | </Grid> |
| | | </Window> |
| New file |
| | |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.ComponentModel; |
| | | using System.IO.Ports; |
| | | using System.Linq; |
| | | using System.Runtime.CompilerServices; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | using System.Windows; |
| | | using System.Windows.Controls; |
| | | using System.Windows.Data; |
| | | using System.Windows.Documents; |
| | | using System.Windows.Input; |
| | | using System.Windows.Media; |
| | | using System.Windows.Media.Imaging; |
| | | using System.Windows.Shapes; |
| | | |
| | | namespace Plugin.TestResult_WPF |
| | | { |
| | | public class BarcodeEventArg |
| | | { |
| | | public string name { get; private set; } |
| | | public string positionCode { get; private set; } |
| | | public string snrCode { get; private set; } |
| | | |
| | | public BarcodeEventArg(string name, string positionCode, string snrCode) |
| | | { |
| | | this.name = name; |
| | | this.positionCode = positionCode; |
| | | this.snrCode = snrCode; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// Scanner.xaml 的交互逻辑 |
| | | /// </summary> |
| | | public partial class Scanner : Window, INotifyPropertyChanged |
| | | { |
| | | #region ... |
| | | public event PropertyChangedEventHandler PropertyChanged; |
| | | |
| | | public virtual void RaisePropertyChanged(string name) |
| | | { |
| | | PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); |
| | | } |
| | | |
| | | public void RaiseAndSetIfchanged<T>(ref T old, T @new, [CallerMemberName] string propertyName = null) |
| | | { |
| | | old = @new; |
| | | if (propertyName != null) RaisePropertyChanged(propertyName); |
| | | } |
| | | #endregion |
| | | |
| | | private string _title; |
| | | |
| | | public string title |
| | | { |
| | | get { return _title; } |
| | | set => RaiseAndSetIfchanged(ref _title, value); |
| | | } |
| | | |
| | | public event EventHandler<BarcodeEventArg> FinishBarcode; |
| | | |
| | | private DataTable dataTable; |
| | | SerialPort serialPort; |
| | | public Scanner(string title) |
| | | { |
| | | this.title = title; |
| | | this.DataContext = this; |
| | | InitializeComponent(); |
| | | InitScanner(); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 设置扫码枪 |
| | | /// </summary> |
| | | private void InitScanner() |
| | | { |
| | | string comStr = ""; |
| | | if (serialPort != null) return; |
| | | if (this.title == "一区扫码") |
| | | { |
| | | comStr = "COM1"; |
| | | } |
| | | else |
| | | { |
| | | comStr = "COM2"; |
| | | } |
| | | |
| | | // 配置串口 |
| | | serialPort = new SerialPort |
| | | { |
| | | PortName = comStr, |
| | | BaudRate = 115200, |
| | | Parity = Parity.None, |
| | | DataBits = 8, |
| | | StopBits = StopBits.One, |
| | | Handshake = Handshake.None, |
| | | DtrEnable = true, |
| | | RtsEnable = true |
| | | //ReadTimeout = 500, |
| | | //WriteTimeout = 500, |
| | | //ReciveBufferSize=4096 |
| | | }; |
| | | |
| | | try |
| | | { |
| | | // 打开串口 |
| | | serialPort.Open(); |
| | | // 注册接收数据事件 |
| | | serialPort.DataReceived += SerialPort_DataReceived; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | MessageBox.Show($"初始化扫码枪失败!{ex.StackTrace}"); |
| | | } |
| | | } |
| | | |
| | | private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) |
| | | { |
| | | try |
| | | { |
| | | SerialPort sp = (SerialPort)sender; |
| | | string barcode = ReadDataFrom(sp); |
| | | |
| | | //string barcode = |
| | | Dispatcher.Invoke(() => |
| | | { |
| | | if (snrText.IsFocused) |
| | | { |
| | | snrText.Text = barcode; |
| | | Con_Click(null, null); |
| | | } |
| | | else |
| | | { |
| | | positionText.Text = barcode; |
| | | //positionText.Focus(); |
| | | //snrText.Text = ""; |
| | | snrText.Focus(); |
| | | } |
| | | }); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | MessageBox.Show($"获取扫码枪数据失败!{ex.StackTrace}"); |
| | | } |
| | | } |
| | | |
| | | private void Con_Click(object sender, RoutedEventArgs e) |
| | | { |
| | | Dispatcher.Invoke(() => |
| | | { |
| | | string position = positionText.Text, snr = snrText.Text; |
| | | if (string.IsNullOrEmpty(position) || string.IsNullOrEmpty(snr)) |
| | | { |
| | | MessageBox.Show("请输入储位条码和产品条码"); |
| | | return; |
| | | } |
| | | try |
| | | { |
| | | FinishBarcode.Invoke(this, new BarcodeEventArg(title, position, snr)); |
| | | //positionText.Text = ""; |
| | | //snrText.Text = ""; |
| | | positionText.Focus(); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | MessageBox.Show(ex.Message); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | private void Ok_Click(object sender, RoutedEventArgs e) |
| | | { |
| | | string position = positionText.Text, snr = snrText.Text; |
| | | if (string.IsNullOrEmpty(position) || string.IsNullOrEmpty(snr)) |
| | | { |
| | | MessageBox.Show("请输入储位条码和产品条码"); |
| | | return; |
| | | } |
| | | try |
| | | { |
| | | FinishBarcode.Invoke(this, new BarcodeEventArg(title, position, snr)); |
| | | this.Close(); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | MessageBox.Show(ex.Message); |
| | | } |
| | | } |
| | | |
| | | private string ReadDataFrom(SerialPort sp) |
| | | { |
| | | string barcode = ""; |
| | | while (sp.BytesToRead > 0) |
| | | { |
| | | byte[] buffer = new byte[sp.BytesToRead]; |
| | | sp.Read(buffer, 0, buffer.Length); |
| | | barcode += System.Text.Encoding.UTF8.GetString(buffer); |
| | | System.Threading.Thread.Sleep(50); |
| | | } |
| | | return barcode; |
| | | } |
| | | |
| | | private void Window_Closing(object sender, CancelEventArgs e) |
| | | { |
| | | try |
| | | { |
| | | serialPort.Close(); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | } |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | <UserControl x:Class="Plugin.TestResult_WPF.SingleCell" |
| | | 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.TestResult_WPF" |
| | | mc:Ignorable="d" |
| | | x:Name="uc" |
| | | Padding="5" |
| | | MouseDoubleClick="UserControl_MouseDoubleClick" |
| | | d:DesignHeight="450" d:DesignWidth="800"> |
| | | <UserControl.Resources> |
| | | <local:FontSizeConverter x:Key="FontSizeConverter"/> |
| | | </UserControl.Resources> |
| | | |
| | | <UserControl.ToolTip> |
| | | <ToolTip Padding="5" BorderThickness="1" BorderBrush="Black" Background="Yellow" Content="{Binding tooltipContent}"/> |
| | | </UserControl.ToolTip> |
| | | |
| | | <UserControl.Style> |
| | | <Style TargetType="UserControl"> |
| | | <Style.Triggers> |
| | | <DataTrigger Binding="{Binding status}" Value="ok"> |
| | | <Setter Property="Background" Value="#FF0F8853"/> |
| | | </DataTrigger> |
| | | <DataTrigger Binding="{Binding status}" Value="ng"> |
| | | <Setter Property="Background" Value="#fd6b6d"/> |
| | | </DataTrigger> |
| | | <DataTrigger Binding="{Binding status}" Value="checkInFailed"> |
| | | <Setter Property="Background" Value="#ffac00"/> |
| | | </DataTrigger> |
| | | <DataTrigger Binding="{Binding status}" Value="checkIn"> |
| | | <Setter Property="Background" Value="#FF00E2FF"/> |
| | | </DataTrigger> |
| | | <DataTrigger Binding="{Binding status}" Value="testing"> |
| | | <Setter Property="Background" Value="#1296db"/> |
| | | </DataTrigger> |
| | | <DataTrigger Binding="{Binding status}" Value="waiting"> |
| | | <Setter Property="Background" Value="#6e6e6e"/> |
| | | </DataTrigger> |
| | | <DataTrigger Binding="{Binding status}" Value="alert"> |
| | | <Setter Property="Background" Value="#e04733"/> |
| | | </DataTrigger> |
| | | <DataTrigger Binding="{Binding status}" Value="ready"> |
| | | <Setter Property="Background" Value="#FF08FF00"/> |
| | | </DataTrigger> |
| | | <DataTrigger Binding="{Binding status}" Value="hadCode"> |
| | | <Setter Property="Background" Value="#FFF"/> |
| | | </DataTrigger> |
| | | </Style.Triggers> |
| | | </Style> |
| | | </UserControl.Style> |
| | | <Grid> |
| | | <Grid.RowDefinitions> |
| | | <RowDefinition Height="Auto"/> |
| | | <RowDefinition/> |
| | | </Grid.RowDefinitions> |
| | | <!--<TextBox Grid.Row="0" IsReadOnly="True" TextAlignment="Center" Margin="0,0,0,3" FontSize="15" |
| | | Background="Transparent" BorderThickness="0" Text="{Binding title}"/>--> |
| | | <Label Grid.Row="0" HorizontalContentAlignment="Left" VerticalContentAlignment="Center" Padding="0" Margin="0,0,0,3" |
| | | FontSize="{Binding ActualWidth,RelativeSource={RelativeSource AncestorType=UserControl}, |
| | | Converter={StaticResource FontSizeConverter}, ConverterParameter='15,103'}" |
| | | FontWeight="Bold" |
| | | Background="Transparent" BorderThickness="0" Content="{Binding title}"/> |
| | | <Image Grid.Row="1"> |
| | | <Image.Style> |
| | | <Style TargetType="Image"> |
| | | <Style.Triggers> |
| | | <DataTrigger Binding="{Binding status}" Value="ok"> |
| | | <Setter Property="Source" Value="Resource/ok2.png"/> |
| | | </DataTrigger> |
| | | <DataTrigger Binding="{Binding status}" Value="ng"> |
| | | <Setter Property="Source" Value="Resource/ng2.png"/> |
| | | </DataTrigger> |
| | | <DataTrigger Binding="{Binding status}" Value="checkInFailed"> |
| | | <Setter Property="Source" Value="Resource/checkInFailed2.png"/> |
| | | </DataTrigger> |
| | | <DataTrigger Binding="{Binding status}" Value="checkIn"> |
| | | <Setter Property="Source" Value="Resource/checkIn.png"/> |
| | | </DataTrigger> |
| | | <DataTrigger Binding="{Binding status}" Value="testing"> |
| | | <Setter Property="Source" Value="Resource/testing2.png"/> |
| | | </DataTrigger> |
| | | <DataTrigger Binding="{Binding status}" Value="waiting"> |
| | | <Setter Property="Source" Value="Resource/waiting2.png"/> |
| | | </DataTrigger> |
| | | <DataTrigger Binding="{Binding status}" Value="alert"> |
| | | <Setter Property="Source" Value="Resource/alert.png"/> |
| | | </DataTrigger> |
| | | <DataTrigger Binding="{Binding status}" Value="ready"> |
| | | <Setter Property="Source" Value="Resource/ready.png"/> |
| | | </DataTrigger> |
| | | <DataTrigger Binding="{Binding status}" Value="hadCode"> |
| | | <Setter Property="Source" Value="Resource/barcode.png"/> |
| | | </DataTrigger> |
| | | </Style.Triggers> |
| | | </Style> |
| | | </Image.Style> |
| | | </Image> |
| | | </Grid> |
| | | </UserControl> |
| New file |
| | |
| | | using Plugin.TestResult_WPF.Constant; |
| | | using Plugin.TestResult_WPF.Model; |
| | | using System; |
| | | using System.Collections.Concurrent; |
| | | using System.Collections.Generic; |
| | | using System.Collections.ObjectModel; |
| | | using System.ComponentModel; |
| | | using System.Runtime.CompilerServices; |
| | | using System.Windows; |
| | | using System.Windows.Controls; |
| | | using System.Windows.Input; |
| | | |
| | | namespace Plugin.TestResult_WPF |
| | | { |
| | | /// <summary> |
| | | /// SingleCell.xaml 的交互逻辑 |
| | | /// </summary> |
| | | public partial class SingleCell : UserControl, INotifyPropertyChanged |
| | | { |
| | | |
| | | #region ... |
| | | public event PropertyChangedEventHandler PropertyChanged; |
| | | |
| | | public virtual void RaisePropertyChanged(string name) |
| | | { |
| | | PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); |
| | | } |
| | | |
| | | public void RaiseAndSetIfchanged<T>(ref T old, T @new, [CallerMemberName] string propertyName = null) |
| | | { |
| | | old = @new; |
| | | if (propertyName != null) RaisePropertyChanged(propertyName); |
| | | } |
| | | #endregion |
| | | |
| | | private InfoWindow window; |
| | | private int maxSize; |
| | | |
| | | public SingleCell() |
| | | { |
| | | DataContext = this; |
| | | InitializeComponent(); |
| | | } |
| | | |
| | | public SingleCell(string parentName, int index,int maxSize) |
| | | { |
| | | this.parentName = parentName; |
| | | this.index = index; |
| | | this.maxSize = maxSize; |
| | | DataContext = this; |
| | | InitializeComponent(); |
| | | } |
| | | |
| | | private string _parentName; |
| | | public string parentName |
| | | { |
| | | get { return _parentName; } |
| | | set |
| | | { |
| | | RaiseAndSetIfchanged(ref _parentName, value); |
| | | RaisePropertyChanged("title"); |
| | | } |
| | | } |
| | | |
| | | private int _index; |
| | | |
| | | public int index |
| | | { |
| | | get { return _index; } |
| | | set |
| | | { |
| | | RaiseAndSetIfchanged(ref _index, value); |
| | | RaisePropertyChanged("title"); |
| | | } |
| | | } |
| | | |
| | | public string title => $"{parentName}{index + 1}"; |
| | | |
| | | private string _status = CommonStatus.WAITING; |
| | | |
| | | public string tooltipContent |
| | | { |
| | | get |
| | | { |
| | | string dataStr = ""; |
| | | if (infos != null && infos.Count > 0) |
| | | { |
| | | foreach (var info in infos) |
| | | { |
| | | dataStr += $"\r\nStep:{info.step},Result:{info.result}"; |
| | | } |
| | | } |
| | | return $"{title}\r\n状态:{CommonStatus.GetStatusDescription(status)}{dataStr}"; |
| | | } |
| | | } |
| | | |
| | | public string status |
| | | { |
| | | get { return _status; } |
| | | set => RaiseAndSetIfchanged(ref _status, value); |
| | | } |
| | | |
| | | private ConcurrentQueue<Info> queue = new ConcurrentQueue<Info>(); |
| | | |
| | | private ObservableCollection<Info> _infos; |
| | | |
| | | public ObservableCollection<Info> infos |
| | | { |
| | | get => _infos; |
| | | set |
| | | { |
| | | RaiseAndSetIfchanged(ref _infos, value); |
| | | RaisePropertyChanged("tooltipContent"); |
| | | } |
| | | } |
| | | |
| | | private void UserControl_MouseDoubleClick(object sender, MouseButtonEventArgs e) |
| | | { |
| | | if (window == null) |
| | | { |
| | | window = new InfoWindow(title, infos); |
| | | window.Closed += Window_Closed; |
| | | window.Owner = Window.GetWindow(this); |
| | | window.Show(); |
| | | } |
| | | else |
| | | { |
| | | window.Activate(); |
| | | } |
| | | } |
| | | |
| | | private void Window_Closed(object sender, EventArgs e) |
| | | { |
| | | this.window = null; |
| | | } |
| | | |
| | | public void SetStatus(string status) |
| | | { |
| | | this.status = status; |
| | | } |
| | | |
| | | public void SetInfos(List<Info> infos) |
| | | { |
| | | this.infos = new ObservableCollection<Info>(infos); |
| | | if (window != null) window.UpdateSource(this.infos); |
| | | } |
| | | |
| | | public void SetInfos(string[,] infos) |
| | | { |
| | | var data = new ObservableCollection<Info>(); |
| | | for (int i = 0; i < infos.GetLength(0); i++) |
| | | { |
| | | data.Add(new Info |
| | | { |
| | | step = infos[i, 0], |
| | | result = infos[i, 1] |
| | | }); |
| | | } |
| | | this.infos = data; |
| | | if (window != null) window.UpdateSource(this.infos); |
| | | } |
| | | |
| | | public void SetInfos(Info info) |
| | | { |
| | | if (queue.Count >= maxSize) |
| | | { |
| | | queue.TryDequeue(out var first); |
| | | } |
| | | queue.Enqueue(info); |
| | | var list = new ObservableCollection<Info>(queue); |
| | | this.infos = list; |
| | | if (window != null) window.UpdateSource(this.infos); |
| | | } |
| | | |
| | | public void ClearInfo() |
| | | { |
| | | queue = new ConcurrentQueue<Info>(); |
| | | var list = new ObservableCollection<Info>(queue); |
| | | this.infos = list; |
| | | if (window != null) window.UpdateSource(this.infos); |
| | | } |
| | | |
| | | public void SetInfos(string step, string result) |
| | | { |
| | | if (queue.Count >= maxSize) |
| | | { |
| | | queue.TryDequeue(out var info); |
| | | } |
| | | queue.Enqueue(new Info() { step = step, result = result }); |
| | | var list = new ObservableCollection<Info>(queue); |
| | | this.infos = list; |
| | | if (window != null) window.UpdateSource(this.infos); |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | <UserControl x:Class="Plugin.TestResult_WPF.TestResultView" |
| | | 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.TestResult_WPF" |
| | | mc:Ignorable="d" |
| | | FontFamily="Microsoft YaHei" |
| | | d:DesignHeight="450" d:DesignWidth="800"> |
| | | <Grid x:Name="panel"> |
| | | <WindowsFormsHost x:Name="host" Visibility="Collapsed"></WindowsFormsHost> |
| | | <Grid x:Name="mainGrid" local:GridProperties.BorderSpace="10"> |
| | | |
| | | </Grid> |
| | | </Grid> |
| | | </UserControl> |
| New file |
| | |
| | | using NationalInstruments.TestStand.Interop.API; |
| | | using NationalInstruments.TestStand.Interop.UI.Ax; |
| | | using NationalInstruments.TestStand.Utility; |
| | | using Plugin.TestResult_WPF.Constant; |
| | | using Plugin.TestResult_WPF.Model; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Windows; |
| | | using System.Windows.Controls; |
| | | |
| | | namespace Plugin.TestResult_WPF |
| | | { |
| | | /// <summary> |
| | | /// TestResultView.xaml 的交互逻辑 |
| | | /// </summary> |
| | | public partial class TestResultView : UserControl |
| | | { |
| | | private int rowCount; |
| | | private int colCount; |
| | | private int cellCount; |
| | | private DataTable[] tables; |
| | | public Dictionary<string, DataTable> nameTables { get; private set; } |
| | | private readonly BaseConfig config; |
| | | |
| | | public AxApplicationMgr testApp; |
| | | public string testSeqFile; |
| | | /// <summary> |
| | | /// 测试序列 |
| | | /// </summary> |
| | | private SequenceFile testSeq = null; |
| | | public Engine engine; |
| | | private Execution execution = null; |
| | | /// <summary> |
| | | /// 测试序列操作句柄 |
| | | /// </summary> |
| | | private SequenceContext SequenceContext = null; |
| | | /// <summary> |
| | | /// 测试模型序列 |
| | | /// </summary> |
| | | private SequenceFile modeSeq; |
| | | |
| | | public TestResultView() : this(new BaseConfig { testing = false }) |
| | | { |
| | | |
| | | } |
| | | |
| | | public TestResultView(BaseConfig config) |
| | | { |
| | | this.rowCount = config.Row; |
| | | this.colCount = config.Column; |
| | | this.config = config; |
| | | if (config.CellCount < 0) |
| | | { |
| | | this.cellCount = rowCount * colCount; |
| | | } |
| | | else |
| | | { |
| | | this.cellCount = config.CellCount; |
| | | } |
| | | tables = new DataTable[this.cellCount]; |
| | | |
| | | |
| | | InitializeComponent(); |
| | | testApp = new AxApplicationMgr(); |
| | | testApp.ExitApplication += new EventHandler(this.axApplicationMgr_ExitApplication); |
| | | testApp.UIMessageEvent += new _ApplicationMgrEvents_UIMessageEventEventHandler(this.axApplicationMgr_UIMessageEvent); |
| | | testApp.ExecutionClosed += new _ApplicationMgrEvents_ExecutionClosedEventHandler(this.axApplicationMgr_ExecutionClosed); |
| | | |
| | | |
| | | ((System.ComponentModel.ISupportInitialize)(this.testApp)).BeginInit();//myClient为第三方控件名 |
| | | host.Child = testApp; |
| | | ((System.ComponentModel.ISupportInitialize)(this.testApp)).EndInit(); |
| | | InitMainGrid(); |
| | | //InitTestStandEngine(); |
| | | //StartTestSequence(); |
| | | } |
| | | |
| | | private void Refresh() |
| | | { |
| | | for (int i = 0; i < tables.Length; i++) |
| | | { |
| | | var sb = new System.Timers.Timer() |
| | | { |
| | | Interval = 1000, |
| | | AutoReset = true, |
| | | }; |
| | | var table = tables[i]; |
| | | Random random = new Random(i * 13); |
| | | sb.Elapsed += (s, e) => |
| | | { |
| | | |
| | | table.SetTemperature(random.Next(100)); |
| | | for (int j = 0; j < 3; j++) |
| | | { |
| | | table.SetTemperature(j + "89", random.Next(100)); |
| | | } |
| | | table.SetOkCount(random.Next(100)); |
| | | table.SetNgCount(random.Next(100)); |
| | | table.SetStatus(CommonStatus.GetRandomStatus()); |
| | | table.SetStartTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); |
| | | table.SetEndTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); |
| | | table.SetConsumeTime(random.Next(10000)); |
| | | |
| | | |
| | | var cell = table.GetSingleCell(random.Next(table.GetSize())); |
| | | cell.SetStatus(CommonStatus.GetRandomStatus()); |
| | | cell.SetInfos(random.Next(1000) + "", random.Next(1000) + ""); |
| | | table.SetStatusText(DateTime.Now + ""); |
| | | }; |
| | | sb.Start(); |
| | | } |
| | | } |
| | | |
| | | public void InitMainGrid() |
| | | { |
| | | nameTables = new Dictionary<string, DataTable>(); |
| | | for (int r = 0; r < rowCount; r++) |
| | | { |
| | | RowDefinition row = new RowDefinition(); |
| | | mainGrid.RowDefinitions.Add(row); |
| | | } |
| | | |
| | | for (int c = 0; c < colCount; c++) |
| | | { |
| | | ColumnDefinition col = new ColumnDefinition(); |
| | | mainGrid.ColumnDefinitions.Add(col); |
| | | } |
| | | string[] names = config.NameStr.Split(','); |
| | | for (int n = 0; n < cellCount; n++) |
| | | { |
| | | string name = n < names.Length ? names[n] : ""; |
| | | DataTable child = new DataTable(this, n, name, config); |
| | | mainGrid.Children.Add(child); |
| | | tables[n] = child; |
| | | nameTables[name] = child; |
| | | int row = n / colCount; |
| | | int col = n % colCount; |
| | | Grid.SetRow(child, row); |
| | | Grid.SetColumn(child, col); |
| | | } |
| | | if (config.testing) Refresh(); |
| | | } |
| | | |
| | | public DataTable GetDataTable(int index) |
| | | { |
| | | if (index > 0 && index < tables.Length) return tables[index]; |
| | | return null; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 启动测试序列 |
| | | /// </summary> |
| | | public void InitTestStandEngine() |
| | | { |
| | | try |
| | | { |
| | | this.engine = this.testApp.GetEngine(); |
| | | this.engine.PersistBreakpoints = false; |
| | | this.testApp.IsEditor = true; |
| | | this.testApp.LoginOnStart = false; |
| | | this.testApp.Start(); |
| | | this.modeSeq = this.engine.GetSequenceFileEx(@"C:\Program Files\National Instruments\TestStand 2020\Components\Models\TestStandModels\ParallelModel.seq"); |
| | | |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | throw new Exception("初始化TS引擎失败:" + ex.Message); |
| | | } |
| | | } |
| | | |
| | | public void StartTestSequence() |
| | | { |
| | | try |
| | | { |
| | | 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); |
| | | this.engine.Globals.SetValBoolean("StationState.StopTest", 0, false); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | throw new Exception("启动测试序列失败:" + ex.Message); |
| | | } |
| | | } |
| | | |
| | | public void StopTest() |
| | | { |
| | | try |
| | | { |
| | | if (this.SequenceContext == null) |
| | | return; |
| | | bool val = this.SequenceContext.StationGlobals.Exists("StationState.StopTest", 0); |
| | | if (val) |
| | | { |
| | | this.SequenceContext.StationGlobals.SetValBoolean("StationState.StopTest", 0, true); |
| | | bool isStop = this.execution.WaitForEndEx(2000, true, null, null); |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | throw new Exception(ex.Message); |
| | | } |
| | | } |
| | | |
| | | private void axApplicationMgr_ExitApplication(object sender, EventArgs e) |
| | | { |
| | | Environment.ExitCode = testApp.ExitCode; |
| | | TSHelper.DoSynchronousGCForCOMObjectDestruction(); |
| | | } |
| | | |
| | | private void axApplicationMgr_ExecutionClosed(object sender, _ApplicationMgrEvents_ExecutionClosedEvent e) |
| | | { |
| | | try |
| | | { |
| | | //this.ReleaseSequenceFile(); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | MessageBox.Show("释放测试序列失败:" + ex.Message); |
| | | } |
| | | } |
| | | |
| | | private void axApplicationMgr_UIMessageEvent(object sender, _ApplicationMgrEvents_UIMessageEventEvent e) |
| | | { |
| | | try |
| | | { |
| | | int EventCase = Convert.ToInt32(e.uiMsg.Event); |
| | | int MethodCode = Convert.ToInt16(e.uiMsg.NumericData); |
| | | string strData; |
| | | |
| | | if (EventCase != 10014) return; |
| | | |
| | | if (MethodCode == 0) |
| | | { |
| | | /// 设置句柄 |
| | | this.SequenceContext = (SequenceContext)e.uiMsg.ActiveXData; |
| | | return; |
| | | } |
| | | |
| | | if (MethodCode == 1) |
| | | { |
| | | /// 更新炉子状态 |
| | | strData = e.uiMsg.StringData; |
| | | string[] datas_10014 = strData.Split(';'); |
| | | int ovenIndex = int.Parse(datas_10014[0]); |
| | | |
| | | string status = datas_10014[1]; |
| | | tables[ovenIndex].SetStatus(status); |
| | | return; |
| | | } |
| | | if (MethodCode == 2) |
| | | { |
| | | /// 更新炉子数量信息 |
| | | strData = e.uiMsg.StringData; |
| | | string[] datas_10014 = strData.Split(';'); |
| | | int ovenIndex = int.Parse(datas_10014[0]); |
| | | |
| | | string okCount = datas_10014[1]; |
| | | string ngCount = datas_10014[2]; |
| | | tables[ovenIndex].SetOkCount(int.Parse(okCount)); |
| | | tables[ovenIndex].SetNgCount(int.Parse(ngCount)); |
| | | return; |
| | | } |
| | | if (MethodCode == 3) |
| | | { |
| | | /// 更新炉子时间信息 |
| | | strData = e.uiMsg.StringData; |
| | | string[] datas_10014 = strData.Split(';'); |
| | | int ovenIndex = int.Parse(datas_10014[0]); |
| | | |
| | | string startTime = datas_10014[1]; |
| | | string consumeTime = datas_10014[2]; |
| | | string planEndTime = datas_10014[3]; |
| | | tables[ovenIndex].SetStartTime(startTime); |
| | | tables[ovenIndex].SetConsumeTime(double.Parse(consumeTime)); |
| | | tables[ovenIndex].SetEndTime(planEndTime); |
| | | return; |
| | | } |
| | | if (MethodCode == 4) |
| | | { |
| | | /// 更新老化炉底部状态栏 |
| | | strData = e.uiMsg.StringData; |
| | | string[] datas_10014 = strData.Split(';'); |
| | | int ovenIndex = int.Parse(datas_10014[0]); |
| | | |
| | | string statusBar = datas_10014[1]; |
| | | tables[ovenIndex].SetStatusText(statusBar); |
| | | return; |
| | | } |
| | | if (MethodCode == 5) |
| | | { |
| | | /// 采集炉温度 |
| | | strData = e.uiMsg.StringData; |
| | | string[] datas_10016 = strData.Split(';'); |
| | | int ovenIndex = int.Parse(datas_10016[0]); |
| | | |
| | | string[] names = datas_10016[1].Split(','); |
| | | string[] values = datas_10016[2].Split(','); |
| | | |
| | | for (int x = 0; x < values.Length; x++) |
| | | { |
| | | if (x == 0) tables[ovenIndex].SetTemperature(double.Parse(values[x])); |
| | | else tables[ovenIndex].SetTemperature(names[x - 1], double.Parse(values[x])); |
| | | } |
| | | return; |
| | | } |
| | | if (MethodCode == 6) |
| | | { |
| | | /// 更新穴位状态 |
| | | strData = e.uiMsg.StringData; |
| | | string[] datas_10015 = strData.Split(';'); |
| | | int ovenIndex = int.Parse(datas_10015[0]); |
| | | int cellIndex = int.Parse(datas_10015[1]); |
| | | string status_10015 = datas_10015[2]; |
| | | tables[ovenIndex].GetSingleCell(cellIndex).SetStatus(status_10015); |
| | | return; |
| | | } |
| | | if (MethodCode == 7) |
| | | { |
| | | /// 更新穴位参数 |
| | | strData = e.uiMsg.StringData; |
| | | string[] datas_10015 = strData.Split(';'); |
| | | int ovenIndex = int.Parse(datas_10015[0]); |
| | | int cellIndex = int.Parse(datas_10015[1]); |
| | | |
| | | string strs = datas_10015[2]; |
| | | string[] values = strs.Split(','); |
| | | |
| | | //string step = datas_10015[2]; |
| | | //string result = datas_10015[3]; |
| | | tables[ovenIndex].GetSingleCell(cellIndex).SetInfos(new Info |
| | | { |
| | | step = values[0], |
| | | value = values[1], |
| | | result = values[2], |
| | | range = values[3], |
| | | condition = values[4], |
| | | updateTime = values[5] |
| | | }); |
| | | return; |
| | | } |
| | | if (MethodCode == 10) |
| | | { |
| | | /// 清空炉子的温度图表 |
| | | strData = e.uiMsg.StringData; |
| | | int ovenIndex = int.Parse(strData); |
| | | tables[ovenIndex].ClearChartData(); |
| | | return; |
| | | } |
| | | if (MethodCode == 11) |
| | | { |
| | | /// 清除穴位参数 |
| | | strData = e.uiMsg.StringData; |
| | | string[] datas_10015 = strData.Split(';'); |
| | | int ovenIndex = int.Parse(datas_10015[0]); |
| | | int cellIndex = int.Parse(datas_10015[1]); |
| | | tables[ovenIndex].GetSingleCell(cellIndex).ClearInfo(); |
| | | return; |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | |
| | | } |
| | | } |
| | | |
| | | public void SetStartFlag(int index, bool data) |
| | | { |
| | | if (this.SequenceContext == null) return; |
| | | char name = (char)(index + 65); |
| | | string key = $"StationState.Start_{name}"; |
| | | this.engine.Globals.SetValBoolean(key, 0, data); |
| | | bool val = this.engine.Globals.GetValBoolean(key, 0); |
| | | //this.SequenceContext.StationGlobals.SetValBoolean(key, 0, data); |
| | | //bool val = this.SequenceContext.StationGlobals.GetValBoolean(key, 0); |
| | | } |
| | | |
| | | public void SetSnrToSeqContext(int index, string snr) |
| | | { |
| | | |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | using Plugin.TestResult_WPF.Model; |
| | | |
| | | namespace Plugin.TestResult_WPF.Util |
| | | { |
| | | public class CommonCodeParser |
| | | { |
| | | public CellInfo GetCellInfoByCode(string code) |
| | | { |
| | | string[] arr = code.Split('-'); |
| | | if (arr == null || arr.Length != 3) |
| | | { |
| | | throw new Exception("扫码格式异常"); |
| | | } |
| | | return new CellInfo() |
| | | { |
| | | MachineName = arr[0], |
| | | OvenName = arr[1], |
| | | Index = int.Parse(arr[2]) - 1, |
| | | }; |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | using System.Collections.Generic; |
| | | using System.Windows; |
| | | using System.Windows.Controls; |
| | | using System.Windows.Controls.Primitives; |
| | | using System.Windows.Media; |
| | | |
| | | namespace Plugin.TestResult_WPF |
| | | { |
| | | public class GridProperties |
| | | { |
| | | public static bool GetShowBorder(DependencyObject obj) |
| | | { |
| | | return (bool)obj.GetValue(ShowBorderProperty); |
| | | } |
| | | public static void SetShowBorder(DependencyObject obj, bool value) |
| | | { |
| | | obj.SetValue(ShowBorderProperty, value); |
| | | } |
| | | public static readonly DependencyProperty ShowBorderProperty = |
| | | DependencyProperty.RegisterAttached("ShowBorder", typeof(bool), typeof(Grid), new PropertyMetadata(false, OnShowBorderChanged)); |
| | | |
| | | public static int GetBorderSpace(DependencyObject obj) |
| | | { |
| | | return (int)obj.GetValue(BorderSpaceProperty); |
| | | } |
| | | public static void SetBorderSpace(DependencyObject obj, int value) |
| | | { |
| | | obj.SetValue(BorderSpaceProperty, value); |
| | | } |
| | | public static readonly DependencyProperty BorderSpaceProperty = |
| | | DependencyProperty.RegisterAttached("BorderSpace", typeof(int), typeof(Grid), new PropertyMetadata(0, OnShowBorderChanged)); |
| | | |
| | | public static string GetInnerBorderIgnore(DependencyObject obj) |
| | | { |
| | | return (string)obj.GetValue(InnerBorderIgnoreProperty); |
| | | } |
| | | public static void SetInnerBorderIgnore(DependencyObject obj, string value) |
| | | { |
| | | obj.SetValue(InnerBorderIgnoreProperty, value); |
| | | } |
| | | public static readonly DependencyProperty InnerBorderIgnoreProperty = |
| | | DependencyProperty.RegisterAttached("InnerBorderIgnore", typeof(string), |
| | | typeof(Grid), new PropertyMetadata("None", OnShowBorderChanged)); |
| | | |
| | | |
| | | private static void OnShowBorderChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) |
| | | { |
| | | if (d is Grid grid) |
| | | { |
| | | if (e.Property == ShowBorderProperty) |
| | | { |
| | | grid.Loaded += GridInnerBorderLoaded; |
| | | return; |
| | | } |
| | | else if (e.Property == BorderSpaceProperty) |
| | | { |
| | | grid.Loaded += GridSpaceOnLoaded; |
| | | return; |
| | | } |
| | | } |
| | | else if (d is UniformGrid uniformGrid) |
| | | { |
| | | uniformGrid.Loaded += UniformGridOnLoad; |
| | | return; |
| | | } |
| | | } |
| | | |
| | | private static void GridInnerBorderLoaded(object sender, RoutedEventArgs e) |
| | | { |
| | | if (!(sender is Grid grid)) return; |
| | | var rowCount = grid.RowDefinitions.Count; |
| | | var columnCount = grid.ColumnDefinitions.Count; |
| | | int totalCount = rowCount * columnCount; |
| | | |
| | | int width = 1; |
| | | |
| | | string baseData = GetInnerBorderIgnore(grid); |
| | | HashSet<string> data = new HashSet<string>(baseData.Split(',')); |
| | | bool ignoreTop = data.Contains("All") || data.Contains("Top"), |
| | | ignoreBottom = data.Contains("All") || data.Contains("Bottom"), |
| | | ignoreLeft = data.Contains("All") || data.Contains("Left"), |
| | | ignoreRight = data.Contains("All") || data.Contains("Right"); |
| | | |
| | | foreach (var child in grid.Children) |
| | | { |
| | | int row = Grid.GetRow((UIElement)child); |
| | | int col = Grid.GetColumn((UIElement)child); |
| | | |
| | | var bt = new Thickness(col == 0 ? (ignoreLeft ? 0 : width) : 0, |
| | | row == 0 ? (ignoreTop ? 0 : width) : 0, |
| | | (col == columnCount - 1 && ignoreRight) ? 0 : width, |
| | | width); |
| | | |
| | | if (child is UserControl control) |
| | | { |
| | | control.BorderBrush = Brushes.Black; |
| | | control.BorderThickness = bt; |
| | | } |
| | | |
| | | if (child is Label label) |
| | | { |
| | | label.BorderBrush = Brushes.Black; |
| | | label.BorderThickness = bt; |
| | | } |
| | | |
| | | if (child is TextBox box) |
| | | { |
| | | box.BorderBrush = Brushes.Black; |
| | | box.BorderThickness = bt; |
| | | } |
| | | } |
| | | |
| | | /// 弃用 |
| | | //for (int i = 0; i < totalCount; i++) |
| | | //{ |
| | | // int row = i / columnCount; |
| | | // int col = i % columnCount; |
| | | |
| | | // if (i > grid.Children.Count - 1) { |
| | | // continue; |
| | | // } |
| | | // var cell = grid.Children[i]; |
| | | // var bt = new Thickness(col == 0 ? (ignoreLeft ? 0 : width) : 0, |
| | | // row == 0 ? (ignoreTop ? 0 : width) : 0, |
| | | // (col == columnCount - 1 && ignoreRight) ? 0 : width, |
| | | // width); |
| | | |
| | | // if (cell is UserControl child) |
| | | // { |
| | | // child.BorderBrush = Brushes.Black; |
| | | // child.BorderThickness = bt; |
| | | // } |
| | | |
| | | // if (cell is Label label) |
| | | // { |
| | | // label.BorderBrush = Brushes.Black; |
| | | // label.BorderThickness = bt; |
| | | // } |
| | | |
| | | // if (cell is TextBox box) |
| | | // { |
| | | // box.BorderBrush = Brushes.Black; |
| | | // box.BorderThickness = bt; |
| | | // } |
| | | //} |
| | | grid.Loaded -= GridInnerBorderLoaded; |
| | | } |
| | | |
| | | private static void GridSpaceOnLoaded(object sender, RoutedEventArgs e) |
| | | { |
| | | if (!(sender is Grid grid)) return; |
| | | int space = GetBorderSpace(grid); |
| | | if (space <= 0) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | var rowCount = grid.RowDefinitions.Count; |
| | | var columnCount = grid.ColumnDefinitions.Count; |
| | | int totalCount = rowCount * columnCount; |
| | | |
| | | for (int i = 0; i < totalCount; i++) |
| | | { |
| | | int row = i / columnCount; |
| | | int col = i % columnCount; |
| | | |
| | | if (i > grid.Children.Count - 1) |
| | | { |
| | | continue; |
| | | } |
| | | var cell = grid.Children[i]; |
| | | |
| | | var bt = new Thickness(col == 0 ? space : 0, row == 0 ? space : 0, space, space); |
| | | |
| | | if (cell is UserControl child) |
| | | { |
| | | child.Margin = bt; |
| | | } |
| | | } |
| | | grid.Loaded -= GridSpaceOnLoaded; |
| | | } |
| | | |
| | | private static void UniformGridOnLoad(object sender, RoutedEventArgs e) |
| | | { |
| | | if (!(sender is UniformGrid grid)) return; |
| | | //var rowCount = grid.Rows; |
| | | int columnCount = grid.Columns; |
| | | int totalCount = grid.Children.Count; |
| | | int rowCount = totalCount / columnCount; |
| | | int width = 1; |
| | | |
| | | for (int i = 0; i < grid.Children.Count; i++) |
| | | { |
| | | int row = i / columnCount; |
| | | int col = i % columnCount; |
| | | var child = grid.Children[i]; |
| | | |
| | | string baseData = GetInnerBorderIgnore(grid); |
| | | HashSet<string> data = new HashSet<string>(baseData.Split(',')); |
| | | bool ignoreTop = data.Contains("All") || data.Contains("Top"), |
| | | ignoreBottom = data.Contains("All") || data.Contains("Bottom"), |
| | | ignoreLeft = data.Contains("All") || data.Contains("Left"), |
| | | ignoreRight = data.Contains("All") || data.Contains("Right"); |
| | | |
| | | var bt = new Thickness(col == 0 ? (ignoreLeft ? 0 : width) : 0, |
| | | row == 0 ? (ignoreTop ? 0 : width) : 0, |
| | | (col == columnCount - 1 && ignoreRight) ? 0 : width, |
| | | (row == rowCount && ignoreBottom) ? 0 : width); |
| | | |
| | | if (child is UserControl control) |
| | | { |
| | | control.BorderBrush = Brushes.Black; |
| | | control.BorderThickness = bt; |
| | | } |
| | | |
| | | if (child is Label label) |
| | | { |
| | | label.BorderBrush = Brushes.Black; |
| | | label.BorderThickness = bt; |
| | | } |
| | | |
| | | if (child is TextBox box) |
| | | { |
| | | box.BorderBrush = Brushes.Black; |
| | | box.BorderThickness = bt; |
| | | } |
| | | } |
| | | grid.Loaded -= UniformGridOnLoad; |
| | | } |
| | | } |
| | | |
| | | } |
| New file |
| | |
| | | using System; |
| | | using System.Globalization; |
| | | using System.Windows.Data; |
| | | |
| | | namespace Plugin.TestResult_WPF |
| | | { |
| | | public class FontSizeConverter : IValueConverter |
| | | { |
| | | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) |
| | | { |
| | | if (parameter == null) return 15; |
| | | |
| | | string[] ps = parameter.ToString().Split(','); |
| | | int size = int.Parse(ps[0]); |
| | | int baseSize = int.Parse(ps[1]); |
| | | if (value is double width) |
| | | { |
| | | return CountFontSize(size, width, baseSize); |
| | | } |
| | | return 15; |
| | | } |
| | | |
| | | public static double CountFontSize(double size, double limit, double baseSize) |
| | | { |
| | | return size * limit / baseSize; |
| | | } |
| | | |
| | | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) |
| | | { |
| | | throw new NotImplementedException(); |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | <UserControl x:Class="Plugin.TestResult_WPF.ViewControl" |
| | | xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
| | | xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
| | | xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" |
| | | xmlns:d="http://schemas.microsoft.com/expression/blend/2008" |
| | | xmlns:local="clr-namespace:Plugin.TestResult_WPF" |
| | | mc:Ignorable="d" |
| | | Loaded="UserControl_Loaded" |
| | | d:DesignHeight="450" d:DesignWidth="800"> |
| | | <UserControl.Resources> |
| | | <local:FontSizeConverter x:Key="FontSizeConverter"/> |
| | | <Style TargetType="GroupBox"> |
| | | <Setter Property="FontSize" Value="{Binding ActualWidth,RelativeSource={RelativeSource AncestorType=UserControl}, |
| | | Converter={StaticResource FontSizeConverter}, ConverterParameter='30,1920'}" /> |
| | | </Style> |
| | | |
| | | <Style TargetType="Button"> |
| | | <Setter Property="Margin" Value="0,10"/> |
| | | <Setter Property="Padding" Value="5"/> |
| | | </Style> |
| | | |
| | | <Style TargetType="Label"> |
| | | <Setter Property="BorderThickness" Value="1"/> |
| | | <Setter Property="BorderBrush" Value="LightGray"/> |
| | | <Setter Property="Margin" Value="0,10"/> |
| | | <Setter Property="Padding" Value="5"/> |
| | | </Style> |
| | | </UserControl.Resources> |
| | | <Grid> |
| | | <Grid.ColumnDefinitions> |
| | | <ColumnDefinition Width="7.5*"/> |
| | | <ColumnDefinition Width="*"/> |
| | | </Grid.ColumnDefinitions> |
| | | <local:TestResultView x:Name="testResultView" Grid.Column="0" Loaded="testResultView_Loaded" /> |
| | | <StackPanel Grid.Column="1" Background="#FFF"> |
| | | <GroupBox Header="产品信息"> |
| | | <ComboBox x:Name="modelSelect" SelectionChanged="modelSelect_SelectionChanged"></ComboBox> |
| | | </GroupBox> |
| | | <GroupBox Header="生产统计"> |
| | | <StackPanel> |
| | | <Label HorizontalContentAlignment="Center" HorizontalAlignment="Stretch"> |
| | | <Label.Style> |
| | | <Style TargetType="Label"> |
| | | <Setter Property="HorizontalContentAlignment" Value="Center"/> |
| | | <Setter Property="HorizontalAlignment" Value="Stretch"/> |
| | | <Setter Property="Margin" Value="0,10"/> |
| | | <Style.Triggers> |
| | | <DataTrigger Binding="{Binding mesStatus}" Value="true"> |
| | | <Setter Property="Background" Value="Green"/> |
| | | <Setter Property="Content" Value="MES开"/> |
| | | <Setter Property="Foreground" Value="White"/> |
| | | </DataTrigger> |
| | | <DataTrigger Binding="{Binding mesStatus}" Value="false"> |
| | | <Setter Property="Background" Value="Red"/> |
| | | <Setter Property="Content" Value="MES关"/> |
| | | <Setter Property="Foreground" Value="White"/> |
| | | </DataTrigger> |
| | | </Style.Triggers> |
| | | </Style> |
| | | </Label.Style> |
| | | </Label> |
| | | <Label> |
| | | <Label.Style> |
| | | <Style TargetType="Label"> |
| | | <Setter Property="HorizontalContentAlignment" Value="Center"/> |
| | | <Setter Property="HorizontalAlignment" Value="Stretch"/> |
| | | <Setter Property="Content" Value="{Binding produceStatus}"/> |
| | | <Setter Property="Margin" Value="0,10"/> |
| | | <Style.Triggers> |
| | | <DataTrigger Binding="{Binding produceStatus}" Value="INIT"> |
| | | <Setter Property="Background" Value="Gray"/> |
| | | <Setter Property="Foreground" Value="White"/> |
| | | </DataTrigger> |
| | | <DataTrigger Binding="{Binding produceStatus}" Value="STOP"> |
| | | <Setter Property="Background" Value="Red"/> |
| | | <Setter Property="Foreground" Value="White"/> |
| | | </DataTrigger> |
| | | <DataTrigger Binding="{Binding produceStatus}" Value="RUNNING"> |
| | | <Setter Property="Background" Value="Green"/> |
| | | <Setter Property="Foreground" Value="White"/> |
| | | </DataTrigger> |
| | | </Style.Triggers> |
| | | </Style> |
| | | </Label.Style> |
| | | </Label> |
| | | </StackPanel> |
| | | </GroupBox> |
| | | <GroupBox Header="操作"> |
| | | <StackPanel> |
| | | <Button x:Name="btnStart" Click="Start_Click"> |
| | | <Button.Content>启动</Button.Content> |
| | | <Button.Style> |
| | | <Style TargetType="Button"> |
| | | <Setter Property="Background" Value="Green"/> |
| | | <Setter Property="Foreground" Value="White"/> |
| | | <Setter Property="Margin" Value="0,10"/> |
| | | <Setter Property="Padding" Value="5"/> |
| | | <Style.Triggers> |
| | | <Trigger Property="IsEnabled" Value="False"> |
| | | <Setter Property="Foreground" Value="Gray"/> |
| | | </Trigger> |
| | | </Style.Triggers> |
| | | </Style> |
| | | </Button.Style> |
| | | </Button> |
| | | |
| | | <Button x:Name="btnStop" Click="Stop_Click"> |
| | | <Button.Content>停止</Button.Content> |
| | | <Button.Style> |
| | | <Style TargetType="Button"> |
| | | <Setter Property="Background" Value="Red"/> |
| | | <Setter Property="Foreground" Value="White"/> |
| | | <Setter Property="Margin" Value="0,10"/> |
| | | <Setter Property="Padding" Value="5"/> |
| | | <Style.Triggers> |
| | | <Trigger Property="IsEnabled" Value="False"> |
| | | <Setter Property="Foreground" Value="Gray"/> |
| | | </Trigger> |
| | | </Style.Triggers> |
| | | </Style> |
| | | </Button.Style> |
| | | </Button> |
| | | |
| | | <Button x:Name="btnScan1" Click="Scan_Click_1"> |
| | | <Button.Content>一区扫码</Button.Content> |
| | | <Button.Style> |
| | | <Style TargetType="Button"> |
| | | <Setter Property="Margin" Value="0,10"/> |
| | | <Setter Property="Padding" Value="5"/> |
| | | <Style.Triggers> |
| | | <Trigger Property="IsEnabled" Value="False"> |
| | | <Setter Property="Foreground" Value="Gray"/> |
| | | </Trigger> |
| | | </Style.Triggers> |
| | | </Style> |
| | | </Button.Style> |
| | | </Button> |
| | | |
| | | <Button x:Name="btnScan2" Click="Scan_Click_2"> |
| | | <Button.Content>二区扫码</Button.Content> |
| | | <Button.Style> |
| | | <Style TargetType="Button"> |
| | | <Setter Property="Margin" Value="0,10"/> |
| | | <Setter Property="Padding" Value="5"/> |
| | | <Style.Triggers> |
| | | <Trigger Property="IsEnabled" Value="False"> |
| | | <Setter Property="Foreground" Value="Gray"/> |
| | | </Trigger> |
| | | </Style.Triggers> |
| | | </Style> |
| | | </Button.Style> |
| | | </Button> |
| | | <!-- <Button Content="计数清零"/> |
| | | <Button Content="扫码"/> |
| | | <Button Content="一区手动"/> |
| | | <Button Content="二区手动"/>--> |
| | | </StackPanel> |
| | | </GroupBox> |
| | | </StackPanel> |
| | | </Grid> |
| | | </UserControl> |
| New file |
| | |
| | | using NationalInstruments.TestStand.Interop.API; |
| | | using NationalInstruments.TestStand.Interop.UI.Ax; |
| | | using NationalInstruments.TestStand.Utility; |
| | | using ParameterHelper; |
| | | using Plugin.TestResult_WPF.Model; |
| | | using Plugin.TestResult_WPF.Util; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.ComponentModel; |
| | | using System.Linq; |
| | | using System.Runtime.CompilerServices; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | using System.Windows; |
| | | using System.Windows.Controls; |
| | | using System.Windows.Data; |
| | | using System.Windows.Documents; |
| | | using System.Windows.Input; |
| | | using System.Windows.Markup; |
| | | using System.Windows.Media; |
| | | using System.Windows.Media.Imaging; |
| | | using System.Windows.Navigation; |
| | | using System.Windows.Shapes; |
| | | |
| | | namespace Plugin.TestResult_WPF |
| | | { |
| | | /// <summary> |
| | | /// ViewControl.xaml 的交互逻辑 |
| | | /// </summary> |
| | | public partial class ViewControl : UserControl, INotifyPropertyChanged |
| | | { |
| | | public event PropertyChangedEventHandler PropertyChanged; |
| | | public void RaisePropertyChanged(string name) |
| | | { |
| | | PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); |
| | | } |
| | | public void RaiseAndSetIfChanged<T>(ref T old, T @new, [CallerMemberName] string propertyName = null) |
| | | { |
| | | old = @new; |
| | | if (propertyName != null) |
| | | { |
| | | RaisePropertyChanged(propertyName); |
| | | } |
| | | } |
| | | |
| | | private ParameterManager parameterManager; |
| | | private CommonCodeParser codeParser = new CommonCodeParser(); |
| | | private double TestTemperature = 60; |
| | | private int TestTime = 3600; |
| | | private double SaftyTemperature = 40; |
| | | private double TestVoltage = 12; |
| | | private double Time_Heating_Low = 300; |
| | | private double Time_Heating_High = 2400; |
| | | private string testSeqFile; |
| | | private Scanner scannerWindow1; |
| | | private Scanner scannerWindow2; |
| | | /// <summary> |
| | | /// 测试序列操作句柄 |
| | | /// </summary> |
| | | private SequenceContext SequenceContext = null; |
| | | |
| | | |
| | | private bool _mesStatus; |
| | | |
| | | public bool mesStatus |
| | | { |
| | | get => _mesStatus; |
| | | set => RaiseAndSetIfChanged(ref _mesStatus, value); |
| | | } |
| | | |
| | | private string _produceStatus = "INIT"; |
| | | |
| | | public string produceStatus |
| | | { |
| | | get => _produceStatus; |
| | | set => RaiseAndSetIfChanged(ref _produceStatus, value); |
| | | } |
| | | |
| | | |
| | | |
| | | public ViewControl() |
| | | { |
| | | DataContext = this; |
| | | InitializeComponent(); |
| | | testResultView.testApp.ExitApplication += new EventHandler(this.axApplicationMgr_ExitApplication); |
| | | testResultView.testApp.UIMessageEvent += new _ApplicationMgrEvents_UIMessageEventEventHandler(this.axApplicationMgr_UIMessageEvent); |
| | | testResultView.testApp.ExecutionClosed += new _ApplicationMgrEvents_ExecutionClosedEventHandler(this.axApplicationMgr_ExecutionClosed); |
| | | } |
| | | |
| | | private void axApplicationMgr_ExitApplication(object sender, EventArgs e) |
| | | { |
| | | } |
| | | |
| | | private void axApplicationMgr_ExecutionClosed(object sender, _ApplicationMgrEvents_ExecutionClosedEvent e) |
| | | { |
| | | |
| | | } |
| | | |
| | | private void axApplicationMgr_UIMessageEvent(object sender, _ApplicationMgrEvents_UIMessageEventEvent e) |
| | | { |
| | | try |
| | | { |
| | | int EventCase = Convert.ToInt32(e.uiMsg.Event); |
| | | int MethodCode = Convert.ToInt16(e.uiMsg.NumericData); |
| | | string strData; |
| | | |
| | | if (EventCase != 10014) return; |
| | | |
| | | if (MethodCode == 0) |
| | | { |
| | | /// 设置句柄 |
| | | this.SequenceContext = (SequenceContext)e.uiMsg.ActiveXData; |
| | | return; |
| | | } |
| | | |
| | | |
| | | if (MethodCode == 8) |
| | | { |
| | | /// 更新MES状态 |
| | | strData = e.uiMsg.StringData; |
| | | mesStatus = strData == "1"; |
| | | return; |
| | | } |
| | | |
| | | if (MethodCode == 9) |
| | | { |
| | | /// 更新生产状态 |
| | | strData = e.uiMsg.StringData; |
| | | produceStatus = strData; |
| | | return; |
| | | } |
| | | } |
| | | catch |
| | | { } |
| | | } |
| | | |
| | | private void UserControl_Loaded(object sender, RoutedEventArgs e) |
| | | { |
| | | LoadProduct(); |
| | | testResultView.InitTestStandEngine(); |
| | | Start_Click(null, null); |
| | | } |
| | | |
| | | public void LoadProduct() |
| | | { |
| | | ProductManager prdManager = new ProductManager(); |
| | | prdManager.LoadProducts(); |
| | | this.modelSelect.Items.Clear(); |
| | | foreach (Product prd in prdManager.Products) |
| | | { |
| | | this.modelSelect.Items.Add(prd.Name); |
| | | } |
| | | if (prdManager.Products.Count > 0) |
| | | { |
| | | this.modelSelect.SelectedIndex = 0; |
| | | } |
| | | } |
| | | |
| | | private void modelSelect_SelectionChanged(object sender, SelectionChangedEventArgs e) |
| | | { |
| | | try |
| | | { |
| | | string ParaFile = @".\Config\ProductionSetting\Parameter\Parameter_" + this.modelSelect.SelectedItem + ".setting"; |
| | | |
| | | this.parameterManager = new ParameterManager(ParaFile); |
| | | this.parameterManager.LoadParameters(); |
| | | //MessageBox.Show("ParaFile:" + ParaFile + "ParaCount:" + this.parameterManager.Parameters.Count.ToString()); |
| | | //this.TestTemperature = Convert.ToDouble(this.parameterManager.Find("TestTemperature").ParmValue); |
| | | //this.TestTime = Convert.ToInt32(this.parameterManager.Find("TestTime").ParmValue); |
| | | //this.TestVoltage = Convert.ToDouble(this.parameterManager.Find("TestVoltage").ParmValue); |
| | | //this.SaftyTemperature = Convert.ToDouble(this.parameterManager.Find("SaftyTemperature").ParmValue); |
| | | //this.Time_Heating_Low = Convert.ToDouble(this.parameterManager.Find("Time_Heat_Low").ParmValue); |
| | | //this.Time_Heating_High = Convert.ToDouble(this.parameterManager.Find("Time_Heat_High").ParmValue); |
| | | testResultView.testSeqFile = this.parameterManager.Find("TestSequence").ParmValue.ToString(); // @"D:\BurnIn\TestDemo.seq" |
| | | |
| | | |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | MessageBox.Show("切换产品型号失败!" + ex.Message + ex.StackTrace); |
| | | } |
| | | } |
| | | |
| | | private void Start_Click(object sender, RoutedEventArgs e) |
| | | { |
| | | try |
| | | { |
| | | testResultView.StartTestSequence(); |
| | | |
| | | this.modelSelect.IsEnabled = false; |
| | | this.btnStart.IsEnabled = false; |
| | | this.btnStop.IsEnabled = true; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | MessageBox.Show("启动测试失败!" + ex.Message); |
| | | } |
| | | } |
| | | |
| | | private void Stop_Click(object sender, RoutedEventArgs e) |
| | | { |
| | | try |
| | | { |
| | | testResultView.StopTest(); |
| | | this.modelSelect.IsEnabled = true; |
| | | this.btnStart.IsEnabled = true; |
| | | this.btnStop.IsEnabled = false; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | MessageBox.Show("停止测试失败!" + ex.Message); |
| | | } |
| | | } |
| | | |
| | | private void Scan_Click_1(object sender, RoutedEventArgs e) |
| | | { |
| | | if (scannerWindow1 == null) |
| | | { |
| | | scannerWindow1 = new Scanner("一区扫码"); |
| | | scannerWindow1.FinishBarcode += ScannerWindow_FinishBarcode; |
| | | scannerWindow1.Owner = Window.GetWindow(this); |
| | | scannerWindow1.Closed += ScannerWindow1_Closed; |
| | | scannerWindow1.Show(); |
| | | } |
| | | else |
| | | { |
| | | scannerWindow1.Activate(); |
| | | } |
| | | } |
| | | |
| | | private void Scan_Click_2(object sender, RoutedEventArgs e) |
| | | { |
| | | if (scannerWindow2 == null) |
| | | { |
| | | scannerWindow2 = new Scanner("二区扫码"); |
| | | scannerWindow2.FinishBarcode += ScannerWindow_FinishBarcode; |
| | | scannerWindow2.Owner = Window.GetWindow(this); |
| | | scannerWindow2.Closed += ScannerWindow2_Closed; |
| | | scannerWindow2.Show(); |
| | | } |
| | | else |
| | | { |
| | | scannerWindow2.Activate(); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 扫码完成逻辑 |
| | | /// </summary> |
| | | /// <param name="sender"></param> |
| | | /// <param name="e"></param> |
| | | private void ScannerWindow_FinishBarcode(object sender, BarcodeEventArg e) |
| | | { |
| | | if (this.SequenceContext == null) return; |
| | | CellInfo cellInfo = codeParser.GetCellInfoByCode(e.positionCode); |
| | | |
| | | string paramName = e.name == "一区扫码" ? "StationState.StartScanner_A" : "StationState.StartScanner_B"; |
| | | testResultView.engine.Globals.SetValBoolean(paramName, 0, true); |
| | | string positionCode = e.positionCode, snrCode = e.snrCode; |
| | | //需要增加条码校验功能 |
| | | |
| | | //将读到的条码写入到SN中 |
| | | int dutNo = Convert.ToInt16(positionCode.Split('-')[2]) - 1; |
| | | string LookupStr = e.name == "一区扫码" ? $"StationState.SN[{dutNo}]" : $"StationState.SN[{(dutNo + 54)}]"; |
| | | //this.SequenceContext.StationGlobals.SetValString(LookupStr, 0, snrCode); |
| | | //string code = this.SequenceContext.StationGlobals.GetValString(LookupStr, 0); |
| | | |
| | | testResultView.engine.Globals.SetValString(LookupStr, 0, snrCode); |
| | | string code = testResultView.engine.Globals.GetValString(LookupStr, 0); |
| | | testResultView.nameTables[cellInfo.OvenName].GetSingleCell(cellInfo.Index).SetStatus("hadCode"); |
| | | } |
| | | |
| | | private void ScannerWindow1_Closed(object sender, EventArgs e) |
| | | { |
| | | scannerWindow1 = null; |
| | | } |
| | | |
| | | private void ScannerWindow2_Closed(object sender, EventArgs e) |
| | | { |
| | | scannerWindow2 = null; |
| | | } |
| | | |
| | | private void testResultView_Loaded(object sender, RoutedEventArgs e) |
| | | { |
| | | |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?> |
| | | <packages> |
| | | <package id="HarfBuzzSharp" version="7.3.0.3" targetFramework="net472" /> |
| | | <package id="HarfBuzzSharp.NativeAssets.Linux" version="7.3.0.3" targetFramework="net472" /> |
| | | <package id="HarfBuzzSharp.NativeAssets.macOS" version="7.3.0.3" targetFramework="net472" /> |
| | | <package id="HarfBuzzSharp.NativeAssets.Win32" version="7.3.0.3" targetFramework="net472" /> |
| | | <package id="OpenTK" version="3.3.1" targetFramework="net472" /> |
| | | <package id="OpenTK.GLWpfControl" version="3.3.0" targetFramework="net472" /> |
| | | <package id="ScottPlot" version="5.0.47" targetFramework="net472" /> |
| | | <package id="ScottPlot.WPF" version="5.0.47" targetFramework="net472" /> |
| | | <package id="SkiaSharp" version="2.88.9" targetFramework="net472" /> |
| | | <package id="SkiaSharp.HarfBuzz" version="2.88.9" targetFramework="net472" /> |
| | | <package id="SkiaSharp.NativeAssets.Linux.NoDependencies" version="2.88.9" targetFramework="net472" /> |
| | | <package id="SkiaSharp.NativeAssets.macOS" version="2.88.9" targetFramework="net472" /> |
| | | <package id="SkiaSharp.NativeAssets.Win32" version="2.88.9" targetFramework="net472" /> |
| | | <package id="SkiaSharp.Views.Desktop.Common" version="2.88.9" targetFramework="net472" /> |
| | | <package id="SkiaSharp.Views.WPF" version="2.88.9" targetFramework="net472" /> |
| | | <package id="System.Buffers" version="4.5.1" targetFramework="net472" /> |
| | | <package id="System.Drawing.Common" version="4.7.3" targetFramework="net472" /> |
| | | <package id="System.Memory" version="4.5.5" targetFramework="net472" /> |
| | | <package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net472" /> |
| | | <package id="System.Runtime.CompilerServices.Unsafe" version="4.5.3" targetFramework="net472" /> |
| | | <package id="System.Runtime.Loader" version="4.3.0" targetFramework="net472" /> |
| | | <package id="System.ValueTuple" version="4.5.0" targetFramework="net472" /> |
| | | </packages> |
| | |
| | | using System.Threading.Tasks; |
| | | using System; |
| | | using System.Threading.Tasks; |
| | | using System.Windows; |
| | | using HMI.Base; |
| | | |
| | |
| | | |
| | | private void Loader_LoadMessageAppend(object sender, string e) |
| | | { |
| | | Dispatcher.BeginInvoke(() => |
| | | this.Dispatcher.BeginInvoke((Action)delegate () |
| | | { |
| | | Console.Text = Console.Text+$"{e}\r\n"; |
| | | Console.Text = Console.Text + $"{e}\r\n"; |
| | | }); |
| | | } |
| | | |
| | |
| | | <Project>{f7663c79-7047-42f3-b129-73a2575ee7c6}</Project> |
| | | <Name>HMI.IOMonitor</Name> |
| | | </ProjectReference> |
| | | <ProjectReference Include="..\HMI.LogViewer\HMI.LogViewer.csproj"> |
| | | <Project>{20c23602-b029-4e21-8c11-b9e5f2223237}</Project> |
| | | <Name>HMI.LogViewer</Name> |
| | | </ProjectReference> |
| | | <ProjectReference Include="..\HMI.ParameterManage\HMI.ParameterManage.csproj"> |
| | | <Project>{736cd77d-b81e-4866-bb00-84b0b57110f0}</Project> |
| | | <Name>HMI.ParameterManage</Name> |
| | |
| | | <Project>{de4205c6-5923-46fd-a4b9-65169bf61c75}</Project> |
| | | <Name>HMI.MenuManage</Name> |
| | | </ProjectReference> |
| | | <ProjectReference Include="..\Plugin.TestResult\Plugin.TestResult.csproj"> |
| | | <Project>{7375b74c-b6bf-4814-9838-e1caacad1897}</Project> |
| | | <Name>Plugin.TestResult</Name> |
| | | </ProjectReference> |
| | | </ItemGroup> |
| | | <ItemGroup> |
| | | <Content Include="Icon\xinzeng_1.png"> |
| | |
| | | EndProject |
| | | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommonLibs", "..\..\HMI.Old\Framework\CommonLibs\CommonLibs\CommonLibs.csproj", "{0212E104-4E85-4F9F-AA70-FC4FAC25C3E5}" |
| | | EndProject |
| | | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HMI.LogViewer", "..\HMI.LogViewer\HMI.LogViewer.csproj", "{20C23602-B029-4E21-8C11-B9E5F2223237}" |
| | | EndProject |
| | | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Plugin.TestResult", "..\Plugin.TestResult\Plugin.TestResult.csproj", "{7375B74C-B6BF-4814-9838-E1CAACAD1897}" |
| | | EndProject |
| | | Global |
| | | GlobalSection(SolutionConfigurationPlatforms) = preSolution |
| | | Debug|Any CPU = Debug|Any CPU |
| | |
| | | {0212E104-4E85-4F9F-AA70-FC4FAC25C3E5}.Release|Any CPU.Build.0 = Release|Any CPU |
| | | {0212E104-4E85-4F9F-AA70-FC4FAC25C3E5}.Release|x64.ActiveCfg = Release|x64 |
| | | {0212E104-4E85-4F9F-AA70-FC4FAC25C3E5}.Release|x64.Build.0 = Release|x64 |
| | | {20C23602-B029-4E21-8C11-B9E5F2223237}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
| | | {20C23602-B029-4E21-8C11-B9E5F2223237}.Debug|Any CPU.Build.0 = Debug|Any CPU |
| | | {20C23602-B029-4E21-8C11-B9E5F2223237}.Debug|x64.ActiveCfg = Debug|x64 |
| | | {20C23602-B029-4E21-8C11-B9E5F2223237}.Debug|x64.Build.0 = Debug|x64 |
| | | {20C23602-B029-4E21-8C11-B9E5F2223237}.Release|Any CPU.ActiveCfg = Release|Any CPU |
| | | {20C23602-B029-4E21-8C11-B9E5F2223237}.Release|Any CPU.Build.0 = Release|Any CPU |
| | | {20C23602-B029-4E21-8C11-B9E5F2223237}.Release|x64.ActiveCfg = Release|Any CPU |
| | | {20C23602-B029-4E21-8C11-B9E5F2223237}.Release|x64.Build.0 = Release|Any CPU |
| | | {7375B74C-B6BF-4814-9838-E1CAACAD1897}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
| | | {7375B74C-B6BF-4814-9838-E1CAACAD1897}.Debug|Any CPU.Build.0 = Debug|Any CPU |
| | | {7375B74C-B6BF-4814-9838-E1CAACAD1897}.Debug|x64.ActiveCfg = Debug|x64 |
| | | {7375B74C-B6BF-4814-9838-E1CAACAD1897}.Debug|x64.Build.0 = Debug|x64 |
| | | {7375B74C-B6BF-4814-9838-E1CAACAD1897}.Release|Any CPU.ActiveCfg = Release|Any CPU |
| | | {7375B74C-B6BF-4814-9838-E1CAACAD1897}.Release|Any CPU.Build.0 = Release|Any CPU |
| | | {7375B74C-B6BF-4814-9838-E1CAACAD1897}.Release|x64.ActiveCfg = Release|x64 |
| | | {7375B74C-B6BF-4814-9838-E1CAACAD1897}.Release|x64.Build.0 = Release|x64 |
| | | EndGlobalSection |
| | | GlobalSection(SolutionProperties) = preSolution |
| | | HideSolutionNode = FALSE |