Переглянути джерело

冲突解决

样式分支
taoye 2 роки тому
джерело
коміт
a301ba945b
100 змінених файлів з 4866 додано та 1171 видалено
  1. +3
    -2
      BPASmart.MenuLoad/App.xaml.cs
  2. +2
    -2
      BPASmart.PageLoad/MainWindow.xaml
  3. +7
    -7
      BPASmart.RecipeManagement/App.xaml
  4. +1
    -0
      BPASmart.RecipeManagement/BPASmart.RecipeManagement.csproj
  5. +1
    -2
      BPASmart.RecipeManagement/View/RecipesConfigure.xaml
  6. +4
    -1
      BPASmart.RecipeManagement/ViewModel/RecipeManagerViewModel.cs
  7. BIN
     
  8. +42
    -2
      BPASmartClient.CustomResource/Pages/Model/MessageLog.cs
  9. +8
    -1
      BPASmartClient.CustomResource/Pages/View/LoginView.xaml.cs
  10. +109
    -0
      BPASmartClient.CustomResource/Pages/View/PromptView.xaml
  11. +75
    -0
      BPASmartClient.CustomResource/Pages/View/PromptView.xaml.cs
  12. +70
    -49
      BPASmartClient.CustomResource/UserControls/ConveyBelt2.xaml
  13. +201
    -120
      BPASmartClient.CustomResource/UserControls/MaterialStock.xaml
  14. +230
    -0
      BPASmartClient.CustomResource/UserControls/NumberTextBox.xaml
  15. +81
    -0
      BPASmartClient.CustomResource/UserControls/NumberTextBox.xaml.cs
  16. +7
    -0
      BPASmartClient.DosingProject/Model/GVL_SmallStation.cs
  17. +228
    -15
      BPASmartClient.DosingProject/Model/ProcessControl.cs
  18. +1
    -1
      BPASmartClient.DosingProject/Model/RawMaterial/DeviceInquire.cs
  19. +0
    -6
      BPASmartClient.DosingProject/Model/Recipes/RemoteRecipeData.cs
  20. +3
    -0
      BPASmartClient.DosingProject/Model/Recipes/RemoteRecipeRawMaterial.cs
  21. +3
    -1
      BPASmartClient.JXJFoodSmallStation/App.xaml.cs
  22. +3
    -0
      BPASmartClient.JXJFoodSmallStation/Model/GVL_SmallStation.cs
  23. +6
    -1
      BPASmartClient.JXJFoodSmallStation/Model/HK_PLC/HKDeviceStatus.cs
  24. +75
    -35
      BPASmartClient.JXJFoodSmallStation/Model/ProcessControl.cs
  25. +2
    -2
      BPASmartClient.JXJFoodSmallStation/Model/RawMaterial/DeviceCurrentStatus.cs
  26. +17
    -6
      BPASmartClient.JXJFoodSmallStation/Model/RawMaterial/DeviceInquire.cs
  27. +34
    -6
      BPASmartClient.JXJFoodSmallStation/View/HardwareStatusView.xaml
  28. +8
    -1
      BPASmartClient.JXJFoodSmallStation/ViewModel/RecipeReceiveViewModel.cs
  29. +4
    -0
      BPASmartClient.JXJFoodSmallStation/ViewModel/SiemensRecipeReceiveViewModel.cs
  30. +12
    -4
      BPASmartClient.MilkWithTea/App.xaml
  31. +19
    -8
      BPASmartClient.MilkWithTea/App.xaml.cs
  32. +6
    -1
      BPASmartClient.MilkWithTea/BPASmartClient.MilkWithTea.csproj
  33. +30
    -0
      BPASmartClient.MilkWithTea/Control/ContextMenuToggleButton.cs
  34. +225
    -0
      BPASmartClient.MilkWithTea/Control/ScrollViewer.cs
  35. +111
    -0
      BPASmartClient.MilkWithTea/Control/ScrollViewerAttach.cs
  36. +426
    -0
      BPASmartClient.MilkWithTea/Control/TabControl.cs
  37. +509
    -0
      BPASmartClient.MilkWithTea/Control/TabItem.cs
  38. +200
    -0
      BPASmartClient.MilkWithTea/Control/TabPanel.cs
  39. +12
    -0
      BPASmartClient.MilkWithTea/Data/CancelRoutedEventArgs.cs
  40. +69
    -0
      BPASmartClient.MilkWithTea/Data/ValueBoxes.cs
  41. +5
    -36
      BPASmartClient.MilkWithTea/GLobal.cs
  42. +49
    -2
      BPASmartClient.MilkWithTea/MainWindow.xaml.cs
  43. +13
    -0
      BPASmartClient.MilkWithTea/Model/JsonDeviceConfig.cs
  44. +23
    -0
      BPASmartClient.MilkWithTea/Model/JsonLocalRecipes.cs
  45. +93
    -154
      BPASmartClient.MilkWithTea/View/LocalConfigureView.xaml
  46. +8
    -1
      BPASmartClient.MilkWithTea/View/LocalConfigureView.xaml.cs
  47. +4
    -4
      BPASmartClient.MilkWithTea/View/MainControlView.xaml
  48. +2
    -3
      BPASmartClient.MilkWithTea/View/MainControlView.xaml.cs
  49. +23
    -14
      BPASmartClient.MilkWithTea/View/ParameterSetting.xaml
  50. +135
    -0
      BPASmartClient.MilkWithTea/View/RecipeConfige.xaml
  51. +174
    -0
      BPASmartClient.MilkWithTea/View/RecipeConfige.xaml.cs
  52. +30
    -169
      BPASmartClient.MilkWithTea/ViewModel/LocalConfigureViewModel.cs
  53. +37
    -28
      BPASmartClient.MilkWithTea/ViewModel/MainControlViewModel.cs
  54. +16
    -17
      BPASmartClient.MilkWithTea/ViewModel/MainWindowVeiwModel.cs
  55. +105
    -86
      BPASmartClient.MilkWithTea/ViewModel/PatrameterSettiongViewModel.cs
  56. +75
    -0
      BPASmartClient.MilkWithTea/ViewModel/RecipeConfigeViewModel.cs
  57. +54
    -13
      BPASmartClient.Modbus/ModbusTcp.cs
  58. +4
    -0
      BPASmartClient.Model/BPASmartClient.Model.csproj
  59. +9
    -0
      BPASmartClient.Model/柔性味魔方/RawMaterialModel.cs
  60. +78
    -165
      BPASmartClient.MorkF/Control_MorkF.cs
  61. +38
    -0
      BPASmartClient.MorkF/GVL_MorkF.cs
  62. +38
    -18
      BPASmartClient.MorkF/View/DebugView.xaml
  63. +83
    -42
      BPASmartClient.MorkF/ViewModel/DebugViewModel.cs
  64. +6
    -1
      BPASmartClient.MorkMOC/BPASmartClient.MorkMOC.csproj
  65. +23
    -4
      BPASmartClient.MorkMOC/Control_MorkMOC.cs
  66. +55
    -0
      BPASmartClient.MorkMOC/Model/LocalMaterail.cs
  67. +3
    -0
      BPASmartClient.MorkMOC/OrderLocInfo.cs
  68. +2
    -0
      BPASmartClient.MorkS/Control_Morks.cs
  69. +1
    -0
      BPASmartClient.MorkS/GVL_MORKS.cs
  70. +4
    -0
      BPASmartClient.MorkTM/Model/LocalTeaWithMilkConfig.cs
  71. +10
    -2
      BPASmartClient.S7Net/SiemensHelper.cs
  72. +8
    -0
      BPASmartClient.SCADAControl/BPASmartClient.SCADAControl.csproj
  73. +37
    -0
      BPASmartClient.SCADAControl/CustomerControls/FYFTheListBox.xaml
  74. +391
    -0
      BPASmartClient.SCADAControl/CustomerControls/FYFTheListBox.xaml.cs
  75. +11
    -1
      BPASmartClient.SCADAControl/CustomerControls/TheCheckBox.xaml.cs
  76. +1
    -1
      BPASmartClient.SCADAControl/CustomerControls/TheImage.xaml
  77. +6
    -7
      BPASmartClient.SCADAControl/CustomerControls/TheImage.xaml.cs
  78. +10
    -0
      BPASmartClient.SCADAControl/CustomerControls/TheRadioButton.cs
  79. +1
    -1
      BPASmartClient.SCADAControl/CustomerControls/TheTabControl.xaml.cs
  80. BIN
     
  81. BIN
     
  82. BIN
     
  83. +15
    -36
      BPASmartClient.SCADAControl/Themes/Generic.xaml
  84. BIN
     
  85. +3
    -0
      BPASmartClient.SmallBatchingSystem/Models/BaseModel.cs
  86. +27
    -4
      BPASmartClient.SmallBatchingSystem/ViewModels/NewOutletViewModel.cs
  87. +15
    -1
      BPASmartClient.SmallBatchingSystem/ViewModels/NewRecipeViewModel.cs
  88. +28
    -17
      BPASmartClient.SmallBatchingSystem/ViewModels/NewSiloViewModel.cs
  89. +8
    -0
      BPASmartClient.SmallBatchingSystem/Views/NewOutletView.xaml
  90. +9
    -1
      BPASmartClient.SmallBatchingSystem/Views/NewRecipeView.xaml
  91. +22
    -0
      BPASmartClient.SmallBatchingSystem/Views/PromptView.xaml
  92. +27
    -0
      BPASmartClient.SmallBatchingSystem/Views/PromptView.xaml.cs
  93. +10
    -6
      BeDesignerSCADA/BeDesignerSCADA.csproj
  94. +15
    -8
      BeDesignerSCADA/Controls/CanvasPanelNew.xaml
  95. +39
    -1
      BeDesignerSCADA/Controls/CanvasPanelNew.xaml.cs
  96. +1
    -1
      BeDesignerSCADA/Controls/MainCanvasPanel.xaml
  97. +136
    -52
      BeDesignerSCADA/Helper/SystemHelper.cs
  98. BIN
     
  99. +1
    -1
      BeDesignerSCADA/View/ChildEditWindow.xaml
  100. +1
    -1
      BeDesignerSCADA/View/RunWindows.xaml

+ 3
- 2
BPASmart.MenuLoad/App.xaml.cs Переглянути файл

@@ -47,8 +47,9 @@ namespace BPASmart.MenuLoad
this.Dispatcher.Invoke(() => {
if (File.Exists(_path))
{
SystemHelperNew.GetInstance.CreateDesktopShortcut("BeDesignerSCADA.exe");
SystemHelperNew.GetInstance.CreateDesktopShortcut();
SystemHelperNew.GetInstance.CreateShortcutOnDesktop();
SystemHelperNew.GetInstance.CreateShortcutOnDesktop("可视化配置工具");
//SystemHelperNew.GetInstance.CreateDesktopShortcut();
run.LoadingData(_path);
run.Show();
isShow = true;


+ 2
- 2
BPASmart.PageLoad/MainWindow.xaml Переглянути файл

@@ -2,7 +2,7 @@
x:Class="BPASmart.PageLoad.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ctrl="clr-namespace:BeDesignerSCADA.Controls;assembly=BeDesignerSCADA"
xmlns:ctrl="clr-namespace:BeDesignerSCADA.Controls;assembly=可视化配置工具"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:BPASmart.PageLoad"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
@@ -13,7 +13,7 @@
mc:Ignorable="d">
<Grid>
<Grid.Background>
<ImageBrush ImageSource="/BeDesignerSCADA;component/Images/bj.png" />
<ImageBrush ImageSource="/可视化配置工具;component/Images/bj.png" />
</Grid.Background>
<ctrl:RunCanvas x:Name="runCanvas" />
</Grid>


+ 7
- 7
BPASmart.RecipeManagement/App.xaml Переглянути файл

@@ -87,7 +87,7 @@
</ControlTemplate>


<Style TargetType="{x:Type ComboBox}">
<Style TargetType="{x:Type ComboBox}">
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Background" Value=" #041039"/>
<Setter Property="BorderBrush" Value="#FF2AB2E7"/>
@@ -101,13 +101,12 @@
<ControlTemplate TargetType="{x:Type ComboBoxItem}">
<Grid Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" >
<Border x:Name="_borderbg" Background=" #041039" BorderBrush="#FF2AB2E7" BorderThickness="0"/>
<TextBlock
<ContentPresenter
x:Name="_txt"
Margin="5,0,3,0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Foreground="#FF2AB2E7"
Text="{Binding Content, RelativeSource={RelativeSource TemplatedParent}}" />
/>

<Border
x:Name="_border"
@@ -123,7 +122,7 @@
<Setter TargetName="_borderbg" Property="Background" Value="#37405E" />
<Setter TargetName="_borderbg" Property="BorderBrush" Value="white" />
<Setter TargetName="_borderbg" Property="BorderThickness" Value="1" />
<Setter TargetName="_txt" Property="Foreground" Value="white" />
<!--<Setter TargetName="_txt" Property="Foreground" Value="white" />-->
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
@@ -132,7 +131,7 @@
<Setter TargetName="_borderbg" Property="Background" Value="#022352" />
<Setter TargetName="_borderbg" Property="BorderBrush" Value=" #00BFFF" />
<Setter TargetName="_borderbg" Property="BorderThickness" Value="1" />
<Setter TargetName="_txt" Property="Foreground" Value="white" />
<!--<Setter TargetName="_txt" Property="Foreground" Value="white" />-->
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
@@ -221,7 +220,8 @@
<StackPanel
Background="{TemplateBinding Background}"
IsItemsHost="True"
KeyboardNavigation.DirectionalNavigation="Contained"/>
KeyboardNavigation.DirectionalNavigation="Contained">
</StackPanel>
</ScrollViewer>
</Grid>
</Popup>


+ 1
- 0
BPASmart.RecipeManagement/BPASmart.RecipeManagement.csproj Переглянути файл

@@ -49,6 +49,7 @@

<ItemGroup>
<ProjectReference Include="..\BPASmart.Model\BPASmart.Model.csproj" />
<ProjectReference Include="..\BPASmartClient.CustomResource\BPASmartClient.CustomResource.csproj" />
<ProjectReference Include="..\BPASmartClient.Model\BPASmartClient.Model.csproj" />
</ItemGroup>



+ 1
- 2
BPASmart.RecipeManagement/View/RecipesConfigure.xaml Переглянути файл

@@ -66,7 +66,7 @@
<ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions>

<ComboBox
<ComboBox
Name="cb"
Grid.Column="0"
Margin="3,1"
@@ -77,7 +77,6 @@
FontFamily="楷体"
FontSize="20"
IsEditable="False"
SelectedValuePath="Key" DisplayMemberPath="Value"
ItemsSource="{Binding DataContext.materialsName, RelativeSource={RelativeSource AncestorType=ItemsControl, Mode=FindAncestor}}"
SelectedValue="{Binding ID}"


+ 4
- 1
BPASmart.RecipeManagement/ViewModel/RecipeManagerViewModel.cs Переглянути файл

@@ -1,5 +1,7 @@
using BPASmart.Model;
using BPASmart.RecipeManagement.View;
using BPASmartClient.CustomResource.UserControls;
using BPASmartClient.CustomResource.UserControls.MessageShow;
using BPASmartClient.Helper;
using BPASmartClient.RecipeManagement.View;
using Microsoft.Toolkit.Mvvm.ComponentModel;
@@ -10,6 +12,7 @@ using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

namespace BPASmart.RecipeManagement.ViewModel
{
@@ -81,7 +84,7 @@ namespace BPASmart.RecipeManagement.ViewModel
if (res != null)
{
//下发配方
NoticeDemoViewModel.OpenMsg(EnumPromptType.Success, Application.Current.MainWindow, "提示", $"配方下发成功!");
}
}
}



+ 42
- 2
BPASmartClient.CustomResource/Pages/Model/MessageLog.cs Переглянути файл

@@ -8,6 +8,7 @@ using System.Threading.Tasks;
using System.Windows;
using BPASmartClient.Model;
using System.Windows.Media;
using BPASmartClient.CustomResource.Pages.View;

namespace BPASmartClient.CustomResource.Pages.Model
{
@@ -44,7 +45,7 @@ namespace BPASmartClient.CustomResource.Pages.Model
{
lock (userlock)
{
if (!string.IsNullOrEmpty(Global.userInfo.UserName) && !string.IsNullOrEmpty(Global.userInfo.permission.ToString())&& !string.IsNullOrEmpty(info))
if (!string.IsNullOrEmpty(Global.userInfo.UserName) && !string.IsNullOrEmpty(Global.userInfo.permission.ToString()) && !string.IsNullOrEmpty(info))
{
UserLog userLog = new UserLog()
{
@@ -76,7 +77,7 @@ namespace BPASmartClient.CustomResource.Pages.Model
RunLog?.Invoke(info);
}
}
int AlarmID;
public void ShowAlarmLog(string info, string AlarmNumber = "_", AlarmLevel level = AlarmLevel.一般报警)
{
@@ -97,5 +98,44 @@ namespace BPASmartClient.CustomResource.Pages.Model
AlarmLog?.Invoke(info);
}
}

public bool ShowDialog(string info, DialogType dialogType = DialogType.Information)
{
PromptView PV = new PromptView();
PV.TextBlockInfo = info;
switch (dialogType)
{
case DialogType.Warning:
PV.TextBlockIcon = "&#xe61f;";
PV.TextBlockForeground = Brushes.Yellow;
PV.infoType.Text = "警告:";
//PV.Cancel.Visibility = Visibility.Collapsed;
break;
case DialogType.Error:
PV.TextBlockIcon = "&#xed1a;";
PV.TextBlockForeground = Brushes.Red;
PV.infoType.Text = "错误:";
//PV.Cancel.Visibility = Visibility.Collapsed;
break;
case DialogType.Information:
PV.TextBlockIcon = "&#xe657;";
PV.TextBlockForeground = Brushes.DeepSkyBlue;
PV.infoType.Text = "提示:";
//PV.Cancel.Visibility = Visibility.Visible;
break;
default:
break;
}
PV.infoType.Foreground = PV.TextBlockForeground;
var res = PV.ShowDialog();
return res == null ? false : (bool)res;
}
}

public enum DialogType
{
Warning,
Error,
Information,
}
}

+ 8
- 1
BPASmartClient.CustomResource/Pages/View/LoginView.xaml.cs Переглянути файл

@@ -28,7 +28,7 @@ namespace BPASmartClient.CustomResource.Pages.View
{
InitializeComponent();
//grid.Visibility = Visibility.Collapsed;
Username.Focus();
//Username.Focus();
Username.SelectionStart = Username.Text.Trim().Length;
this.Loaded += LoginView_Loaded;
ActionManage.GetInstance.Register(new Action(() =>
@@ -55,6 +55,13 @@ namespace BPASmartClient.CustomResource.Pages.View
//player.Unloaded += new RoutedEventHandler(media_Unloaded);// 添加元素卸载完成事件 -- 停止播放
//player.MediaOpened += Player_MediaOpened;//已播放事件
}
Task.Factory.StartNew(() =>
{
Thread.Sleep(100);
Application.Current.Dispatcher.Invoke(() => { Username.Focus(); });
//grid.Visibility = Visibility.Visible;
});

}

private void Player_MediaOpened(object sender, RoutedEventArgs e)


+ 109
- 0
BPASmartClient.CustomResource/Pages/View/PromptView.xaml Переглянути файл

@@ -0,0 +1,109 @@
<Window
x:Class="BPASmartClient.CustomResource.Pages.View.PromptView"
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:local="clr-namespace:BPASmartClient.CustomResource.Pages.View"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="PromptView"
Width="400"
Height="200"
AllowsTransparency="True"
Background="{x:Null}"
WindowStartupLocation="CenterScreen"
WindowStyle="None"
mc:Ignorable="d">

<Window.Resources>
<Style x:Key="buttonStyle" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Border
BorderBrush="DeepSkyBlue"
BorderThickness="2"
CornerRadius="8" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>

<Grid Name="main">
<Grid.Background>
<ImageBrush ImageSource="/BPASmartClient.CustomResource;component/Image/弹窗.png" Stretch="Fill" />
</Grid.Background>

<Grid Margin="18,16">
<Button
Width="30"
Height="20"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Background="Transparent"
BorderThickness="0"
Click="Button_Click" />

<Grid Margin="0,40,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.2*" />
<ColumnDefinition Width="0.15*" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock
Name="infoType"
Grid.Column="1"
VerticalAlignment="Top"
FontSize="16"
Foreground="DeepSkyBlue" />
<TextBlock
Name="icon"
HorizontalAlignment="Center"
VerticalAlignment="Top"
FontFamily="../../Fonts/#iconfont"
FontSize="30"
Foreground="DeepSkyBlue"
Text="&#xe61f;" />
<TextBlock
Name="info"
Grid.Column="2"
Margin="10,0,0,0"
VerticalAlignment="Top"
Foreground="DeepSkyBlue"
Text="警告:"
TextWrapping="Wrap" />
</Grid>

<StackPanel
Grid.Row="1"
Margin="0,0,10,0"
HorizontalAlignment="Right"
Orientation="Horizontal">
<Button
Name="Cancel"
Width="90"
Height="30"
Margin="5,0,5,0"
Click="Cancel_Click"
Content="取消"
FontSize="20"
Style="{StaticResource ImageButtonStyle}" />

<Button
Name="ok"
Width="90"
Height="30"
Margin="5,0,5,0"
Click="ok_Click"
Content="确定"
FontSize="20"
Style="{StaticResource ImageButtonStyle}" />
</StackPanel>

<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="0.5*" />
</Grid.RowDefinitions>
</Grid>
</Grid>
</Window>

+ 75
- 0
BPASmartClient.CustomResource/Pages/View/PromptView.xaml.cs Переглянути файл

@@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
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 BPASmartClient.CustomResource.Pages.View
{
/// <summary>
/// PromptView.xaml 的交互逻辑
/// </summary>
public partial class PromptView : Window
{
public PromptView()
{
InitializeComponent();
this.main.MouseLeftButtonDown += (o, e) => { if (e.LeftButton == MouseButtonState.Pressed) this.DragMove(); };
}

public string TextBlockIcon
{
get { return this.icon.Text.Trim(); }
set { this.icon.Text = Regex.Unescape(StringToUnicode(value.ToString())); }
}

public Brush TextBlockForeground
{
get { return this.icon.Foreground; }
set { this.icon.Foreground = value; this.info.Foreground = value; }
}

public string TextBlockInfo
{
get { return this.info.Text.Trim(); }
set { this.info.Text = value; }
}

private string StringToUnicode(string s)
{
if (!string.IsNullOrEmpty(s))
{
//这里把格式&#xe625; 转为 \ue625
return s.Replace(@"&#x", @"\u").Replace(";", "");
}
return s;
}

private void Button_Click(object sender, RoutedEventArgs e)
{
this.DialogResult = false;
this.Close();
}

private void Cancel_Click(object sender, RoutedEventArgs e)
{
this.DialogResult = false;
this.Close();
}

private void ok_Click(object sender, RoutedEventArgs e)
{
this.DialogResult = true;
this.Close();
}
}
}

+ 70
- 49
BPASmartClient.CustomResource/UserControls/ConveyBelt2.xaml Переглянути файл

@@ -1,16 +1,73 @@
<UserControl x:Class="BPASmartClient.CustomResource.UserControls.ConveyBelt2"
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:BPASmartClient.CustomResource.UserControls"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Border x:Name="br" >
<UserControl
x:Class="BPASmartClient.CustomResource.UserControls.ConveyBelt2"
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:local="clr-namespace:BPASmartClient.CustomResource.UserControls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
d:DesignHeight="450"
d:DesignWidth="800"
mc:Ignorable="d">
<Border x:Name="br">
<Viewbox HorizontalAlignment="Center" VerticalAlignment="Center">

<Canvas
Width="{Binding ElementName=br, Path=ActualWidth}"
Height="{Binding ElementName=br, Path=ActualHeight}"
Margin="5">

<Rectangle
Canvas.Top="20"
Width="{Binding ElementName=br, Path=ActualWidth}"
Height="5"
HorizontalAlignment="Center"
RadiusX="1"
RadiusY="1">
<Rectangle.Fill>
<LinearGradientBrush>
<GradientStop Offset="0" Color="LightGray" />
<GradientStop Offset="0.5" Color="White" />
<GradientStop Offset="1" Color="LightGray" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle
x:Name="recDown"
Width="{Binding ElementName=br, Path=ActualWidth}"
Height="5"
Margin="0,80,0,0"
HorizontalAlignment="Center"
RadiusX="1"
RadiusY="1">
<Rectangle.Fill>
<LinearGradientBrush>
<GradientStop Offset="0" Color="LightGray" />
<GradientStop Offset="0.5" Color="White" />
<GradientStop Offset="1" Color="LightGray" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Path
x:Name="belt"
Canvas.Left="10"
Canvas.Top="20"
StrokeDashArray="2"
StrokeThickness="20">
<Path.Stroke>
<LinearGradientBrush>
<GradientStop Offset="0" Color="SlateGray" />
<GradientStop Offset="0.5" Color="White" />
<GradientStop Offset="1" Color="SlateGray" />
</LinearGradientBrush>
</Path.Stroke>
</Path>

</Canvas>
</Viewbox>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="StockGroup">
<VisualState Name="RunState">
<Storyboard RepeatBehavior="Forever">
<Storyboard RepeatBehavior="Forever">
<DoubleAnimation
Storyboard.TargetName="belt"
Storyboard.TargetProperty="StrokeDashOffset"
@@ -19,12 +76,11 @@
Duration="0:0:20" />
</Storyboard>
</VisualState>
<VisualState Name="Stop">
</VisualState>
<VisualState Name="Stop" />
</VisualStateGroup>
<VisualStateGroup Name="DirectionGroup">
<VisualState Name="LeftState">
<Storyboard RepeatBehavior="Forever">
<Storyboard RepeatBehavior="Forever">
<DoubleAnimation
Storyboard.TargetName="belt"
Storyboard.TargetProperty="StrokeDashOffset"
@@ -34,7 +90,7 @@
</Storyboard>
</VisualState>
<VisualState Name="RightState">
<Storyboard RepeatBehavior="Forever">
<Storyboard RepeatBehavior="Forever">
<DoubleAnimation
Storyboard.TargetName="belt"
Storyboard.TargetProperty="StrokeDashOffset"
@@ -45,40 +101,5 @@
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Viewbox HorizontalAlignment="Center" VerticalAlignment="Center">

<Canvas Width="{Binding ElementName=br, Path=ActualWidth}" Height="{Binding ElementName=br, Path=ActualHeight}" Margin="5">

<Rectangle HorizontalAlignment="Center" Width="{Binding ElementName=br, Path=ActualWidth}" Height="5" Canvas.Top="20" RadiusX="1" RadiusY="1">
<Rectangle.Fill>
<LinearGradientBrush >
<GradientStop Color="LightGray" Offset="0"/>
<GradientStop Color="White" Offset="0.5"/>
<GradientStop Color="LightGray" Offset="1"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle HorizontalAlignment="Center" x:Name="recDown" Width="{Binding ElementName=br, Path=ActualWidth}" Height="5" RadiusX="1" RadiusY="1" Margin="0,80,0,0">
<Rectangle.Fill>
<LinearGradientBrush >
<GradientStop Color="LightGray" Offset="0"/>
<GradientStop Color="White" Offset="0.5"/>
<GradientStop Color="LightGray" Offset="1"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Path x:Name="belt" Canvas.Top="20" Canvas.Left="10"
StrokeDashArray="2" StrokeThickness="20">
<Path.Stroke>
<LinearGradientBrush>
<GradientStop Color="SlateGray" Offset="0"/>
<GradientStop Color="White" Offset="0.5"/>
<GradientStop Color="SlateGray" Offset="1"/>
</LinearGradientBrush>
</Path.Stroke>
</Path>
</Canvas>
</Viewbox>
</Border>
</UserControl>

+ 201
- 120
BPASmartClient.CustomResource/UserControls/MaterialStock.xaml Переглянути файл

@@ -1,80 +1,25 @@
<UserControl x:Class="BPASmartClient.CustomResource.UserControls.MaterialStock"
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:BPASmartClient.CustomResource.UserControls"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl
x:Class="BPASmartClient.CustomResource.UserControls.MaterialStock"
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:local="clr-namespace:BPASmartClient.CustomResource.UserControls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
d:DesignHeight="450"
d:DesignWidth="800"
mc:Ignorable="d">
<UserControl.Resources>
<PathGeometry x:Key="move" Figures="M 0,0 L 0,10"/>
<PathGeometry x:Key="move" Figures="M 0,0 L 0,10" />
</UserControl.Resources>
<Border HorizontalAlignment="Center">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="StockGroup">
<VisualState Name="OpenState">
<Storyboard>
<DoubleAnimation Duration="00:0:1" From="0" To="200"
Storyboard.TargetProperty="Width"
Storyboard.TargetName="stock"/>
<DoubleAnimation Duration="00:0:1" From="0" To="70"
Storyboard.TargetProperty="Height"
Storyboard.TargetName="stock"/>
</Storyboard>
</VisualState>
<VisualState Name="CloseState">
<Storyboard>
<DoubleAnimation Duration="00:0:1" From="200" To="0"
Storyboard.TargetProperty="Width"
Storyboard.TargetName="stock"/>
<DoubleAnimation Duration="00:0:1" From="70" To="0"
Storyboard.TargetProperty="Height"
Storyboard.TargetName="stock"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup Name="RunStateGroup">
<VisualState Name="RunState">
<Storyboard>
<ColorAnimationUsingKeyFrames
Storyboard.TargetName="gsGreen"
Storyboard.TargetProperty="Color">
<DiscreteColorKeyFrame Value="Green" KeyTime="0"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState Name="Stop"/>
</VisualStateGroup>
<VisualStateGroup x:Name="FaultStateGroup">
<VisualState Name="FaultState">
<Storyboard>
<ColorAnimationUsingKeyFrames RepeatBehavior="Forever"
Storyboard.TargetName="gsRed1"
Storyboard.TargetProperty="Color">
<DiscreteColorKeyFrame Value="Red" KeyTime="0:0:0.5"/>
<DiscreteColorKeyFrame Value="Gray" KeyTime="0:0:1"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState Name="NormalState"/>
</VisualStateGroup>
<VisualStateGroup x:Name="LayOffStateGroup">
<VisualState Name="LayOffState">
<Storyboard>
<DoubleAnimationUsingPath Duration="0:0:1" PathGeometry="{StaticResource move}" RepeatBehavior="Forever"
Storyboard.TargetName="arrow" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[1].(Y)" Source="Y"></DoubleAnimationUsingPath>
</Storyboard>
</VisualState>
<VisualState Name="LayStopState">
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Viewbox VerticalAlignment="Center" HorizontalAlignment="Center">
<Viewbox HorizontalAlignment="Center" VerticalAlignment="Center">

<Canvas Width="205" Height="245" Margin="5">
<Polygon Points="0,80 20,40 205,40 185,80" Canvas.Left="67">
<Canvas
Width="205"
Height="245"
Margin="5">
<Polygon Canvas.Left="67" Points="0,80 20,40 205,40 185,80">
<Polygon.RenderTransform>
<SkewTransform AngleX="-40" />
</Polygon.RenderTransform>
@@ -84,35 +29,49 @@
<GradientStop Color="WhiteSmoke" Offset="0.85"/>
<GradientStop Color="LightGray" Offset="1"/>
</LinearGradientBrush>-->
<ImageBrush ImageSource="/BPASmartClient.CustomResource;component/Image/不锈钢纹理2.jpeg" Stretch="Fill"/>
<ImageBrush ImageSource="/BPASmartClient.CustomResource;component/Image/不锈钢纹理2.jpeg" Stretch="Fill" />
</Polygon.Fill>
</Polygon>
<Polygon Width="200" Height="70" Points="45,70 60,50 170,50 155,70" Stroke="Gray" StrokeThickness="2" Canvas.Left="67">
<Polygon
Canvas.Left="67"
Width="200"
Height="70"
Points="45,70 60,50 170,50 155,70"
Stroke="Gray"
StrokeThickness="2">
<Polygon.RenderTransform>
<SkewTransform AngleX="-40" />
</Polygon.RenderTransform>
</Polygon>
<Polygon x:Name="stock" Width="0" Height="0" Points="45,70 60,50 170,50 155,70" Canvas.Left="67" >
<Polygon
x:Name="stock"
Canvas.Left="67"
Width="0"
Height="0"
Points="45,70 60,50 170,50 155,70">
<Polygon.Fill>
<SolidColorBrush Color="DimGray"/>
<SolidColorBrush Color="DimGray" />
</Polygon.Fill>
<Polygon.RenderTransform>
<SkewTransform AngleX="-40" />
</Polygon.RenderTransform>
</Polygon>
<Polygon Points="-5,90 0,80 185,80 180,90" Panel.ZIndex="1" >
<Polygon Panel.ZIndex="1" Points="-5,90 0,80 185,80 180,90">
<Polygon.Fill>
<LinearGradientBrush>
<GradientStop Color="LightGray" Offset="0"/>
<GradientStop Color="White" Offset="0.66"/>
<GradientStop Color="LightGray" Offset="0.95"/>
<GradientStop Offset="0" Color="LightGray" />
<GradientStop Offset="0.66" Color="White" />
<GradientStop Offset="0.95" Color="LightGray" />
</LinearGradientBrush>
</Polygon.Fill>

</Polygon>
<Grid Width="185" Height="160" Canvas.Top="80">
<Grid
Canvas.Top="80"
Width="185"
Height="160">
<Grid.Background>
<ImageBrush ImageSource="/BPASmartClient.CustomResource;component/Image/不锈钢纹理.jpg" Stretch="Fill"/>
<ImageBrush ImageSource="/BPASmartClient.CustomResource;component/Image/不锈钢纹理.jpg" Stretch="Fill" />
</Grid.Background>
<!--<Grid VerticalAlignment="Bottom" Height="20" Margin="5">
<Grid.ColumnDefinitions>
@@ -134,7 +93,7 @@
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
</Button>
<Button Width="60" Grid.Column="1">
@@ -156,37 +115,65 @@
</Button>
</Grid>-->
</Grid>
<Grid Width="185" Height="60" Canvas.Top="90">
<Grid
Canvas.Top="90"
Width="185"
Height="60">
<Grid.Background>
<ImageBrush ImageSource="/BPASmartClient.CustomResource;component/Image/不锈钢纹理2.jpeg"/>
<ImageBrush ImageSource="/BPASmartClient.CustomResource;component/Image/不锈钢纹理2.jpeg" />
</Grid.Background>
<Grid.RenderTransform>
<TranslateTransform X="-5"/>
<TranslateTransform X="-5" />
</Grid.RenderTransform>
<TextBox x:Name="stockName" Width="58" Height="50" HorizontalAlignment="Left" HorizontalContentAlignment="Center" Background="Transparent"
BorderThickness="0" VerticalContentAlignment="Center" FontSize="13" Foreground="DarkSlateGray">
</TextBox>
<TextBox
x:Name="stockName"
Width="58"
Height="50"
HorizontalAlignment="Left"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
Background="Transparent"
BorderThickness="0"
FontSize="13"
Foreground="DarkSlateGray" />


<Border Width="80" Height="50" BorderBrush="DimGray " BorderThickness="2" CornerRadius="5" Margin="15,0,0,0">
<StackPanel >
<TextBlock HorizontalAlignment="Center" FontSize="12" Text="剩余重量" FontFamily="幼圆" Margin="0,2,0,5"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<TextBlock x:Name="stockWeight" HorizontalAlignment="Center" FontSize="16" />
<TextBlock Text="Kg" FontSize="16"/>
<Border
Width="80"
Height="50"
Margin="15,0,0,0"
BorderBrush="DimGray "
BorderThickness="2"
CornerRadius="5">
<StackPanel>
<TextBlock
Margin="0,2,0,5"
HorizontalAlignment="Center"
FontFamily="幼圆"
FontSize="12"
Text="剩余重量" />
<StackPanel HorizontalAlignment="Center" Orientation="Horizontal">
<TextBlock
x:Name="stockWeight"
HorizontalAlignment="Center"
FontSize="16" />
<TextBlock FontSize="16" Text="Kg" />
</StackPanel>
</StackPanel>
</Border>
</Grid>
<Grid Width="40" Height="60" Canvas.Top="90" Canvas.Left="180">
<Grid
Canvas.Left="180"
Canvas.Top="90"
Width="40"
Height="60">
<Grid.Background>
<ImageBrush ImageSource="/BPASmartClient.CustomResource;component/Image/不锈钢纹理3.jpeg" Stretch="UniformToFill"/>
<ImageBrush ImageSource="/BPASmartClient.CustomResource;component/Image/不锈钢纹理3.jpeg" Stretch="UniformToFill" />
</Grid.Background>
<Grid.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="0.119"/>
<SkewTransform AngleY="-65.5"/>
<ScaleTransform ScaleX="0.119" />
<SkewTransform AngleY="-65.5" />
</TransformGroup>
</Grid.RenderTransform>
<!--<Border VerticalAlignment="Top" Height="140" BorderThickness="10">
@@ -202,35 +189,44 @@
<Border Background="#FFAAAAAA" Margin="2"/>
<Border Background="#FFAAAAAA" Margin="2" Grid.Column="1"/>
</Grid>-->
</Grid >
<Path x:Name="arrow" Canvas.Top="175" Canvas.Left="113" Visibility="Collapsed" Data="M -15,8 L 17,17 C 17,17 19,18 17,19 L 17,19 L -15,28 C -15,28 -17,28.2 -16,26 L -16,26 L -5,18 L -16,10 C -16,10 -17,8.5 -15,8 Z">
</Grid>
<Path
x:Name="arrow"
Canvas.Left="113"
Canvas.Top="175"
Data="M -15,8 L 17,17 C 17,17 19,18 17,19 L 17,19 L -15,28 C -15,28 -17,28.2 -16,26 L -16,26 L -5,18 L -16,10 C -16,10 -17,8.5 -15,8 Z"
Visibility="Collapsed">
<Path.RenderTransform>
<TransformGroup>
<RotateTransform Angle="90"/>
<TranslateTransform Y="0"/>
<RotateTransform Angle="90" />
<TranslateTransform Y="0" />
</TransformGroup>
</Path.RenderTransform>
<Path.Fill>
<LinearGradientBrush>
<LinearGradientBrush.RelativeTransform>
<RotateTransform Angle="-15"/>
<RotateTransform Angle="-15" />
</LinearGradientBrush.RelativeTransform>
<GradientStop Color="LightGray" Offset="0"/>
<GradientStop Color="White" Offset="0.4"/>
<GradientStop Color="AntiqueWhite" Offset="1"/>
<GradientStop Offset="0" Color="LightGray" />
<GradientStop Offset="0.4" Color="White" />
<GradientStop Offset="1" Color="AntiqueWhite" />
</LinearGradientBrush>
</Path.Fill>
</Path>
<!--<Path Data="M 95,190 L 95,200" Stroke="Red"/>-->

<Grid Width="185" Height="160" Canvas.Top="80" Canvas.Left="185">
<Grid
Canvas.Left="185"
Canvas.Top="80"
Width="185"
Height="160">
<Grid.Background>
<ImageBrush ImageSource="/BPASmartClient.CustomResource;component/Image/不锈钢纹理.jpg"/>
<ImageBrush ImageSource="/BPASmartClient.CustomResource;component/Image/不锈钢纹理.jpg" />
</Grid.Background>
<Grid.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="0.288"/>
<SkewTransform AngleY="-36.8"/>
<ScaleTransform ScaleX="0.288" />
<SkewTransform AngleY="-36.8" />
</TransformGroup>
</Grid.RenderTransform>
<!--<Border VerticalAlignment="Top" Height="140" BorderThickness="10">
@@ -264,24 +260,109 @@
</Grid>-->
</Grid>

<Border Width="18" Height="18" CornerRadius="10" Canvas.Left="150" Canvas.Top="100">
<Border
Canvas.Left="150"
Canvas.Top="100"
Width="18"
Height="18"
CornerRadius="10">
<Border.Background>
<RadialGradientBrush>
<GradientStop Color="Gray" Offset="0.6" x:Name="gsGreen"/>
<GradientStop Color="White"/>
<GradientStop x:Name="gsGreen" Offset="0.6" Color="Gray" />
<GradientStop Color="White" />
</RadialGradientBrush>
</Border.Background>
</Border>
<Border Width="18" Height="18" CornerRadius="10" Canvas.Left="150" Canvas.Top="125" >
<Border
Canvas.Left="150"
Canvas.Top="125"
Width="18"
Height="18"
CornerRadius="10">
<Border.Background>
<RadialGradientBrush>
<GradientStop Color="Gray" Offset="0.6" x:Name="gsRed1"/>
<GradientStop Color="White"/>
<GradientStop x:Name="gsRed1" Offset="0.6" Color="Gray" />
<GradientStop Color="White" />
</RadialGradientBrush>
</Border.Background>
</Border>
</Canvas>
</Viewbox>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="StockGroup">
<VisualState Name="OpenState">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="stock"
Storyboard.TargetProperty="Width"
From="0"
To="200"
Duration="00:0:1" />
<DoubleAnimation
Storyboard.TargetName="stock"
Storyboard.TargetProperty="Height"
From="0"
To="70"
Duration="00:0:1" />
</Storyboard>
</VisualState>
<VisualState Name="CloseState">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="stock"
Storyboard.TargetProperty="Width"
From="200"
To="0"
Duration="00:0:1" />
<DoubleAnimation
Storyboard.TargetName="stock"
Storyboard.TargetProperty="Height"
From="70"
To="0"
Duration="00:0:1" />
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup Name="RunStateGroup">
<VisualState Name="RunState">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="gsGreen" Storyboard.TargetProperty="Color">
<DiscreteColorKeyFrame KeyTime="0" Value="Green" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState Name="Stop" />
</VisualStateGroup>
<VisualStateGroup x:Name="FaultStateGroup">
<VisualState Name="FaultState">
<Storyboard>
<ColorAnimationUsingKeyFrames
RepeatBehavior="Forever"
Storyboard.TargetName="gsRed1"
Storyboard.TargetProperty="Color">
<DiscreteColorKeyFrame KeyTime="0:0:0.5" Value="Red" />
<DiscreteColorKeyFrame KeyTime="0:0:1" Value="Gray" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState Name="NormalState" />
</VisualStateGroup>
<VisualStateGroup x:Name="LayOffStateGroup">
<VisualState Name="LayOffState">
<Storyboard>
<DoubleAnimationUsingPath
PathGeometry="{StaticResource move}"
RepeatBehavior="Forever"
Source="Y"
Storyboard.TargetName="arrow"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[1].(Y)"
Duration="0:0:1" />
</Storyboard>
</VisualState>
<VisualState Name="LayStopState" />

</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Border>
</UserControl>

+ 230
- 0
BPASmartClient.CustomResource/UserControls/NumberTextBox.xaml Переглянути файл

@@ -0,0 +1,230 @@
<UserControl
x:Class="BPASmartClient.CustomResource.UserControls.NumberTextBox"
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:local="clr-namespace:BPASmartClient.CustomResource.UserControls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
d:DesignHeight="35"
d:DesignWidth="150"
mc:Ignorable="d">


<UserControl.Resources>

<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/BPASmartClient.CustomResource;component/RecDictionarys/RecButtonStyle.xaml" />

<ResourceDictionary>
<Style x:Key="TextBoxStyle" TargetType="TextBox">
<Setter Property="FontFamily" Value="楷体" />
<Setter Property="FontSize" Value="22" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Width" Value="188" />
<Setter Property="Padding" Value="6,0,0,0" />
<Setter Property="Height" Value="37" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Foreground" Value="#009dff" />
<Setter Property="BorderBrush" Value="#009dff" />
<Setter Property="CaretBrush" Value="#009dff" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Background">
<Setter.Value>
<ImageBrush ImageSource="/BPASmartClient.CustomResource;component/Image/textBox.png" Stretch="Fill" />
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>


</UserControl.Resources>

<Grid>
<Viewbox>
<Grid>
<TextBox
Name="outLoc"
Width="180"
Height="35"
FontSize="20"
GotFocus="outLoc_GotFocus"
Style="{StaticResource TextBoxStyle}" />

<Popup
Name="pp"
AllowsTransparency="True"
Focusable="False"
Placement="Bottom"
PlacementTarget="{Binding ElementName=outLoc}"
StaysOpen="True">
<Border
Width="260"
Height="300"
Background="#081424"
ClipToBounds="True">
<Grid Margin="0">
<Grid.RowDefinitions>
<RowDefinition Height="35" />
<RowDefinition />
</Grid.RowDefinitions>

<TextBox
Name="input"
Width="267"
Height="36"
Margin="-4,0,0,0"
VerticalContentAlignment="Center"
FontSize="18"
GotFocus="input_GotFocus"
Style="{StaticResource TextBoxStyle}" />

<Grid Grid.Row="1">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>

<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>

<Button
Grid.Row="0"
Grid.Column="0"
Margin="2"
Click="Button_Click"
Content="1"
FontSize="20"
Style="{StaticResource ImageButtonStyle}" />
<Button
Grid.Row="0"
Grid.Column="1"
Margin="2"
Click="Button_Click"
Content="2"
FontSize="20"
Style="{StaticResource ImageButtonStyle}" />
<Button
Grid.Row="0"
Grid.Column="2"
Margin="2"
Click="Button_Click"
Content="3"
FontSize="20"
Style="{StaticResource ImageButtonStyle}" />
<Button
Grid.Row="0"
Grid.Column="3"
Margin="2"
Click="Button_Click"
Content="ESC"
FontSize="20"
Style="{StaticResource ImageButtonStyle}" />
<Button
Grid.Row="1"
Grid.Column="0"
Margin="2"
Click="Button_Click"
Content="4"
FontSize="20"
Style="{StaticResource ImageButtonStyle}" />
<Button
Grid.Row="1"
Grid.Column="1"
Margin="2"
Click="Button_Click"
Content="5"
FontSize="20"
Style="{StaticResource ImageButtonStyle}" />
<Button
Grid.Row="1"
Grid.Column="2"
Margin="2"
Click="Button_Click"
Content="6"
FontSize="20"
Style="{StaticResource ImageButtonStyle}" />
<Button
Grid.Row="1"
Grid.Column="3"
Margin="2"
Click="Button_Click"
Content="BR"
FontSize="20"
Style="{StaticResource ImageButtonStyle}" />
<Button
Grid.Row="2"
Grid.Column="0"
Margin="2"
Click="Button_Click"
Content="7"
FontSize="20"
Style="{StaticResource ImageButtonStyle}" />
<Button
Grid.Row="2"
Grid.Column="1"
Margin="2"
Click="Button_Click"
Content="8"
FontSize="20"
Style="{StaticResource ImageButtonStyle}" />
<Button
Grid.Row="2"
Grid.Column="2"
Margin="2"
Click="Button_Click"
Content="9"
FontSize="20"
Style="{StaticResource ImageButtonStyle}" />
<Button
Grid.Row="2"
Grid.Column="3"
Margin="2"
Click="Button_Click"
Content="Clear"
FontSize="20"
Style="{StaticResource ImageButtonStyle}" />
<Button
Grid.Row="3"
Grid.Column="0"
Margin="2"
Click="Button_Click"
Content="0"
FontSize="20"
Style="{StaticResource ImageButtonStyle}" />
<Button
Grid.Row="3"
Grid.Column="1"
Margin="2"
Click="Button_Click"
Content="."
FontSize="20"
Style="{StaticResource ImageButtonStyle}" />
<Button
Grid.Row="3"
Grid.Column="2"
Grid.ColumnSpan="2"
Margin="2"
Click="Button_Click"
Content="Deter"
FontSize="20"
Style="{StaticResource ImageButtonStyle}" />
</Grid>


</Grid>
</Border>
</Popup>

</Grid>
</Viewbox>
</Grid>
</UserControl>

+ 81
- 0
BPASmartClient.CustomResource/UserControls/NumberTextBox.xaml.cs Переглянути файл

@@ -0,0 +1,81 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace BPASmartClient.CustomResource.UserControls
{
/// <summary>
/// NumberTextBox.xaml 的交互逻辑
/// </summary>
public partial class NumberTextBox : UserControl
{
public NumberTextBox()
{
InitializeComponent();
}


private void outLoc_GotFocus(object sender, RoutedEventArgs e)
{
this.pp.IsOpen = outLoc.Focusable;
}

private void Button_Click(object sender, RoutedEventArgs e)
{
var obj = (Button)sender;
switch (obj.Content)
{
case "0":
case "1":
case "2":
case "3":
case "4":
case "5":
case "6":
case "7":
case "8":
case "9":
input.Text = input.Text.Trim() + obj.Content.ToString();
break;
case ".":
if (!string.IsNullOrEmpty(input.Text) && input.Text.Length > 0)
input.Text = input.Text.Trim() + obj.Content.ToString();
break;
case "ESC":
this.pp.IsOpen = false;
break;
case "BR":
if (!string.IsNullOrEmpty(input.Text) && input.Text.Length > 0)
input.Text = input.Text.Remove(input.Text.Length - 1);
break;
case "Clear":
input.Text = string.Empty;
break;
case "Deter":
outLoc.Text = input.Text;
this.pp.IsOpen = false;
break;
default:
break;
}
}

private void input_GotFocus(object sender, RoutedEventArgs e)
{

}


}
}

+ 7
- 0
BPASmartClient.DosingProject/Model/GVL_SmallStation.cs Переглянути файл

@@ -78,6 +78,13 @@ namespace BPASmartClient.DosingHKProject.Model

public HKPlcCommRead plcRead = new HKPlcCommRead();
public HKPlcCommWrite plcWrite = new HKPlcCommWrite();
/// <summary>
/// 0:无意义,1=load位,2=1号位,3=2号位,4=3号位,5=4号位,6=5号位,7=6号位,8=unload位
/// </summary>
public int[] Barrel_Location = new int[MaxBarrelNum];
public bool[] AllowDosing_Pos = new bool[MaxBarrelNum];
public bool[] AllowDosing_Sign = new bool[MaxBarrelNum];
public const int MaxBarrelNum = 6;
#region 本地模拟配方
/// <summary>
/// 是否使用本地模拟配方


+ 228
- 15
BPASmartClient.DosingProject/Model/ProcessControl.cs Переглянути файл

@@ -188,6 +188,16 @@ namespace BPASmartClient.DosingHKProject.Model
GVL_SmallStation.GetInstance.RecipeStatusID = 0;
}
}

int cnt_sensor1 = 0;
int cnt_sensor2 = 0;
int cnt_sensor3 = 0;
int cnt_sensor4 = 0;
int cnt_sensor5 = 0;
int cnt_sensor6 = 0;
int cnt_sensor7 = 0;
int cnt_sensor8 = 0;
int barrel1 = 0;
/// <summary>
/// 执行配方队列中的第一个配方
/// </summary>
@@ -199,12 +209,214 @@ namespace BPASmartClient.DosingHKProject.Model
if (index >= 0 && index < RemoteRecipes.Count)
{
string code = RemoteRecipes.ElementAt(index).RecipeCode;
int trayCode = RemoteRecipes.ElementAt(index).TrayCode;
string recipeName = RemoteRecipes.ElementAt(index).RecipeName;
string windSend = RemoteRecipes.ElementAt(index).ToString();
#region sensor处理
if (GVL_SmallStation.GetInstance.plcRead.Sensor_Load)
{
cnt_sensor1++;
}
else
{
if (cnt_sensor1 >= 50)
{
if (barrel1 >= 0 && barrel1 < GVL_SmallStation.MaxBarrelNum)
{
if (GVL_SmallStation.GetInstance.Barrel_Location[barrel1] == 0)
{
GVL_SmallStation.GetInstance.Barrel_Location[barrel1] = 1;
barrel1++;
}
}
else
{
//报错,超过最大的桶号数
}
}
cnt_sensor1 = 0;
}
if (GVL_SmallStation.GetInstance.plcRead.Sensor_Station1)
{
cnt_sensor2++;
}
else
{
if (cnt_sensor2 >= 50)
{
for (int i = 0; i < GVL_SmallStation.GetInstance.Barrel_Location.Length; i++)
{
if (GVL_SmallStation.GetInstance.Barrel_Location[i] == 1)
{
GVL_SmallStation.GetInstance.Barrel_Location[i] = 2;
}
}
}
cnt_sensor2 = 0;
}
if (GVL_SmallStation.GetInstance.plcRead.Sensor_Station2)
{
cnt_sensor3++;
}
else
{
if (cnt_sensor3 >= 50)
{
for (int i = 0; i < GVL_SmallStation.GetInstance.Barrel_Location.Length; i++)
{
if (GVL_SmallStation.GetInstance.Barrel_Location[i] == 2)
{
GVL_SmallStation.GetInstance.Barrel_Location[i] = 3;
}
}
}
cnt_sensor3 = 0;
}
if (GVL_SmallStation.GetInstance.plcRead.Sensor_Station3)
{
cnt_sensor4++;
}
else
{
if (cnt_sensor4 >= 50)
{
for (int i = 0; i < GVL_SmallStation.GetInstance.Barrel_Location.Length; i++)
{
if (GVL_SmallStation.GetInstance.Barrel_Location[i] == 3)
{
GVL_SmallStation.GetInstance.Barrel_Location[i] = 4;
}
}
}
cnt_sensor4 = 0;
}
if (GVL_SmallStation.GetInstance.plcRead.Sensor_Station4)
{
cnt_sensor5++;
}
else
{
if (cnt_sensor5 >= 50)
{
for (int i = 0; i < GVL_SmallStation.GetInstance.Barrel_Location.Length; i++)
{
if (GVL_SmallStation.GetInstance.Barrel_Location[i] == 4)
{
GVL_SmallStation.GetInstance.Barrel_Location[i] = 5;
}
}
}
cnt_sensor5 = 0;
}
if (GVL_SmallStation.GetInstance.plcRead.Sensor_Station5)
{
cnt_sensor6++;
}
else
{
if (cnt_sensor6 >= 50)
{
for (int i = 0; i < GVL_SmallStation.GetInstance.Barrel_Location.Length; i++)
{
if (GVL_SmallStation.GetInstance.Barrel_Location[i] == 5)
{
GVL_SmallStation.GetInstance.Barrel_Location[i] = 6;
}
}
}
cnt_sensor6 = 0;
}
if (GVL_SmallStation.GetInstance.plcRead.Sensor_Station6)
{
cnt_sensor7++;
}
else
{
if (cnt_sensor7 >= 50)
{
for (int i = 0; i < GVL_SmallStation.GetInstance.Barrel_Location.Length; i++)
{
if (GVL_SmallStation.GetInstance.Barrel_Location[i] == 6)
{
GVL_SmallStation.GetInstance.Barrel_Location[i] = 7;
}
}
}
cnt_sensor7 = 0;
}
if (GVL_SmallStation.GetInstance.plcRead.Sensor_Unload)
{
HKDevice.HK_PLC_S7.Write<bool>("DB2.DBX3.0", false);
HKDevice.HK_PLC_S7.Write<bool>("DB2.DBX3.1", false);
MessageLog.GetInstance.ShowRunLog($"下料桶堵料,线体不运行");
cnt_sensor8++;
}
else
{
if (cnt_sensor8 >= 50)
{
for (int i = 0; i < GVL_SmallStation.GetInstance.Barrel_Location.Length; i++)
{
if (GVL_SmallStation.GetInstance.Barrel_Location[i] == 7)
{
GVL_SmallStation.GetInstance.Barrel_Location[i] = 0;
}
}
}
cnt_sensor8 = 0;
}
#endregion
for (int i = 0; i < GVL_SmallStation.GetInstance.Barrel_Location.Length; i++)
{
if (GVL_SmallStation.GetInstance.plcRead.Sensor_Station1 && GVL_SmallStation.GetInstance.Barrel_Location[i] == 1)
{
foreach (var item in RemoteRecipes.ElementAt(index).RawMaterial)
{
if ((item.RawMaterialLocation == i+1 || item.RawMaterialLocation == i+7) && item.IsDosingFinish == false && item.RawMaterialBarrelNum == i+1)
{
GVL_SmallStation.GetInstance.AllowDosing_Pos[i] = true;
}
}
}
}
if (GVL_SmallStation.GetInstance.plcRead.Sensor_Station1 && GVL_SmallStation.GetInstance.Barrel_Location[0] == 1)
{
foreach (var item in RemoteRecipes.ElementAt(index).RawMaterial)
{
if ((item.RawMaterialLocation == 1 || item.RawMaterialLocation == 7) && item.IsDosingFinish == false && item.RawMaterialBarrelNum == 1)
{
GVL_SmallStation.GetInstance.AllowDosing_Pos[0] = true;
}
}
}
if (GVL_SmallStation.GetInstance.plcRead.Sensor_Station2 && GVL_SmallStation.GetInstance.Barrel_Location[1] == 1)
{
GVL_SmallStation.GetInstance.AllowDosing_Pos[1] = true;
}
if (GVL_SmallStation.GetInstance.plcRead.Sensor_Station3 && GVL_SmallStation.GetInstance.Barrel_Location[2] == 1)
{
GVL_SmallStation.GetInstance.AllowDosing_Pos[2] = true;
}
if (GVL_SmallStation.GetInstance.plcRead.Sensor_Station4 && GVL_SmallStation.GetInstance.Barrel_Location[3] == 1)
{
GVL_SmallStation.GetInstance.AllowDosing_Pos[3] = true;
}
if (GVL_SmallStation.GetInstance.plcRead.Sensor_Station5 && GVL_SmallStation.GetInstance.Barrel_Location[4] == 1)
{
GVL_SmallStation.GetInstance.AllowDosing_Pos[4] = true;
}
if (GVL_SmallStation.GetInstance.plcRead.Sensor_Station6 && GVL_SmallStation.GetInstance.Barrel_Location[5] == 1)
{
GVL_SmallStation.GetInstance.AllowDosing_Pos[5] = true;
}
foreach (var item in RemoteRecipes.ElementAt(index).RawMaterial)
{
}
if (GVL_SmallStation.GetInstance.RecipeStatusID == 0)
{
RunInit();
if (RunInit() == 1)
{
GVL_SmallStation.GetInstance.RecipeStatusID = 1;
}
}
if (GVL_SmallStation.GetInstance.RecipeStatusID == 1)
{
@@ -214,28 +426,29 @@ namespace BPASmartClient.DosingHKProject.Model
}
if (HKDevice.HK_PLC_S7.Read<bool>("DB2.DBX3.0") && HKDevice.HK_PLC_S7.Read<bool>("DB2.DBX3.1") && GVL_SmallStation.GetInstance.RecipeStatusID == 2)
{
if (GVL_SmallStation.GetInstance.plcRead.Sensor_Load)
{
}
GVL_SmallStation.GetInstance.RecipeStatusID = 3;
}
if (GVL_SmallStation.GetInstance.RecipeStatusID == 3)
{
if (RTrig.GetInstance("DB3.DBX50.0").Start(HKDevice.HK_PLC_S7.Read<bool>("DB3.DBX50.0")))
for (int i = 0; i < 6; i++)
{
var res = HKDevice.HK_PLC_S7.Read<float>("DB3.DBD10");
MessageLog.GetInstance.ShowRunLog($"托盘1,配方:{recipeName},1号桶,{res}料仓,允许配料");
if (res > 0 && res is float loc)

}
if (GVL_SmallStation.GetInstance.AllowDosing_Pos[0])
{
int res = 1;
MessageLog.GetInstance.ShowRunLog($"配方:{recipeName},1号桶,{res}料仓,允许配料");
if (res > 0 )
{
int loc_index = Array.FindIndex(RemoteRecipes.ElementAt(index).RawMaterial.ToArray(), p => p.RawMaterialLocation == loc);
int loc_index = Array.FindIndex(RemoteRecipes.ElementAt(index).RawMaterial.ToArray(), p => p.RawMaterialLocation == res);
float weight = RemoteRecipes.ElementAt(index).RawMaterial.ElementAt(loc_index).RawMaterialWeight;
if (loc_index >= 0)
{
DeviceInquire.GetInstance.GetDevice((int)loc)?.Start(weight);//根据料仓编号 启动并写入每个原料重量
GVL_SmallStation.GetInstance.StockInIsWork = (int)loc;
DeviceInquire.GetInstance.GetDevice((int)res)?.Start(weight);//根据料仓编号 启动并写入每个原料重量
GVL_SmallStation.GetInstance.StockInIsWork = (int)res;
}
GVL_SmallStation.GetInstance.DosingTray1 = true;
MessageLog.GetInstance.ShowRunLog($"托盘1,配方:{recipeName},1号桶,{(int)loc}号仓,配料完成");
MessageLog.GetInstance.ShowRunLog($"托盘1,配方:{recipeName},1号桶,{(int)res}号仓,配料完成");
}
}
else if(RTrig.GetInstance("DB3.DBX50.1").Start(HKDevice.HK_PLC_S7.Read<bool>("DB3.DBX50.1")))


+ 1
- 1
BPASmartClient.DosingProject/Model/RawMaterial/DeviceInquire.cs Переглянути файл

@@ -210,7 +210,7 @@ namespace BPASmartClient.DosingHKProject.Model
{
if (Global.DeviceRawMaterials.FirstOrDefault(p => p.RawMaterialName == DeviceName) == null)
{
Global.DeviceRawMaterials.Add(new RawMaterialModel() { RawMaterialName = DeviceName, DeviceIp = ip, RawMaterialSource = 1});
Global.DeviceRawMaterials.Add(new RawMaterialModel() { RawMaterialName = DeviceName, DeviceIp = ip, RawMaterialSource = 1 });
}
}
else


+ 0
- 6
BPASmartClient.DosingProject/Model/Recipes/RemoteRecipeData.cs Переглянути файл

@@ -21,12 +21,6 @@ namespace BPASmartClient.DosingHKProject.Model
/// </summary>
public string RecipeCode { get { return _mRecipeCode; } set { _mRecipeCode = value;OnPropertyChanged(); } }
private string _mRecipeCode;
/// <summary>
/// 托盘编号
/// </summary>
public int TrayCode { get { return _mTrayCode; } set { _mTrayCode = value; OnPropertyChanged(); } }
private int _mTrayCode;

/// <summary>
/// 原料数据


+ 3
- 0
BPASmartClient.DosingProject/Model/Recipes/RemoteRecipeRawMaterial.cs Переглянути файл

@@ -44,5 +44,8 @@ namespace BPASmartClient.DosingHKProject.Model
/// </summary>
public int RawMaterialLocation { get { return _mRawMaterialLocation; } set { _mRawMaterialLocation = value;OnPropertyChanged(); } }
private int _mRawMaterialLocation;

public bool IsDosingFinish { get { return _mDosingFinish; } set { _mDosingFinish = value; } }
private bool _mDosingFinish;
}
}

+ 3
- 1
BPASmartClient.JXJFoodSmallStation/App.xaml.cs Переглянути файл

@@ -29,7 +29,7 @@ namespace BPASmartClient.JXJFoodSmallStation
MenuInit();
DataInit();
DeviceInquire.GetInstance.Init();//配料机设备上线监听,设备列表初始化
// ProcessControl.GetInstance.Init();
ProcessControl.GetInstance.Init();
MainView mv = new MainView();
LoginView lv = new LoginView();
var res = lv.ShowDialog();
@@ -47,6 +47,7 @@ namespace BPASmartClient.JXJFoodSmallStation
{
base.OnExit(e);
Json<LocaPar>.Save();
Json<LocalRecipeDataColl>.Save();
MessageLog.GetInstance.LogSave();
ThreadManage.GetInstance().Dispose();
}
@@ -258,6 +259,7 @@ namespace BPASmartClient.JXJFoodSmallStation
Json<LocaPar>.Read();
Json<DevicePar>.Read();
Json<WindSendDevicePar>.Read();
Json<LocalRecipeDataColl>.Read();
}

}


+ 3
- 0
BPASmartClient.JXJFoodSmallStation/Model/GVL_SmallStation.cs Переглянути файл

@@ -37,6 +37,9 @@ namespace BPASmartClient.JXJFoodSmallStation.Model
/// Tray2的柔性味魔方配料标志
/// </summary>
public bool DosingTray2 { get; set; } = true;

public int DosingTray1Loc { get; set; } = 0;
public int DosingTray2Loc { get; set; } = 0;
/// <summary>
/// 配方下发状态 =0:配方未下发 ,1:配方下发给plc ,2:plc成功接收配方
/// </summary>


+ 6
- 1
BPASmartClient.JXJFoodSmallStation/Model/HK_PLC/HKDeviceStatus.cs Переглянути файл

@@ -7,6 +7,7 @@ using System.Text;
using System.Threading.Tasks;
using BPASmartClient.S7Net;
using BPASmartClient.CustomResource.Pages.Model;
using System.Threading;

namespace BPASmartClient.JXJFoodSmallStation.Model.HK_PLC
{
@@ -20,7 +21,11 @@ namespace BPASmartClient.JXJFoodSmallStation.Model.HK_PLC
{
ThreadManage.GetInstance().StartLong(new Action(() =>
{
if (!IsConnected)
{
MessageLog.GetInstance.ShowRunLog("海科PLC断开连接");
}
Thread.Sleep(10);
}),"信号收发处理");
}
}


+ 75
- 35
BPASmartClient.JXJFoodSmallStation/Model/ProcessControl.cs Переглянути файл

@@ -691,6 +691,7 @@ namespace BPASmartClient.JXJFoodSmallStation.Model
//HKDevice.HK_PLC_S7.Write("DB3.DBX50.0", false);
}
GVL_SmallStation.GetInstance.DosingTray1 = true;
GVL_SmallStation.GetInstance.DosingTray1Loc = (int)loc;
MessageLog.GetInstance.ShowRunLog($"托盘1,配方:{recipeName},1号桶,{(int)loc}号仓,配料完成");
}
}
@@ -709,6 +710,7 @@ namespace BPASmartClient.JXJFoodSmallStation.Model
//HKDevice.HK_PLC_S7.Write("DB3.DBX50.1", false);
}
GVL_SmallStation.GetInstance.DosingTray1 = true;
GVL_SmallStation.GetInstance.DosingTray1Loc = (int)loc;
MessageLog.GetInstance.ShowRunLog($"托盘1,配方:{recipeName},2号桶,{(int)loc}号仓,配料完成");
}
}
@@ -727,6 +729,7 @@ namespace BPASmartClient.JXJFoodSmallStation.Model
//HKDevice.HK_PLC_S7.Write("DB3.DBX50.2", false);
}
GVL_SmallStation.GetInstance.DosingTray1 = true;
GVL_SmallStation.GetInstance.DosingTray1Loc = (int)loc;
MessageLog.GetInstance.ShowRunLog($"托盘1,配方:{recipeName},3号桶,{(int)loc}号仓,配料完成");
}
}
@@ -745,30 +748,34 @@ namespace BPASmartClient.JXJFoodSmallStation.Model
//HKDevice.HK_PLC_S7.Write("DB3.DBX50.3", false);
}
GVL_SmallStation.GetInstance.DosingTray1 = true;
GVL_SmallStation.GetInstance.DosingTray1Loc = (int)loc;
MessageLog.GetInstance.ShowRunLog($"托盘1,配方:{recipeName},4号桶,{(int)loc}号仓,配料完成");
}
}
if (GVL_SmallStation.GetInstance.DosingTray1)
if (GVL_SmallStation.GetInstance.DosingTray1 && GVL_SmallStation.GetInstance.DosingTray1Loc > 0 && GVL_SmallStation.GetInstance.DosingTray1Loc < 16)
{
for (int i = 1; i < 16; i++)
int i = GVL_SmallStation.GetInstance.DosingTray1Loc;
if (RTrig.GetInstance("Tray1StatusDevice" + i).Start(DeviceInquire.GetInstance.GetDevice(i).deviceStatus.RunStatus == 3))
{
if (RTrig.GetInstance("GetDeviceRunStatus").Start(DeviceInquire.GetInstance.GetDevice(i).deviceStatus.RunStatus == 3))
MessageLog.GetInstance.ShowRunLog($"柔性味魔方,托盘1,配方:{recipeName},{i}号仓,配料完成");
int res = Array.FindIndex(RemoteRecipes.ElementAt(index).RawMaterial.ToArray(), p => p.RawMaterialLocation == i);
RemoteRecipes.ElementAt(index).RawMaterial.ElementAt(res).Laying_Off_Weight = DeviceInquire.GetInstance.GetDevice(i).deviceStatus.CutWeightFeedback;
string info = DeviceInquire.GetInstance.GetDevice(i).StatusReset();
MessageLog.GetInstance.ShowRunLog(info);
if (i >= 1 && i <= 8)
{
MessageLog.GetInstance.ShowRunLog($"柔性味魔方,托盘1,配方:{recipeName},{i}号仓,配料完成");
int res = Array.FindIndex(RemoteRecipes.ElementAt(index).RawMaterial.ToArray(), p => p.RawMaterialLocation == i);
RemoteRecipes.ElementAt(index).RawMaterial.ElementAt(res).Laying_Off_Weight = DeviceInquire.GetInstance.GetDevice(i).deviceStatus.CutWeightFeedback;
DeviceInquire.GetInstance.GetDevice(i).StatusReset();
if (i >= 1 && i <= 8)
{
HKDevice.HK_PLC_S7.Write("DB4.DBX30." + (i - 1), true);
}
else if (i >= 9 && i <= 15)
{
HKDevice.HK_PLC_S7.Write("DB4.DBX31." + (i - 9), true);
}
GVL_SmallStation.GetInstance.DosingTray1 = false;
string commInfo = HKDevice.HK_PLC_S7.Write("DB4.DBX30." + (i - 1), true);
MessageLog.GetInstance.ShowRunLog(commInfo);
}
else if (i >= 9 && i <= 15)
{
string commInfo1 = HKDevice.HK_PLC_S7.Write("DB4.DBX31." + (i - 9), true);
MessageLog.GetInstance.ShowRunLog(commInfo1);
}
GVL_SmallStation.GetInstance.DosingTray1 = false;
GVL_SmallStation.GetInstance.DosingTray1Loc = 0;
}
}
if (RTrig.GetInstance("配方配料完成").Start(HKDevice.HK_PLC_S7.Read<bool>("DB3.DBX1.1")) && (GVL_SmallStation.GetInstance.WindSendDosingFinish || !GVL_SmallStation.GetInstance.IsUseWindSend))
{
@@ -847,6 +854,7 @@ namespace BPASmartClient.JXJFoodSmallStation.Model
//HKDevice.HK_PLC_S7.Write("DB3.DBX50.0", false);
}
GVL_SmallStation.GetInstance.DosingTray2 = true;
GVL_SmallStation.GetInstance.DosingTray2Loc = (int)loc;
MessageLog.GetInstance.ShowRunLog($"托盘2,配方:{recipeName},1号桶,{(int)loc}号仓,配料完成");
}
}
@@ -865,6 +873,7 @@ namespace BPASmartClient.JXJFoodSmallStation.Model
//HKDevice.HK_PLC_S7.Write("DB3.DBX50.5", false);
}
GVL_SmallStation.GetInstance.DosingTray2 = true;
GVL_SmallStation.GetInstance.DosingTray2Loc = (int)loc;
MessageLog.GetInstance.ShowRunLog($"托盘2,配方:{recipeName},2号桶,{(int)loc}号仓,配料完成");
}
}
@@ -875,7 +884,7 @@ namespace BPASmartClient.JXJFoodSmallStation.Model
if (res > 0 && res is float loc)
{
int loc_index = Array.FindIndex(RemoteRecipes.ElementAt(index).RawMaterial.ToArray(), p => p.RawMaterialLocation == loc);
double weight = RemoteRecipes.ElementAt(index).RawMaterial.ElementAt(loc_index).RawMaterialWeight;
double weight = RemoteRecipes.ElementAt(index).RawMaterial.ElementAt(loc_index).RawMaterialWeightW;
if (loc_index >= 0)
{
DeviceInquire.GetInstance.GetDevice((int)loc)?.Start((uint)weight);//启动并写入每个原料重量
@@ -883,8 +892,8 @@ namespace BPASmartClient.JXJFoodSmallStation.Model
//HKDevice.HK_PLC_S7.Write("DB3.DBX50.6", false);
}
GVL_SmallStation.GetInstance.DosingTray2 = true;
GVL_SmallStation.GetInstance.DosingTray2Loc = (int)loc;
MessageLog.GetInstance.ShowRunLog($"托盘2,配方:{recipeName},3号桶,{(int)loc}号仓,配料完成");

}
}
else if (RTrig.GetInstance("DB3.DBX50.7").Start(HKDevice.HK_PLC_S7.Read<bool>("DB3.DBX50.7")))
@@ -902,35 +911,38 @@ namespace BPASmartClient.JXJFoodSmallStation.Model
//HKDevice.HK_PLC_S7.Write("DB3.DBX50.7", false);
}
GVL_SmallStation.GetInstance.DosingTray2 = true;
GVL_SmallStation.GetInstance.DosingTray2Loc = (int)loc;
MessageLog.GetInstance.ShowRunLog($"托盘2,配方:{recipeName},4号桶,{(int)loc}号仓,配料完成");
}
}
if (GVL_SmallStation.GetInstance.DosingTray2 == true)
if (GVL_SmallStation.GetInstance.DosingTray2 == true && GVL_SmallStation.GetInstance.DosingTray1 == false && GVL_SmallStation.GetInstance.DosingTray2Loc > 0 && GVL_SmallStation.GetInstance.DosingTray2Loc < 16)
{
for (int i = 1; i < 16; i++)
int i = GVL_SmallStation.GetInstance.DosingTray2Loc;
if (RTrig.GetInstance("Tray2StatusDevice" + i).Start(DeviceInquire.GetInstance.GetDevice(i).deviceStatus.RunStatus == 3))
{
if (RTrig.GetInstance("柔性味魔方配料完成").Start(DeviceInquire.GetInstance.GetDevice(i).deviceStatus.RunStatus == 3))
MessageLog.GetInstance.ShowRunLog($"柔性味魔方,托盘2,配方:{recipeName},{i}号仓,配料完成");
int res = Array.FindIndex(RemoteRecipes.ElementAt(index).RawMaterial.ToArray(), p => p.RawMaterialLocation == i);
RemoteRecipes.ElementAt(index).RawMaterial.ElementAt(res).Laying_Off_Weight = DeviceInquire.GetInstance.GetDevice(i).deviceStatus.CutWeightFeedback;
string info = DeviceInquire.GetInstance.GetDevice(i).StatusReset();
MessageLog.GetInstance.ShowRunLog(info);
if (i >= 1 && i <= 8)
{
string commInfo = HKDevice.HK_PLC_S7.Write("DB4.DBX30." + (i - 1), true);
MessageLog.GetInstance.ShowRunLog(commInfo);
}
else if (i >= 9 && i <= 15)
{
MessageLog.GetInstance.ShowRunLog($"柔性味魔方,托盘2,配方:{recipeName},{i}号仓,配料完成");
int res = Array.FindIndex(RemoteRecipes.ElementAt(index).RawMaterial.ToArray(), p => p.RawMaterialLocation == i);
RemoteRecipes.ElementAt(index).RawMaterial.ElementAt(res).Laying_Off_Weight = DeviceInquire.GetInstance.GetDevice(i).deviceStatus.CutWeightFeedback;
DeviceInquire.GetInstance.GetDevice(i).StatusReset();
if (i >= 1 && i <= 8)
{
HKDevice.HK_PLC_S7.Write("DB4.DBX30." + (i - 1), true);
}
else if (i >= 9 && i <= 15)
{
HKDevice.HK_PLC_S7.Write("DB4.DBX31." + (i - 9), true);
}
GVL_SmallStation.GetInstance.DosingTray2 = false;
string commInfo1 = HKDevice.HK_PLC_S7.Write("DB4.DBX31." + (i - 9), true);
MessageLog.GetInstance.ShowRunLog(commInfo1);
}
GVL_SmallStation.GetInstance.DosingTray2 = false;
GVL_SmallStation.GetInstance.DosingTray2Loc = 0;
}
}
if (RTrig.GetInstance("DB3.DBX1.2").Start(HKDevice.HK_PLC_S7.Read<bool>("DB3.DBX1.2")))
{
var res = Json<RemoteRecipeDataColl>.Data.Recipes.FirstOrDefault(p => p.RecipeCode == code);
MessageLog.GetInstance.ShowRunLog($"托盘2配方{res.RecipeName}配料完成");
MessageLog.GetInstance.ShowRunLog($"托盘2,配方{res.RecipeName},配料完成");
RecipeFinishInfo.Order_No = RemoteRecipes.ElementAt(index).RecipeCode;
RecipeFinishInfo.Product_Code = RemoteRecipes.ElementAt(index).RecipeName;
for (int i = 0; i < RemoteRecipes.ElementAt(index).RawMaterial.Count; i++)
@@ -958,5 +970,33 @@ namespace BPASmartClient.JXJFoodSmallStation.Model
}
}
}
private void StockBinInit()
{
for (int i = 1; i < 16; i++)
{
if (DeviceInquire.GetInstance.GetDevice(i).deviceStatus.RunStatus == 3)
{
DeviceInquire.GetInstance.GetDevice(i).StatusReset();
}
}
}
private void DosingDevice(int Index,int DeviceID)
{
if (RTrig.GetInstance("Tray2StatusDevice" + DeviceID).Start(DeviceInquire.GetInstance.GetDevice(DeviceID).deviceStatus.RunStatus == 3))
{
MessageLog.GetInstance.ShowRunLog($"柔性味魔方,托盘2,配方:{RemoteRecipes.ElementAt(Index).RecipeName},{DeviceID}号仓,配料完成");
int res = Array.FindIndex(RemoteRecipes.ElementAt(Index).RawMaterial.ToArray(), p => p.RawMaterialLocation == DeviceID);
RemoteRecipes.ElementAt(Index).RawMaterial.ElementAt(res).Laying_Off_Weight = DeviceInquire.GetInstance.GetDevice(DeviceID).deviceStatus.CutWeightFeedback;
DeviceInquire.GetInstance.GetDevice(DeviceID).StatusReset();
if (DeviceID >= 1 && DeviceID <= 8)
{
HKDevice.HK_PLC_S7.Write("DB4.DBX30." + (DeviceID - 1), true);
}
else if (DeviceID >= 9 && DeviceID <= 15)
{
HKDevice.HK_PLC_S7.Write("DB4.DBX31." + (DeviceID - 9), true);
}
}
}
}
}

+ 2
- 2
BPASmartClient.JXJFoodSmallStation/Model/RawMaterial/DeviceCurrentStatus.cs Переглянути файл

@@ -14,8 +14,8 @@ namespace BPASmartClient.JXJFoodSmallStation.Model
private double _mWeight;


public bool RunStatus { get { return _mRunStatus; } set { _mRunStatus = value; OnPropertyChanged(); } }
private bool _mRunStatus;
public ushort RunStatus { get { return _mRunStatus; } set { _mRunStatus = value; OnPropertyChanged(); } }
private ushort _mRunStatus;


public int DeviceNum { get { return _mDeviceNum; } set { _mDeviceNum = value; OnPropertyChanged(); } }


+ 17
- 6
BPASmartClient.JXJFoodSmallStation/Model/RawMaterial/DeviceInquire.cs Переглянути файл

@@ -43,12 +43,14 @@ namespace BPASmartClient.JXJFoodSmallStation.Model
{
TopDeviceCurrentStatuses.ElementAt(TopIndex).Weight = DeviceLists.ElementAt(i).Value.deviceStatus.WeightFeedback;
TopDeviceCurrentStatuses.ElementAt(TopIndex).DeviceNum = DeviceLists.ElementAt(i).Value.deviceStatus.DeviceNum;
TopDeviceCurrentStatuses.ElementAt(TopIndex).RunStatus = DeviceLists.ElementAt(i).Value.deviceStatus.RunStatus;
}

if (BottomIndex >= 0 && BottomIndex < BottomDeviceCurrentStatuses.Count)
{
BottomDeviceCurrentStatuses.ElementAt(BottomIndex).Weight = DeviceLists.ElementAt(i).Value.deviceStatus.WeightFeedback;
BottomDeviceCurrentStatuses.ElementAt(BottomIndex).DeviceNum = DeviceLists.ElementAt(i).Value.deviceStatus.DeviceNum;
BottomDeviceCurrentStatuses.ElementAt(BottomIndex).RunStatus = DeviceLists.ElementAt(i).Value.deviceStatus.RunStatus;
}

int deviceIndex = Array.FindIndex(devices.ToArray(), p => p.IpAddress == DeviceLists.ElementAt(i).Key && p.DeviceName != DeviceLists.ElementAt(i).Value.DeviceName);
@@ -68,7 +70,9 @@ namespace BPASmartClient.JXJFoodSmallStation.Model
{
DeviceName = $"测试设备{i + 1}",
DeviceNum = i + 1,
RunStatus = 1,
Weight = new Random().Next(100, 10000) / 100.0
});

devices.Add(new Devices()
@@ -84,6 +88,7 @@ namespace BPASmartClient.JXJFoodSmallStation.Model
{
DeviceName = $"测试设备{i + 1}",
DeviceNum = i + 1,
RunStatus = 1,
Weight = new Random().Next(100, 10000) / 100.0
});

@@ -293,7 +298,6 @@ namespace BPASmartClient.JXJFoodSmallStation.Model
{
this.DeviceName = DeviceName;
AlarmHelper<AlarmInfo>.Init();
AlarmHelper<AlarmInfo>.Alarm.EStop1 = true;
if (modbusTcp.Connected)
{
ThreadManage.GetInstance().StartLong(new Action(() =>
@@ -310,7 +314,7 @@ namespace BPASmartClient.JXJFoodSmallStation.Model
deviceStatus.DeviceNum = (ushort)this.modbusTcp.ReadShort(DeviceAddress.DeviceNum);//获取设备编号
deviceStatus.DeviceAlarmCode = (ushort)this.modbusTcp.ReadShort(DeviceAddress.DeviceAlarmCode);//获取设备故障编码

//AlarmHelper<AlarmInfo>.Alarm.EStop1 = deviceStatus.DeviceAlarmCode.Get16bitValue(1);
AlarmHelper<AlarmInfo>.Alarm.EStop1 = deviceStatus.DeviceAlarmCode.Get16bitValue(1);
AlarmHelper<AlarmInfo>.Alarm.Servo = deviceStatus.DeviceAlarmCode.Get16bitValue(2);
AlarmHelper<AlarmInfo>.Alarm.Inverter = deviceStatus.DeviceAlarmCode.Get16bitValue(3);
AlarmHelper<AlarmInfo>.Alarm.EStop2 = deviceStatus.DeviceAlarmCode.Get16bitValue(7);
@@ -328,9 +332,9 @@ namespace BPASmartClient.JXJFoodSmallStation.Model
this.modbusTcp.SetString(DeviceAddress.DeviceName, name);
}

public void StatusReset()
public string StatusReset()
{
this.modbusTcp.Write(DeviceAddress.FinfishStatus, (ushort)1);
return this.modbusTcp.Write(DeviceAddress.FinfishStatus, (ushort)1);
//var res = modbusTcp.Read(DeviceAddress.RunStatus);
}

@@ -344,8 +348,15 @@ namespace BPASmartClient.JXJFoodSmallStation.Model
if (modbusTcp.Connected)
{
modbusTcp.SetReal(DeviceAddress.WeightSet, Value);//写入配方量
modbusTcp.Write(DeviceAddress.Start, (ushort)1);//设备启动写入
MessageLog.GetInstance.ShowRunLog($"开始配料");
string returnValue = modbusTcp.Write(DeviceAddress.Start, (ushort)1);//设备启动写入
if (returnValue.Substring(0, 2) == "成功")
{
MessageLog.GetInstance.ShowRunLog("发送成功" + returnValue);
}
else
{
MessageLog.GetInstance.ShowRunLog("发送失败" + returnValue);
}
//配料设备参数写入
var res = Json<DevicePar>.Data.deviceParModels.FirstOrDefault(p => p.MaterialName == DeviceName);
if (res != null)


+ 34
- 6
BPASmartClient.JXJFoodSmallStation/View/HardwareStatusView.xaml Переглянути файл

@@ -62,7 +62,7 @@

<StackPanel
Grid.Row="1"
Margin="0,25,0,0"
Margin="0,10,0,0"
HorizontalAlignment="Center"
Orientation="Horizontal">
<TextBlock
@@ -76,10 +76,9 @@
Text=" kg" />
</StackPanel>


<StackPanel
Grid.Row="1"
Margin="0,70,0,0"
Margin="0,40,0,0"
HorizontalAlignment="Center"
Orientation="Horizontal">
<TextBlock
@@ -92,6 +91,22 @@
Foreground="#FF0084FF"
Text=" 号仓" />
</StackPanel>
<StackPanel
Grid.Row="1"
Margin="0,70,0,0"
HorizontalAlignment="Center"
Orientation="Horizontal">
<TextBlock
FontSize="20"
Foreground="#FF0084FF"
Text="运行状态:" />
<TextBlock
FontSize="20"
Foreground="#FF0084FF"
Text="{Binding RunStatus}" />

</StackPanel>

<Image
Grid.RowSpan="2"
@@ -157,7 +172,7 @@

<StackPanel
Grid.Row="1"
Margin="0,25,0,0"
Margin="0,10,0,0"
HorizontalAlignment="Center"
Orientation="Horizontal">
<TextBlock
@@ -174,7 +189,7 @@

<StackPanel
Grid.Row="1"
Margin="0,70,0,0"
Margin="0,40,0,0"
HorizontalAlignment="Center"
Orientation="Horizontal">
<TextBlock
@@ -187,7 +202,20 @@
Foreground="#FF0084FF"
Text=" 号仓" />
</StackPanel>

<StackPanel
Grid.Row="1"
Margin="0,70,0,0"
HorizontalAlignment="Center"
Orientation="Horizontal">
<TextBlock
FontSize="20"
Foreground="#FF0084FF"
Text="运行状态:" />
<TextBlock
FontSize="20"
Foreground="#FF0084FF"
Text="{Binding RunStatus}" />
</StackPanel>
<Image
Grid.RowSpan="2"
Source="/BPASmartClient.CustomResource;component/Image/光柱.png"


+ 8
- 1
BPASmartClient.JXJFoodSmallStation/ViewModel/RecipeReceiveViewModel.cs Переглянути файл

@@ -76,9 +76,16 @@ namespace BPASmartClient.JXJFoodSmallStation.ViewModel
if (o != null && o is string cnt)
{
var res = Json<LocalRecipeDataColl>.Data.Recipes.FirstOrDefault(p => p.RecipeCode == cnt);
if (res != null)
var res1 = Json<RemoteRecipeDataColl>.Data.Recipes.FirstOrDefault(p => p.RecipeCode == cnt);
if (res1 != null)
{
NoticeDemoViewModel.OpenMsg(EnumPromptType.Error, App.MainWindow, "错误", $"远程已经存在该配方!");
return;
}
if (res != null && res1 ==null)
{
ActionManage.GetInstance.Send("LocalSimulationRecipeIssue", res);
NoticeDemoViewModel.OpenMsg(EnumPromptType.Success, App.MainWindow, "提示", $"{res.RecipeName}配方下发成功!");
MessageLog.GetInstance.ShowUserLog($"下发本地模拟配方——{res.RecipeName}");
}
}


+ 4
- 0
BPASmartClient.JXJFoodSmallStation/ViewModel/SiemensRecipeReceiveViewModel.cs Переглянути файл

@@ -44,6 +44,10 @@ namespace BPASmartClient.JXJFoodSmallStation.ViewModel
}
}
});
ClearAllRecipe = new RelayCommand(() =>
{
Json<RemoteRecipeDataColl>.Data.Recipes.Clear();
});
}
public RelayCommand<object> DetailsCommand { get; set; }
public RelayCommand ClearAllRecipe { get; set; }


+ 12
- 4
BPASmartClient.MilkWithTea/App.xaml Переглянути файл

@@ -424,7 +424,7 @@
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBoxItem">
<Border Name="Back" Background="Transparent" BorderThickness="0,0,0,0" BorderBrush="#81D779" >
<Border Name="Back" Background="Transparent" BorderThickness="0,0,0,0" BorderBrush="#81D779" Height="{TemplateBinding Height}" >
<ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Left" Margin="5,0,0,0"></ContentPresenter>
</Border>
<ControlTemplate.Triggers>
@@ -444,13 +444,13 @@
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBox}">
<Border BorderThickness="1" BorderBrush="#CDC9C9 " CornerRadius="3" Width="{TemplateBinding Width}" Height="30" Background="{TemplateBinding Background}" >
<Grid >
<Border BorderThickness="1" BorderBrush="#CDC9C9 " CornerRadius="3" Height="{TemplateBinding Height}" Width="{TemplateBinding Width}" Background="{TemplateBinding Background}" >
<Grid Height="{TemplateBinding Height}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0" x:Name="grid">
<Grid Grid.Column="0" x:Name="grid" >
<ToggleButton
Width="{Binding ElementName=grid,Path=ActualWidth}"
Height="{Binding ElementName=grid, Path=ActualHeight}"
@@ -672,5 +672,13 @@
</DoubleAnimationUsingKeyFrames>
</Storyboard>

<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="18"/>
<Setter Property="Foreground" Value="DarkSlateGray"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="FontSize" Value="18"/>
</Style>

</Application.Resources>
</Application>

+ 19
- 8
BPASmartClient.MilkWithTea/App.xaml.cs Переглянути файл

@@ -1,11 +1,22 @@
using BPASmartClient.Helper;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
global using BPA.Message;
global using BPA.Message.Enum;
global using BPASmartClient.Device;
global using BPASmartClient.EventBus;
global using BPASmartClient.Helper;
global using BPASmartClient.MilkWithTea.Model;
global using BPASmartClient.Model;
global using BPASmartClient.MorkMOC;
global using System;
global using System.Collections.Generic;
global using System.Collections.ObjectModel;
global using System.Linq;
global using System.Text;
global using System.Threading.Tasks;
global using System.Windows;
global using System.Configuration;
global using System.Data;



namespace BPASmartClient.MilkWithTea
{


+ 6
- 1
BPASmartClient.MilkWithTea/BPASmartClient.MilkWithTea.csproj Переглянути файл

@@ -23,14 +23,19 @@
</EmbeddedResource>
</ItemGroup>

<ItemGroup>
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.0.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\BPASmartClient.Business\BPASmartClient.Business.csproj" />
<ProjectReference Include="..\BPASmartClient.CustomResource\BPASmartClient.CustomResource.csproj" />
<ProjectReference Include="..\BPASmartClient.EventBus\BPASmartClient.EventBus.csproj" />
<ProjectReference Include="..\BPASmartClient.Helper\BPASmartClient.Helper.csproj" />
<ProjectReference Include="..\BPASmartClient.IoT\BPASmartClient.IoT.csproj" />
<ProjectReference Include="..\BPASmartClient.Model\BPASmartClient.Model.csproj" />
<ProjectReference Include="..\BPASmartClient.MorkMOC\BPASmartClient.MorkMOC.csproj" />
<ProjectReference Include="..\BPASmartClient.MORKSM.BK.PLC\BPASmartClient.PLC.csproj" />
<ProjectReference Include="..\BPASmartClient.MorkTM\BPASmartClient.MorkTM.csproj" />
<ProjectReference Include="..\BPASmartClient.ViewModel\BPASmartClient.ViewModel.csproj" />
</ItemGroup>



+ 30
- 0
BPASmartClient.MilkWithTea/Control/ContextMenuToggleButton.cs Переглянути файл

@@ -0,0 +1,30 @@
using System.Windows.Controls;
using System.Windows.Controls.Primitives;


namespace BPASmartClient.MilkWithTea.Control;

/// <summary>
/// 带上下文菜单的切换按钮
/// </summary>
public class ContextMenuToggleButton : ToggleButton
{
public ContextMenu Menu { get; set; }

protected override void OnClick()
{
base.OnClick();
if (Menu != null)
{
if (IsChecked == true)
{
Menu.PlacementTarget = this;
Menu.IsOpen = true;
}
else
{
Menu.IsOpen = false;
}
}
}
}

+ 225
- 0
BPASmartClient.MilkWithTea/Control/ScrollViewer.cs Переглянути файл

@@ -0,0 +1,225 @@
using BPASmartClient.MilkWithTea.Data;
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;

namespace BPASmartClient.MilkWithTea.Control;

public class ScrollViewer : System.Windows.Controls.ScrollViewer
{
private double _totalVerticalOffset;

private double _totalHorizontalOffset;

private bool _isRunning;

/// <summary>
/// 是否响应鼠标滚轮操作
/// </summary>
public static readonly DependencyProperty CanMouseWheelProperty = DependencyProperty.Register(
"CanMouseWheel", typeof(bool), typeof(ScrollViewer), new PropertyMetadata(ValueBoxes.TrueBox));

/// <summary>
/// 是否响应鼠标滚轮操作
/// </summary>
public bool CanMouseWheel
{
get => (bool) GetValue(CanMouseWheelProperty);
set => SetValue(CanMouseWheelProperty, ValueBoxes.BooleanBox(value));
}

protected override void OnMouseWheel(MouseWheelEventArgs e)
{
if (!CanMouseWheel) return;

if (!IsInertiaEnabled)
{
if (ScrollViewerAttach.GetOrientation(this) == Orientation.Vertical)
{
base.OnMouseWheel(e);
}
else
{
_totalHorizontalOffset = HorizontalOffset;
CurrentHorizontalOffset = HorizontalOffset;
_totalHorizontalOffset = Math.Min(Math.Max(0, _totalHorizontalOffset - e.Delta), ScrollableWidth);
CurrentHorizontalOffset = _totalHorizontalOffset;
}
return;
}
e.Handled = true;

if (ScrollViewerAttach.GetOrientation(this) == Orientation.Vertical)
{
if (!_isRunning)
{
_totalVerticalOffset = VerticalOffset;
CurrentVerticalOffset = VerticalOffset;
}
_totalVerticalOffset = Math.Min(Math.Max(0, _totalVerticalOffset - e.Delta), ScrollableHeight);
ScrollToVerticalOffsetWithAnimation(_totalVerticalOffset);
}
else
{
if (!_isRunning)
{
_totalHorizontalOffset = HorizontalOffset;
CurrentHorizontalOffset = HorizontalOffset;
}
_totalHorizontalOffset = Math.Min(Math.Max(0, _totalHorizontalOffset - e.Delta), ScrollableWidth);
ScrollToHorizontalOffsetWithAnimation(_totalHorizontalOffset);
}
}

internal void ScrollToTopInternal(double milliseconds = 500)
{
if (!_isRunning)
{
_totalVerticalOffset = VerticalOffset;
CurrentVerticalOffset = VerticalOffset;
}
ScrollToVerticalOffsetWithAnimation(0, milliseconds);
}

public void ScrollToVerticalOffsetWithAnimation(double offset, double milliseconds = 500)
{
var animation = CreateAnimation(offset, milliseconds);
animation.EasingFunction = new CubicEase
{
EasingMode = EasingMode.EaseOut
};
animation.FillBehavior = FillBehavior.Stop;
animation.Completed += (s, e1) =>
{
CurrentVerticalOffset = offset;
_isRunning = false;
};
_isRunning = true;

BeginAnimation(CurrentVerticalOffsetProperty, animation, HandoffBehavior.Compose);
}

public void ScrollToHorizontalOffsetWithAnimation(double offset, double milliseconds = 500)
{
var animation = CreateAnimation(offset, milliseconds);
animation.EasingFunction = new CubicEase
{
EasingMode = EasingMode.EaseOut
};
animation.FillBehavior = FillBehavior.Stop;
animation.Completed += (s, e1) =>
{
CurrentHorizontalOffset = offset;
_isRunning = false;
};
_isRunning = true;

BeginAnimation(CurrentHorizontalOffsetProperty, animation, HandoffBehavior.Compose);
}

protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters) =>
IsPenetrating ? null : base.HitTestCore(hitTestParameters);

/// <summary>
/// 是否支持惯性
/// </summary>
public static readonly DependencyProperty IsInertiaEnabledProperty = DependencyProperty.RegisterAttached(
"IsInertiaEnabled", typeof(bool), typeof(ScrollViewer), new PropertyMetadata(ValueBoxes.FalseBox));

public static void SetIsInertiaEnabled(DependencyObject element, bool value) => element.SetValue(IsInertiaEnabledProperty, ValueBoxes.BooleanBox(value));

public static bool GetIsInertiaEnabled(DependencyObject element) => (bool) element.GetValue(IsInertiaEnabledProperty);

/// <summary>
/// 是否支持惯性
/// </summary>
public bool IsInertiaEnabled
{
get => (bool) GetValue(IsInertiaEnabledProperty);
set => SetValue(IsInertiaEnabledProperty, ValueBoxes.BooleanBox(value));
}

/// <summary>
/// 控件是否可以穿透点击
/// </summary>
public static readonly DependencyProperty IsPenetratingProperty = DependencyProperty.RegisterAttached(
"IsPenetrating", typeof(bool), typeof(ScrollViewer), new PropertyMetadata(ValueBoxes.FalseBox));

/// <summary>
/// 控件是否可以穿透点击
/// </summary>
public bool IsPenetrating
{
get => (bool) GetValue(IsPenetratingProperty);
set => SetValue(IsPenetratingProperty, ValueBoxes.BooleanBox(value));
}

public static void SetIsPenetrating(DependencyObject element, bool value) => element.SetValue(IsPenetratingProperty, ValueBoxes.BooleanBox(value));

public static bool GetIsPenetrating(DependencyObject element) => (bool) element.GetValue(IsPenetratingProperty);

/// <summary>
/// 当前垂直滚动偏移
/// </summary>
internal static readonly DependencyProperty CurrentVerticalOffsetProperty = DependencyProperty.Register(
"CurrentVerticalOffset", typeof(double), typeof(ScrollViewer), new PropertyMetadata(ValueBoxes.Double0Box, OnCurrentVerticalOffsetChanged));

private static void OnCurrentVerticalOffsetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is ScrollViewer ctl && e.NewValue is double v)
{
ctl.ScrollToVerticalOffset(v);
}
}

/// <summary>
/// 当前垂直滚动偏移
/// </summary>
internal double CurrentVerticalOffset
{
// ReSharper disable once UnusedMember.Local
get => (double) GetValue(CurrentVerticalOffsetProperty);
set => SetValue(CurrentVerticalOffsetProperty, value);
}

/// <summary>
/// 当前水平滚动偏移
/// </summary>
internal static readonly DependencyProperty CurrentHorizontalOffsetProperty = DependencyProperty.Register(
"CurrentHorizontalOffset", typeof(double), typeof(ScrollViewer), new PropertyMetadata(ValueBoxes.Double0Box, OnCurrentHorizontalOffsetChanged));

private static void OnCurrentHorizontalOffsetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is ScrollViewer ctl && e.NewValue is double v)
{
ctl.ScrollToHorizontalOffset(v);
}
}

/// <summary>
/// 当前水平滚动偏移
/// </summary>
internal double CurrentHorizontalOffset
{
get => (double) GetValue(CurrentHorizontalOffsetProperty);
set => SetValue(CurrentHorizontalOffsetProperty, value);
}


/// <summary>
/// 创建一个Double动画
/// </summary>
/// <param name="toValue"></param>
/// <param name="milliseconds"></param>
/// <returns></returns>
public DoubleAnimation CreateAnimation(double toValue, double milliseconds = 200)
{
return new(toValue, new Duration(TimeSpan.FromMilliseconds(milliseconds)))
{
EasingFunction = new PowerEase { EasingMode = EasingMode.EaseInOut }
};
}
}

+ 111
- 0
BPASmartClient.MilkWithTea/Control/ScrollViewerAttach.cs Переглянути файл

@@ -0,0 +1,111 @@
using BPASmartClient.MilkWithTea.Data;
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace BPASmartClient.MilkWithTea.Control;

public class ScrollViewerAttach
{
public static readonly DependencyProperty AutoHideProperty = DependencyProperty.RegisterAttached(
"AutoHide", typeof(bool), typeof(ScrollViewerAttach), new FrameworkPropertyMetadata(ValueBoxes.TrueBox, FrameworkPropertyMetadataOptions.Inherits));

public static void SetAutoHide(DependencyObject element, bool value)
=> element.SetValue(AutoHideProperty, ValueBoxes.BooleanBox(value));

public static bool GetAutoHide(DependencyObject element)
=> (bool) element.GetValue(AutoHideProperty);

public static readonly DependencyProperty OrientationProperty = DependencyProperty.RegisterAttached(
"Orientation", typeof(Orientation), typeof(ScrollViewerAttach), new FrameworkPropertyMetadata(ValueBoxes.VerticalBox, FrameworkPropertyMetadataOptions.Inherits, OnOrientationChanged));

private static void OnOrientationChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is ScrollViewer)
{
return;
}

if (d is System.Windows.Controls.ScrollViewer scrollViewer)
{
if ((Orientation) e.NewValue == Orientation.Horizontal)
{
scrollViewer.PreviewMouseWheel += ScrollViewerPreviewMouseWheel;
}
else
{
scrollViewer.PreviewMouseWheel -= ScrollViewerPreviewMouseWheel;
}
}

void ScrollViewerPreviewMouseWheel(object sender, MouseWheelEventArgs args)
{
var scrollViewerNative = (System.Windows.Controls.ScrollViewer) sender;
scrollViewerNative.ScrollToHorizontalOffset(Math.Min(Math.Max(0, scrollViewerNative.HorizontalOffset - args.Delta), scrollViewerNative.ScrollableWidth));

args.Handled = true;
}
}

public static void SetOrientation(DependencyObject element, Orientation value)
=> element.SetValue(OrientationProperty, ValueBoxes.OrientationBox(value));

public static Orientation GetOrientation(DependencyObject element)
=> (Orientation) element.GetValue(OrientationProperty);

public static readonly DependencyProperty IsDisabledProperty = DependencyProperty.RegisterAttached(
"IsDisabled", typeof(bool), typeof(ScrollViewerAttach), new PropertyMetadata(ValueBoxes.FalseBox, OnIsDisabledChanged));

private static void OnIsDisabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is UIElement element)
{
if ((bool) e.NewValue)
{
element.PreviewMouseWheel += ScrollViewerPreviewMouseWheel;
}
else
{
element.PreviewMouseWheel -= ScrollViewerPreviewMouseWheel;
}
}

void ScrollViewerPreviewMouseWheel(object sender, MouseWheelEventArgs args)
{
if (args.Handled)
{
return;
}

args.Handled = true;

if (GetParent<System.Windows.Controls.ScrollViewer>((UIElement) sender) is { } scrollViewer)
{
scrollViewer.RaiseEvent(new MouseWheelEventArgs(args.MouseDevice, args.Timestamp, args.Delta)
{
RoutedEvent = UIElement.MouseWheelEvent,
Source = sender
});
}
}

static T GetParent<T>(DependencyObject d) where T : DependencyObject =>
d switch
{
null => default,
T t => t,
Window _ => null,
_ => GetParent<T>(VisualTreeHelper.GetParent(d))
};
}

public static void SetIsDisabled(DependencyObject element, bool value)
=> element.SetValue(IsDisabledProperty, ValueBoxes.BooleanBox(value));

public static bool GetIsDisabled(DependencyObject element)
=> (bool) element.GetValue(IsDisabledProperty);

}

+ 426
- 0
BPASmartClient.MilkWithTea/Control/TabControl.cs Переглянути файл

@@ -0,0 +1,426 @@
using BPASmartClient.MilkWithTea.Data;
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;

namespace BPASmartClient.MilkWithTea.Control;

[TemplatePart(Name = HeaderPanelKey, Type = typeof(TabPanel))]
[TemplatePart(Name = OverflowScrollviewer, Type = typeof(ScrollViewer))]
[TemplatePart(Name = ScrollButtonLeft, Type = typeof(ButtonBase))]
[TemplatePart(Name = ScrollButtonRight, Type = typeof(ButtonBase))]
[TemplatePart(Name = HeaderBorder, Type = typeof(Border))]
public class TabControl : System.Windows.Controls.TabControl
{
private const string OverflowButtonKey = "PART_OverflowButton";

private const string HeaderPanelKey = "PART_HeaderPanel";

private const string OverflowScrollviewer = "PART_OverflowScrollviewer";

private const string ScrollButtonLeft = "PART_ScrollButtonLeft";

private const string ScrollButtonRight = "PART_ScrollButtonRight";

private const string HeaderBorder = "PART_HeaderBorder";

private ContextMenuToggleButton _buttonOverflow;

internal TabPanel HeaderPanel { get; private set; }

private ScrollViewer _scrollViewerOverflow;

private ButtonBase _buttonScrollLeft;

private ButtonBase _buttonScrollRight;

private Border _headerBorder;

/// <summary>
/// 是否为内部操作
/// </summary>
internal bool IsInternalAction;

/// <summary>
/// 是否启用动画
/// </summary>
public static readonly DependencyProperty IsAnimationEnabledProperty = DependencyProperty.Register(
"IsAnimationEnabled", typeof(bool), typeof(TabControl), new PropertyMetadata(ValueBoxes.FalseBox));

/// <summary>
/// 是否启用动画
/// </summary>
public bool IsAnimationEnabled
{
get => (bool) GetValue(IsAnimationEnabledProperty);
set => SetValue(IsAnimationEnabledProperty, ValueBoxes.BooleanBox(value));
}

/// <summary>
/// 是否可以拖动
/// </summary>
public static readonly DependencyProperty IsDraggableProperty = DependencyProperty.Register(
"IsDraggable", typeof(bool), typeof(TabControl), new PropertyMetadata(ValueBoxes.FalseBox));

/// <summary>
/// 是否可以拖动
/// </summary>
public bool IsDraggable
{
get => (bool) GetValue(IsDraggableProperty);
set => SetValue(IsDraggableProperty, ValueBoxes.BooleanBox(value));
}

/// <summary>
/// 是否显示关闭按钮
/// </summary>
public static readonly DependencyProperty ShowCloseButtonProperty = DependencyProperty.RegisterAttached(
"ShowCloseButton", typeof(bool), typeof(TabControl), new FrameworkPropertyMetadata(ValueBoxes.FalseBox, FrameworkPropertyMetadataOptions.Inherits));

public static void SetShowCloseButton(DependencyObject element, bool value)
=> element.SetValue(ShowCloseButtonProperty, ValueBoxes.BooleanBox(value));

public static bool GetShowCloseButton(DependencyObject element)
=> (bool) element.GetValue(ShowCloseButtonProperty);

/// <summary>
/// 是否显示关闭按钮
/// </summary>
public bool ShowCloseButton
{
get => (bool) GetValue(ShowCloseButtonProperty);
set => SetValue(ShowCloseButtonProperty, ValueBoxes.BooleanBox(value));
}

/// <summary>
/// 是否显示上下文菜单
/// </summary>
public static readonly DependencyProperty ShowContextMenuProperty = DependencyProperty.RegisterAttached(
"ShowContextMenu", typeof(bool), typeof(TabControl), new FrameworkPropertyMetadata(ValueBoxes.TrueBox, FrameworkPropertyMetadataOptions.Inherits));

public static void SetShowContextMenu(DependencyObject element, bool value)
=> element.SetValue(ShowContextMenuProperty, ValueBoxes.BooleanBox(value));

public static bool GetShowContextMenu(DependencyObject element)
=> (bool) element.GetValue(ShowContextMenuProperty);

/// <summary>
/// 是否显示上下文菜单
/// </summary>
public bool ShowContextMenu
{
get => (bool) GetValue(ShowContextMenuProperty);
set => SetValue(ShowContextMenuProperty, ValueBoxes.BooleanBox(value));
}

/// <summary>
/// 是否将标签填充
/// </summary>
public static readonly DependencyProperty IsTabFillEnabledProperty = DependencyProperty.Register(
"IsTabFillEnabled", typeof(bool), typeof(TabControl), new PropertyMetadata(ValueBoxes.FalseBox));

/// <summary>
/// 是否将标签填充
/// </summary>
public bool IsTabFillEnabled
{
get => (bool) GetValue(IsTabFillEnabledProperty);
set => SetValue(IsTabFillEnabledProperty, ValueBoxes.BooleanBox(value));
}

/// <summary>
/// 标签宽度
/// </summary>
public static readonly DependencyProperty TabItemWidthProperty = DependencyProperty.Register(
"TabItemWidth", typeof(double), typeof(TabControl), new PropertyMetadata(200.0));

/// <summary>
/// 标签宽度
/// </summary>
public double TabItemWidth
{
get => (double) GetValue(TabItemWidthProperty);
set => SetValue(TabItemWidthProperty, value);
}

/// <summary>
/// 标签高度
/// </summary>
public static readonly DependencyProperty TabItemHeightProperty = DependencyProperty.Register(
"TabItemHeight", typeof(double), typeof(TabControl), new PropertyMetadata(30.0));

/// <summary>
/// 标签高度
/// </summary>
public double TabItemHeight
{
get => (double) GetValue(TabItemHeightProperty);
set => SetValue(TabItemHeightProperty, value);
}

/// <summary>
/// 是否可以滚动
/// </summary>
public static readonly DependencyProperty IsScrollableProperty = DependencyProperty.Register(
"IsScrollable", typeof(bool), typeof(TabControl), new PropertyMetadata(ValueBoxes.FalseBox));

/// <summary>
/// 是否可以滚动
/// </summary>
public bool IsScrollable
{
get => (bool) GetValue(IsScrollableProperty);
set => SetValue(IsScrollableProperty, ValueBoxes.BooleanBox(value));
}

/// <summary>
/// 是否显示溢出按钮
/// </summary>
public static readonly DependencyProperty ShowOverflowButtonProperty = DependencyProperty.Register(
"ShowOverflowButton", typeof(bool), typeof(TabControl), new PropertyMetadata(ValueBoxes.TrueBox));

/// <summary>
/// 是否显示溢出按钮
/// </summary>
public bool ShowOverflowButton
{
get => (bool) GetValue(ShowOverflowButtonProperty);
set => SetValue(ShowOverflowButtonProperty, ValueBoxes.BooleanBox(value));
}

/// <summary>
/// 是否显示滚动按钮
/// </summary>
public static readonly DependencyProperty ShowScrollButtonProperty = DependencyProperty.Register(
"ShowScrollButton", typeof(bool), typeof(TabControl), new PropertyMetadata(ValueBoxes.FalseBox));

/// <summary>
/// 是否显示滚动按钮
/// </summary>
public bool ShowScrollButton
{
get => (bool) GetValue(ShowScrollButtonProperty);
set => SetValue(ShowScrollButtonProperty, ValueBoxes.BooleanBox(value));
}

/// <summary>
/// 可见的标签数量
/// </summary>
private int _itemShowCount;

protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e)
{
base.OnItemsChanged(e);

if (HeaderPanel == null)
{
IsInternalAction = false;
return;
}

UpdateOverflowButton();

if (IsInternalAction)
{
IsInternalAction = false;
return;
}

if (e.Action == NotifyCollectionChangedAction.Add)
{
for (var i = 0; i < Items.Count; i++)
{
if (ItemContainerGenerator.ContainerFromIndex(i) is not TabItem item) return;
item.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
item.TabPanel = HeaderPanel;
}
}

_headerBorder?.InvalidateMeasure();
IsInternalAction = false;
}

public override void OnApplyTemplate()
{
if (_buttonOverflow != null)
{
if (_buttonOverflow.Menu != null)
{
_buttonOverflow.Menu.Closed -= Menu_Closed;
_buttonOverflow.Menu = null;
}

_buttonOverflow.Click -= ButtonOverflow_Click;
}

if (_buttonScrollLeft != null) _buttonScrollLeft.Click -= ButtonScrollLeft_Click;
if (_buttonScrollRight != null) _buttonScrollRight.Click -= ButtonScrollRight_Click;

base.OnApplyTemplate();
HeaderPanel = GetTemplateChild(HeaderPanelKey) as TabPanel;

if (IsTabFillEnabled) return;

_buttonOverflow = GetTemplateChild(OverflowButtonKey) as ContextMenuToggleButton;
_scrollViewerOverflow = GetTemplateChild(OverflowScrollviewer) as ScrollViewer;
_buttonScrollLeft = GetTemplateChild(ScrollButtonLeft) as ButtonBase;
_buttonScrollRight = GetTemplateChild(ScrollButtonRight) as ButtonBase;
_headerBorder = GetTemplateChild(HeaderBorder) as Border;

if (_buttonScrollLeft != null) _buttonScrollLeft.Click += ButtonScrollLeft_Click;
if (_buttonScrollRight != null) _buttonScrollRight.Click += ButtonScrollRight_Click;

if (_buttonOverflow != null)
{
var menu = new ContextMenu
{
Placement = PlacementMode.Bottom,
PlacementTarget = _buttonOverflow
};
menu.Closed += Menu_Closed;
_buttonOverflow.Menu = menu;
_buttonOverflow.Click += ButtonOverflow_Click;
}
}

protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
{
base.OnRenderSizeChanged(sizeInfo);
UpdateOverflowButton();
}

private void UpdateOverflowButton()
{
if (!IsTabFillEnabled)
{
_itemShowCount = (int) (ActualWidth / TabItemWidth);
//_buttonOverflow?.Show(ShowOverflowButton && Items.Count > 0 && Items.Count >= _itemShowCount);
}
}

private void Menu_Closed(object sender, RoutedEventArgs e) => _buttonOverflow.IsChecked = false;

private void ButtonScrollRight_Click(object sender, RoutedEventArgs e) =>
_scrollViewerOverflow.ScrollToHorizontalOffsetWithAnimation(Math.Min(
_scrollViewerOverflow.CurrentHorizontalOffset + TabItemWidth, _scrollViewerOverflow.ScrollableWidth));

private void ButtonScrollLeft_Click(object sender, RoutedEventArgs e) =>
_scrollViewerOverflow.ScrollToHorizontalOffsetWithAnimation(Math.Max(
_scrollViewerOverflow.CurrentHorizontalOffset - TabItemWidth, 0));

private void ButtonOverflow_Click(object sender, RoutedEventArgs e)
{
if (_buttonOverflow.IsChecked == true)
{
_buttonOverflow.Menu.Items.Clear();
for (var i = 0; i < Items.Count; i++)
{
if (ItemContainerGenerator.ContainerFromIndex(i) is not TabItem item) continue;

var menuItem = new MenuItem
{
HeaderStringFormat = ItemStringFormat,
HeaderTemplate = ItemTemplate,
HeaderTemplateSelector = ItemTemplateSelector,
Header = item.Header,
Width = TabItemWidth,
IsChecked = item.IsSelected,
IsCheckable = true,
IsEnabled = item.IsEnabled
};

menuItem.Click += delegate
{
_buttonOverflow.IsChecked = false;

var list = GetActualList();
if (list == null) return;

var actualItem = ItemContainerGenerator.ItemFromContainer(item);
if (actualItem == null) return;

var index = list.IndexOf(actualItem);
if (index >= _itemShowCount)
{
list.Remove(actualItem);
list.Insert(0, actualItem);
HeaderPanel.SetValue(TabPanel.FluidMoveDurationPropertyKey,
IsAnimationEnabled
? new Duration(TimeSpan.FromMilliseconds(200))
: new Duration(TimeSpan.FromMilliseconds(0)));
HeaderPanel.ForceUpdate = true;
HeaderPanel.Measure(new Size(HeaderPanel.DesiredSize.Width, ActualHeight));
HeaderPanel.ForceUpdate = false;
SetCurrentValue(SelectedIndexProperty, ValueBoxes.Int0Box);
}

item.IsSelected = true;
};
_buttonOverflow.Menu.Items.Add(menuItem);
}
}
}

internal double GetHorizontalOffset() => _scrollViewerOverflow?.CurrentHorizontalOffset ?? 0;

internal void UpdateScroll() => _scrollViewerOverflow?.RaiseEvent(new MouseWheelEventArgs(Mouse.PrimaryDevice, Environment.TickCount, 0)
{
RoutedEvent = MouseWheelEvent
});

internal void CloseAllItems() => CloseOtherItems(null);

internal void CloseOtherItems(TabItem currentItem)
{
var actualItem = currentItem != null ? ItemContainerGenerator.ItemFromContainer(currentItem) : null;

var list = GetActualList();
if (list == null) return;

IsInternalAction = true;

for (var i = 0; i < Items.Count; i++)
{
var item = list[i];
if (!Equals(item, actualItem) && item != null)
{
var argsClosing = new CancelRoutedEventArgs(TabItem.ClosingEvent, item);

if (ItemContainerGenerator.ContainerFromItem(item) is not TabItem tabItem) continue;

tabItem.RaiseEvent(argsClosing);
if (argsClosing.Cancel) return;

tabItem.RaiseEvent(new RoutedEventArgs(TabItem.ClosedEvent, item));
list.Remove(item);

i--;
}
}

SetCurrentValue(SelectedIndexProperty, Items.Count == 0 ? -1 : 0);
}

internal IList GetActualList()
{
IList list;
if (ItemsSource != null)
{
list = ItemsSource as IList;
}
else
{
list = Items;
}

return list;
}

protected override bool IsItemItsOwnContainerOverride(object item) => item is TabItem;

protected override DependencyObject GetContainerForItemOverride() => new TabItem();
}

+ 509
- 0
BPASmartClient.MilkWithTea/Control/TabItem.cs Переглянути файл

@@ -0,0 +1,509 @@
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using BPASmartClient.MilkWithTea.Control;
using BPASmartClient.MilkWithTea.Data;
using TabControl = BPASmartClient.MilkWithTea.Control.TabControl;

namespace BPASmartClient.MilkWithTea.Control;

public class TabItem : System.Windows.Controls.TabItem
{
/// <summary>
/// 动画速度
/// </summary>
private const int AnimationSpeed = 150;

/// <summary>
/// 选项卡是否处于拖动状态
/// </summary>
private static bool ItemIsDragging;

/// <summary>
/// 选项卡是否等待被拖动
/// </summary>
private bool _isWaiting;

/// <summary>
/// 拖动中的选项卡坐标
/// </summary>
private Point _dragPoint;

/// <summary>
/// 鼠标按下时选项卡位置
/// </summary>
private int _mouseDownIndex;

/// <summary>
/// 鼠标按下时选项卡横向偏移
/// </summary>
private double _mouseDownOffsetX;

/// <summary>
/// 鼠标按下时的坐标
/// </summary>
private Point _mouseDownPoint;

/// <summary>
/// 右侧可移动的最大值
/// </summary>
private double _maxMoveRight;

/// <summary>
/// 左侧可移动的最大值
/// </summary>
private double _maxMoveLeft;

/// <summary>
/// 选项卡宽度
/// </summary>
public double ItemWidth { get; internal set; }

/// <summary>
/// 选项卡拖动等待距离(在鼠标移动了超过20个像素无关单位后,选项卡才开始被拖动)
/// </summary>
private const double WaitLength = 20;

/// <summary>
/// 选项卡是否处于拖动状态
/// </summary>
private bool _isDragging;

/// <summary>
/// 选项卡是否已经被拖动
/// </summary>
private bool _isDragged;

/// <summary>
/// 目标横向位移
/// </summary>
internal double TargetOffsetX { get; set; }

/// <summary>
/// 当前编号
/// </summary>
private int _currentIndex;

/// <summary>
/// 标签容器横向滚动距离
/// </summary>
private double _scrollHorizontalOffset;


private TabPanel _tabPanel;


/// <summary>
/// 标签容器
/// </summary>
internal TabPanel TabPanel
{
get
{
if (_tabPanel == null && TabControlParent != null)
{
_tabPanel = TabControlParent.HeaderPanel;
}

return _tabPanel;
}
set => _tabPanel = value;
}

private TabControl TabControlParent => ItemsControl.ItemsControlFromItemContainer(this) as TabControl;


/// <summary>
/// 当前编号
/// </summary>
internal int CurrentIndex
{
get => _currentIndex;
set
{
if (_currentIndex == value || value < 0) return;
var oldIndex = _currentIndex;
_currentIndex = value;
UpdateItemOffsetX(oldIndex);
}
}

/// <summary>
/// 是否显示关闭按钮
/// </summary>
public static readonly DependencyProperty ShowCloseButtonProperty =
TabControl.ShowCloseButtonProperty.AddOwner(typeof(TabItem));

/// <summary>
/// 是否显示关闭按钮
/// </summary>
public bool ShowCloseButton
{
get => (bool) GetValue(ShowCloseButtonProperty);
set => SetValue(ShowCloseButtonProperty, ValueBoxes.BooleanBox(value));
}

public static void SetShowCloseButton(DependencyObject element, bool value)
=> element.SetValue(ShowCloseButtonProperty, ValueBoxes.BooleanBox(value));

public static bool GetShowCloseButton(DependencyObject element)
=> (bool) element.GetValue(ShowCloseButtonProperty);

/// <summary>
/// 是否显示上下文菜单
/// </summary>
public static readonly DependencyProperty ShowContextMenuProperty =
TabControl.ShowContextMenuProperty.AddOwner(typeof(TabItem), new FrameworkPropertyMetadata(OnShowContextMenuChanged));

private static void OnShowContextMenuChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var ctl = (TabItem) d;
if (ctl.Menu != null)
{
var show = (bool) e.NewValue;
ctl.Menu.IsEnabled = show;
//ctl.Menu.Show(show);
}
}

/// <summary>
/// 是否显示上下文菜单
/// </summary>
public bool ShowContextMenu
{
get => (bool) GetValue(ShowContextMenuProperty);
set => SetValue(ShowContextMenuProperty, ValueBoxes.BooleanBox(value));
}

public static void SetShowContextMenu(DependencyObject element, bool value)
=> element.SetValue(ShowContextMenuProperty, ValueBoxes.BooleanBox(value));

public static bool GetShowContextMenu(DependencyObject element)
=> (bool) element.GetValue(ShowContextMenuProperty);

public static readonly DependencyProperty MenuProperty = DependencyProperty.Register(
"Menu", typeof(ContextMenu), typeof(TabItem), new PropertyMetadata(default(ContextMenu), OnMenuChanged));

private static void OnMenuChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var ctl = (TabItem) d;
//ctl.OnMenuChanged(e.NewValue as ContextMenu);
}

//private void OnMenuChanged(ContextMenu menu)
//{
// if (IsLoaded && menu != null)
// {
// var parent = TabControlParent;
// if (parent == null) return;

// var item = parent.ItemContainerGenerator.ItemFromContainer(this);

// menu.DataContext = item;
// menu.SetBinding(IsEnabledProperty, new Binding(ShowContextMenuProperty.Name)
// {
// Source = this
// });
// menu.SetBinding(VisibilityProperty, new Binding(ShowContextMenuProperty.Name)
// {
// Source = this,
// Converter = GetResourceInternal<IValueConverter>(ResourceToken.Boolean2VisibilityConverter)
// });
// }
//}


public ContextMenu Menu
{
get => (ContextMenu) GetValue(MenuProperty);
set => SetValue(MenuProperty, value);
}

/// <summary>
/// 更新选项卡横向偏移
/// </summary>
/// <param name="oldIndex"></param>
private void UpdateItemOffsetX(int oldIndex)
{
if (!_isDragging || CurrentIndex >= TabPanel.ItemDic.Count)
{
return;
}

var moveItem = TabPanel.ItemDic[CurrentIndex];
moveItem.CurrentIndex -= CurrentIndex - oldIndex;
var offsetX = moveItem.TargetOffsetX;
var resultX = offsetX + (oldIndex - CurrentIndex) * ItemWidth;
TabPanel.ItemDic[CurrentIndex] = this;
TabPanel.ItemDic[moveItem.CurrentIndex] = moveItem;
moveItem.CreateAnimation(offsetX, resultX);
}

public TabItem()
{
//CommandBindings.Add(new CommandBinding(ControlCommands.Close, (s, e) => Close()));
//CommandBindings.Add(new CommandBinding(ControlCommands.CloseAll,
// (s, e) => { TabControlParent.CloseAllItems(); }));
//CommandBindings.Add(new CommandBinding(ControlCommands.CloseOther,
// (s, e) => { TabControlParent.CloseOtherItems(this); }));

//Loaded += (s, e) => OnMenuChanged(Menu);
}

protected override void OnMouseRightButtonDown(MouseButtonEventArgs e)
{
base.OnMouseRightButtonDown(e);

if (VisualTreeHelper.HitTest(this, e.GetPosition(this)) == null) return;
IsSelected = true;
Focus();
}

protected override void OnHeaderChanged(object oldHeader, object newHeader)
{
base.OnHeaderChanged(oldHeader, newHeader);

if (TabPanel != null)
{
TabPanel.ForceUpdate = true;
InvalidateMeasure();
TabPanel.ForceUpdate = true;
}
}

internal void Close()
{
var parent = TabControlParent;
if (parent == null) return;

var item = parent.ItemContainerGenerator.ItemFromContainer(this);

var argsClosing = new CancelRoutedEventArgs(ClosingEvent, item);
RaiseEvent(argsClosing);
if (argsClosing.Cancel) return;

TabPanel.SetValue(TabPanel.FluidMoveDurationPropertyKey, parent.IsAnimationEnabled
? new Duration(TimeSpan.FromMilliseconds(200))
: new Duration(TimeSpan.FromMilliseconds(1)));

parent.IsInternalAction = true;
RaiseEvent(new RoutedEventArgs(ClosedEvent, item));

var list = parent.GetActualList();
list?.Remove(item);
}

protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
base.OnMouseLeftButtonDown(e);

if (VisualTreeHelper.HitTest(this, e.GetPosition(this)) == null) return;
var parent = TabControlParent;
if (parent == null) return;

if (parent.IsDraggable && !ItemIsDragging && !_isDragging)
{
parent.UpdateScroll();
TabPanel.SetValue(TabPanel.FluidMoveDurationPropertyKey, new Duration(TimeSpan.FromSeconds(0)));
_mouseDownOffsetX = RenderTransform.Value.OffsetX;
_scrollHorizontalOffset = parent.GetHorizontalOffset();
var mx = TranslatePoint(new Point(), parent).X + _scrollHorizontalOffset;
_mouseDownIndex = CalLocationIndex(mx);
var subIndex = _mouseDownIndex - CalLocationIndex(_scrollHorizontalOffset);
_maxMoveLeft = -subIndex * ItemWidth;
_maxMoveRight = parent.ActualWidth - ActualWidth + _maxMoveLeft;

_isDragging = true;
ItemIsDragging = true;
_isWaiting = true;
_dragPoint = e.GetPosition(parent);
_dragPoint = new Point(_dragPoint.X + _scrollHorizontalOffset, _dragPoint.Y);
_mouseDownPoint = _dragPoint;
CaptureMouse();
}
}

protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);

if (ItemIsDragging && _isDragging)
{
var parent = TabControlParent;
if (parent == null) return;

var subX = TranslatePoint(new Point(), parent).X + _scrollHorizontalOffset;
CurrentIndex = CalLocationIndex(subX);

var p = e.GetPosition(parent);
p = new Point(p.X + _scrollHorizontalOffset, p.Y);

var subLeft = p.X - _dragPoint.X;
var totalLeft = p.X - _mouseDownPoint.X;

if (Math.Abs(subLeft) <= WaitLength && _isWaiting) return;

_isWaiting = false;
_isDragged = true;

var left = subLeft + RenderTransform.Value.OffsetX;
if (totalLeft < _maxMoveLeft)
{
left = _maxMoveLeft + _mouseDownOffsetX;
}
else if (totalLeft > _maxMoveRight)
{
left = _maxMoveRight + _mouseDownOffsetX;
}

var t = new TranslateTransform(left, 0);
RenderTransform = t;
_dragPoint = p;
}
}

protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
{
base.OnMouseLeftButtonUp(e);

ReleaseMouseCapture();

if (_isDragged)
{
var parent = TabControlParent;
if (parent == null) return;

var subX = TranslatePoint(new Point(), parent).X + _scrollHorizontalOffset;
var index = CalLocationIndex(subX);
var left = index * ItemWidth;
var offsetX = RenderTransform.Value.OffsetX;
CreateAnimation(offsetX, offsetX - subX + left, index);
}

_isDragging = false;
ItemIsDragging = false;
_isDragged = false;
}

protected override void OnMouseDown(MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Middle && e.ButtonState == MouseButtonState.Pressed)
{
if (ShowCloseButton || ShowContextMenu)
{
Close();
}
}
}

/// <summary>
/// 创建动画
/// </summary>
internal void CreateAnimation(double offsetX, double resultX, int index = -1)
{
var parent = TabControlParent;

void AnimationCompleted()
{
RenderTransform = new TranslateTransform(resultX, 0);
if (index == -1) return;

var list = parent.GetActualList();
if (list == null) return;

var item = parent.ItemContainerGenerator.ItemFromContainer(this);
if (item == null) return;

TabPanel.CanUpdate = false;
parent.IsInternalAction = true;

list.Remove(item);
parent.IsInternalAction = true;
list.Insert(index, item);
_tabPanel.SetValue(TabPanel.FluidMoveDurationPropertyKey, new Duration(TimeSpan.FromMilliseconds(0)));
TabPanel.CanUpdate = true;
TabPanel.ForceUpdate = true;
TabPanel.Measure(new Size(TabPanel.DesiredSize.Width, ActualHeight));
TabPanel.ForceUpdate = false;

Focus();
IsSelected = true;

if (!IsMouseCaptured)
{
parent.SetCurrentValue(Selector.SelectedIndexProperty, _currentIndex);
}
}

TargetOffsetX = resultX;
if (!parent.IsAnimationEnabled)
{
AnimationCompleted();
return;
}

var animation = CreateAnimation(resultX, AnimationSpeed);
animation.FillBehavior = FillBehavior.Stop;
animation.Completed += (s1, e1) => AnimationCompleted();
var f = new TranslateTransform(offsetX, 0);
RenderTransform = f;
f.BeginAnimation(TranslateTransform.XProperty, animation, HandoffBehavior.Compose);
}
/// <summary>
/// 创建一个Double动画
/// </summary>
/// <param name="toValue"></param>
/// <param name="milliseconds"></param>
/// <returns></returns>
public static DoubleAnimation CreateAnimation(double toValue, double milliseconds = 200)
{
return new(toValue, new Duration(TimeSpan.FromMilliseconds(milliseconds)))
{
EasingFunction = new PowerEase { EasingMode = EasingMode.EaseInOut }
};
}


/// <summary>
/// 计算选项卡当前合适的位置编号
/// </summary>
/// <param name="left"></param>
/// <returns></returns>
private int CalLocationIndex(double left)
{
if (_isWaiting)
{
return CurrentIndex;
}

var maxIndex = TabControlParent.Items.Count - 1;
var div = (int) (left / ItemWidth);
var rest = left % ItemWidth;
var result = rest / ItemWidth > .5 ? div + 1 : div;

return result > maxIndex ? maxIndex : result;
}

public static readonly RoutedEvent ClosingEvent = EventManager.RegisterRoutedEvent("Closing", RoutingStrategy.Bubble, typeof(EventHandler), typeof(TabItem));

public event EventHandler Closing
{
add => AddHandler(ClosingEvent, value);
remove => RemoveHandler(ClosingEvent, value);
}

public static readonly RoutedEvent ClosedEvent = EventManager.RegisterRoutedEvent("Closed", RoutingStrategy.Bubble, typeof(EventHandler), typeof(TabItem));

public event EventHandler Closed
{
add => AddHandler(ClosedEvent, value);
remove => RemoveHandler(ClosedEvent, value);
}
}

+ 200
- 0
BPASmartClient.MilkWithTea/Control/TabPanel.cs Переглянути файл

@@ -0,0 +1,200 @@
using BPASmartClient.MilkWithTea.Data;
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;


namespace BPASmartClient.MilkWithTea.Control;

public class TabPanel : Panel
{
private int _itemCount;

/// <summary>
/// 是否可以更新
/// </summary>
internal bool CanUpdate = true;

/// <summary>
/// 选项卡字典
/// </summary>
internal Dictionary<int, TabItem> ItemDic = new();

public static readonly DependencyPropertyKey FluidMoveDurationPropertyKey =
DependencyProperty.RegisterReadOnly("FluidMoveDuration", typeof(Duration), typeof(TabPanel),
new PropertyMetadata(new Duration(TimeSpan.FromMilliseconds(0))));

/// <summary>
/// 流式行为持续时间
/// </summary>
public static readonly DependencyProperty FluidMoveDurationProperty =
FluidMoveDurationPropertyKey.DependencyProperty;

/// <summary>
/// 流式行为持续时间
/// </summary>
public Duration FluidMoveDuration
{
get => (Duration) GetValue(FluidMoveDurationProperty);
set => SetValue(FluidMoveDurationProperty, value);
}

/// <summary>
/// 是否将标签填充
/// </summary>
public static readonly DependencyProperty IsTabFillEnabledProperty = DependencyProperty.Register(
"IsTabFillEnabled", typeof(bool), typeof(TabPanel), new PropertyMetadata(ValueBoxes.FalseBox));

/// <summary>
/// 是否将标签填充
/// </summary>
public bool IsTabFillEnabled
{
get => (bool) GetValue(IsTabFillEnabledProperty);
set => SetValue(IsTabFillEnabledProperty, ValueBoxes.BooleanBox(value));
}

/// <summary>
/// 标签宽度
/// </summary>
public static readonly DependencyProperty TabItemWidthProperty = DependencyProperty.Register(
"TabItemWidth", typeof(double), typeof(TabPanel), new PropertyMetadata(200.0));

/// <summary>
/// 标签宽度
/// </summary>
public double TabItemWidth
{
get => (double) GetValue(TabItemWidthProperty);
set => SetValue(TabItemWidthProperty, value);
}

/// <summary>
/// 标签高度
/// </summary>
public static readonly DependencyProperty TabItemHeightProperty = DependencyProperty.Register(
"TabItemHeight", typeof(double), typeof(TabPanel), new PropertyMetadata(30.0));

/// <summary>
/// 标签高度
/// </summary>
public double TabItemHeight
{
get => (double) GetValue(TabItemHeightProperty);
set => SetValue(TabItemHeightProperty, value);
}

/// <summary>
/// 是否可以强制更新
/// </summary>
internal bool ForceUpdate;

private Size _oldSize;

/// <summary>
/// 是否已经加载
/// </summary>
private bool _isLoaded;

protected override Size MeasureOverride(Size constraint)
{
if ((_itemCount == InternalChildren.Count || !CanUpdate) && !ForceUpdate && !IsTabFillEnabled) return _oldSize;
constraint.Height = TabItemHeight;
_itemCount = InternalChildren.Count;

var size = new Size();

ItemDic.Clear();

var count = InternalChildren.Count;
if (count == 0)
{
_oldSize = new Size();
return _oldSize;
}
constraint.Width += InternalChildren.Count;

var itemWidth = .0;
var arr = new int[count];

if (!IsTabFillEnabled)
{
itemWidth = TabItemWidth;
}
else
{
if (TemplatedParent is TabControl tabControl)
{
arr = DivideInt2Arr((int) tabControl.ActualWidth + InternalChildren.Count, count);
}
}

for (var index = 0; index < count; index++)
{
if (IsTabFillEnabled)
{
itemWidth = arr[index];
}
if (InternalChildren[index] is TabItem tabItem)
{
tabItem.RenderTransform = new TranslateTransform();
tabItem.MaxWidth = itemWidth;
var rect = new Rect
{
X = size.Width - tabItem.BorderThickness.Left,
Width = itemWidth,
Height = TabItemHeight
};
tabItem.Arrange(rect);
tabItem.ItemWidth = itemWidth - tabItem.BorderThickness.Left;
tabItem.CurrentIndex = index;
tabItem.TargetOffsetX = 0;
ItemDic[index] = tabItem;
size.Width += tabItem.ItemWidth;
}
}
size.Height = constraint.Height;
_oldSize = size;
return _oldSize;
}

/// <summary>
/// 平分一个整数到一个数组中
/// </summary>
/// <param name="num"></param>
/// <param name="count"></param>
/// <returns></returns>
public static int[] DivideInt2Arr(int num, int count)
{
var arr = new int[count];
var div = num / count;
var rest = num % count;
for (var i = 0; i < count; i++)
{
arr[i] = div;
}
for (var i = 0; i < rest; i++)
{
arr[i] += 1;
}
return arr;
}

public TabPanel()
{
Loaded += (s, e) =>
{
if (_isLoaded) return;
ForceUpdate = true;
Measure(new Size(DesiredSize.Width, ActualHeight));
ForceUpdate = false;
foreach (var item in ItemDic.Values)
{
item.TabPanel = this;
}
_isLoaded = true;
};
}
}

+ 12
- 0
BPASmartClient.MilkWithTea/Data/CancelRoutedEventArgs.cs Переглянути файл

@@ -0,0 +1,12 @@
using System.Windows;

namespace BPASmartClient.MilkWithTea.Data;

public class CancelRoutedEventArgs : RoutedEventArgs
{
public CancelRoutedEventArgs(RoutedEvent routedEvent, object source) : base(routedEvent, source)
{
}

public bool Cancel { get; set; }
}

+ 69
- 0
BPASmartClient.MilkWithTea/Data/ValueBoxes.cs Переглянути файл

@@ -0,0 +1,69 @@
using System;
using System.Windows;
using System.Windows.Controls;

namespace BPASmartClient.MilkWithTea.Data;

/// <summary>
/// 装箱后的值类型(用于提高效率)
/// </summary>
internal static class ValueBoxes
{
internal static object TrueBox = true;

internal static object FalseBox = false;

internal static object VerticalBox = Orientation.Vertical;

internal static object HorizontalBox = Orientation.Horizontal;

internal static object VisibleBox = Visibility.Visible;

internal static object CollapsedBox = Visibility.Collapsed;

internal static object HiddenBox = Visibility.Hidden;

internal static object Double01Box = .1;

internal static object Double0Box = .0;

internal static object Double1Box = 1.0;

internal static object Double10Box = 10.0;

internal static object Double20Box = 20.0;

internal static object Double100Box = 100.0;

internal static object Double200Box = 200.0;

internal static object Double300Box = 300.0;

internal static object DoubleNeg1Box = -1.0;

internal static object Int0Box = 0;

internal static object Int1Box = 1;

internal static object Int2Box = 2;

internal static object Int5Box = 5;

internal static object Int99Box = 99;

internal static object BooleanBox(bool value) => value ? TrueBox : FalseBox;

internal static object OrientationBox(Orientation value) =>
value == Orientation.Horizontal ? HorizontalBox : VerticalBox;

internal static object VisibilityBox(Visibility value)
{
return value switch
{
Visibility.Visible => VisibleBox,
Visibility.Hidden => HiddenBox,
Visibility.Collapsed => CollapsedBox,
_ => throw new ArgumentOutOfRangeException(nameof(value), value, null)
};
}
}

+ 5
- 36
BPASmartClient.MilkWithTea/GLobal.cs Переглянути файл

@@ -1,5 +1,5 @@
using BPASmartClient.Model;
using Model;
using BPASmartClient.MorkMOC;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
@@ -17,46 +17,15 @@ namespace BPASmartClient.MilkWithTea
public static string recipePath = string.Empty;
public static string posionPath = string.Empty;

public static bool makeEnable = false;

public static ObservableCollection<LocalTeaWithMilkConfig> MaterialRecipes { get; set; } = new ObservableCollection<LocalTeaWithMilkConfig>();
public static bool makeEnable = true;
/// <summary>
/// 设备信息列表
/// 设备信息集合
/// </summary>
public static ObservableCollection<DeviceConfigModelJson> deviceConfig { get; set; } = new ObservableCollection<DeviceConfigModelJson>();


/// <summary>
/// 获取Json文件内容,转换成ObservableCollection
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="path"></param>
/// <returns></returns>
public static ObservableCollection<T> GetJsonToT<T>(string path)
{
if (!File.Exists(path))
{
//创建该文件
File.Create(path);
return default;
}
else
{
using (StreamReader recipeReader = new StreamReader(path))//读取json文件
{
string datacache = "";
string line;
while ((line = recipeReader.ReadLine()) != null) //循环将每一行数据拼接为一个完整的字符串
{
datacache = datacache + line;
}

var res = JsonConvert.DeserializeObject<ObservableCollection<T>>(datacache); //将string转换为class类,从而达到json文件转换的目的
if (res != null)
return res;
else return new ObservableCollection<T> { };
}
}
}


}
}

+ 49
- 2
BPASmartClient.MilkWithTea/MainWindow.xaml.cs Переглянути файл

@@ -7,6 +7,7 @@ using BPASmartClient.IoT;
using BPASmartClient.Message;
using BPASmartClient.Peripheral;
using BPASmartClient.ViewModel;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
@@ -36,8 +37,10 @@ namespace BPASmartClient.MilkWithTea
public MainWindow()
{
InitializeComponent();

Initialize();
TextHelper.GetInstance.WriteTextInfo("MOC", "StartShop", "DeviceConfig");
CreateDevice();
//Initialize();

}

@@ -45,6 +48,50 @@ namespace BPASmartClient.MilkWithTea
DoubleAnimation yd1 = new DoubleAnimation();//实例化浮点动画
DoubleAnimation yd2 = new DoubleAnimation();

private void CreateDevice()
{
DirectoryInfo directoryInfo = new DirectoryInfo(LocaPath.GetInstance().GetDeviceConfigPath);
if(!File.Exists($"{directoryInfo}Moc.json"))
{
File.WriteAllText($"{directoryInfo}Moc.json", JsonConvert.SerializeObject(GLobal.deviceConfig));
}
string JsonString = File.ReadAllText($"{directoryInfo}MOC.json");
var result = JsonConvert.DeserializeObject<ObservableCollection<DeviceConfigModelJson>>(JsonString);
if (result != null)
{
ShopDeviceConfigViewModel.deviceConfig.Clear();
foreach (var item in result)
{
GLobal.deviceConfig.Add(item);
}
}

if(GLobal.deviceConfig.Count <1)
{
GLobal.deviceConfig.Add(new DeviceConfigModelJson());
if(GLobal.deviceConfig.ElementAtOrDefault(0).deviceModels.Count <1)
{
GLobal.deviceConfig.ElementAtOrDefault(0).deviceModels.Add(new DeviceModel());
if(GLobal.deviceConfig.ElementAtOrDefault(0).deviceModels.ElementAtOrDefault(0).communicationDevcies.Count <1)
{
GLobal.deviceConfig.ElementAtOrDefault(0).deviceModels.ElementAtOrDefault(0).communicationDevcies.Add(new CommunicationModel());
}
}
}
if (GLobal.deviceConfig.ElementAt(0).deviceModels.ElementAt(0).communicationDevcies.ElementAt(0).variables.Count < 1)
{
for (int i = 0; i < 20; i++)
{
GLobal.deviceConfig.ElementAt(0).deviceModels.ElementAt(0).communicationDevcies.ElementAt(0).variables.Add(new Variable()
{
Id = GLobal.deviceConfig.ElementAt(0).deviceModels.ElementAt(0).communicationDevcies.ElementAt(0).variables.Count,
Address = string.Empty,
ReadLeng = 0
});
}
File.WriteAllText($"{LocaPath.GetInstance().GetDeviceConfigPath}MOC.json", JsonConvert.SerializeObject(GLobal.deviceConfig));
}
}

private void Initialize()
{


+ 13
- 0
BPASmartClient.MilkWithTea/Model/JsonDeviceConfig.cs Переглянути файл

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BPASmartClient.MilkWithTea.Model
{
public class JsonDeviceConfig
{
public ObservableCollection<DeviceConfigModelJson> deviceConfig { get; set; } = new ObservableCollection<DeviceConfigModelJson>();
}
}

+ 23
- 0
BPASmartClient.MilkWithTea/Model/JsonLocalRecipes.cs Переглянути файл

@@ -0,0 +1,23 @@
using BPASmartClient.MorkMOC;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BPASmartClient.MilkWithTea.Model
{
partial class JsonLocalRecipes
{
/// <summary>
/// 本地奶茶配方
/// </summary>
public ObservableCollection<LocalRecipe> localRecipes { get; set; } = new ObservableCollection<LocalRecipe>();
/// <summary>
/// 本地原料
/// </summary>
public ObservableCollection<LocalMaterail> localMaterails { get; set; } = new ObservableCollection<LocalMaterail>();

}
}

+ 93
- 154
BPASmartClient.MilkWithTea/View/LocalConfigureView.xaml Переглянути файл

@@ -11,48 +11,6 @@
<vm:LocalConfigureViewModel/>
</UserControl.DataContext>
<UserControl.Resources>
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="TextBlock.FontSize" Value="13" />
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Mode=Self},Path=Content.Text}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="0" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<!--HorizontalAlignment 可以设置内容展示位置-->
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center" HorizontalAlignment="Center"
Margin="{TemplateBinding Padding}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" Value=".56"/>
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="DataGridRow">
<Setter Property="FontSize" Value="16"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Margin" Value="0,5"/>
<Style.Triggers>
<!-- 隔行换色 -->
<Trigger Property="AlternationIndex" Value="0">
<Setter Property="Background" Value="#FFFAFAFA" />
</Trigger>
<Trigger Property="AlternationIndex" Value="1">
<Setter Property="Background" Value="#FFF5F5F7" />
</Trigger>

<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#87CEFA" />
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="Button">
<Setter Property="Width" Value="90"/>
<Setter Property="Height" Value="20"/>
@@ -78,12 +36,47 @@
</Setter.Value>
</Setter>
</Style>

<Style TargetType="ListViewItem" >
<Setter Property="Margin" Value="60,20"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<Border Padding="4" x:Name="mborder" BorderBrush="Transparent" BorderThickness="1">

<Border >
<Grid Width="250" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding MaterialPosition}" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="10,0"/>
<TextBox Text="{Binding MaterialName}" Grid.Column="1" Width="140"
HorizontalAlignment="Center" VerticalAlignment="Center"></TextBox>
</Grid>
</Border>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">

</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Grid Background="#F3F6F9" Margin="20">
<ScrollViewer VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Visible">
<StackPanel>
<!--奶茶配方录入-->
<Expander Style="{StaticResource ExpanderStyle}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Button Content="奶茶配方录入" HorizontalAlignment="Right" VerticalAlignment="Center" Width="150" Click="Button_Click"/>
<ScrollViewer VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Visible" Grid.Row="1">
<StackPanel>
<!--奶茶配方录入-->
<!--<Expander Style="{StaticResource ExpanderStyle}">
<Expander.Header>
<TextBlock Text="奶茶配方录入" />
</Expander.Header>
@@ -154,128 +147,74 @@
</DataGrid>
</Grid>
</Expander.Content>
</Expander>
<!--配料录入-->
<Expander Grid.Row="1" Style="{StaticResource ExpanderStyle}">
<Expander.Header>
<TextBlock Text="本地配料录入" />
</Expander.Header>
<Expander.Content>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="70"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button Content="保存物料位置名称" Grid.ColumnSpan="2" Style="{StaticResource buttonNormal}" Height="34" Width="200" Command="{Binding UpdateMaterialPosionCommand}"/>
<DataGrid Grid.Row="1" Margin="50,5" AutoGenerateColumns="False" ItemsSource="{Binding materail1,Mode=TwoWay}"
FrozenColumnCount="1" RowHeight="34"
VerticalAlignment="Top" HorizontalAlignment="Right"
IsReadOnly="True"
CanUserResizeColumns="False" CanUserResizeRows="False" SelectionMode="Single"
CanUserReorderColumns="False" AlternationCount="2" RowHeaderWidth="0" CanUserAddRows="False">
<DataGrid.Columns>
<DataGridTemplateColumn Header="物料位置" Width="170">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" >
<TextBlock Foreground="Black" Text="{Binding MaterialPosion}"
VerticalAlignment="Center" HorizontalAlignment="Left"
Margin="5,0" FontSize="16"/>
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="物料" Width="250">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Text="{Binding MaterialName ,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
VerticalAlignment="Center" HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
Margin="2" FontSize="16"
Width="160" Height="28" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
<DataGrid Grid.Row="1" Grid.Column="1" Margin="50,5" AutoGenerateColumns="False" ItemsSource="{Binding materail2,Mode=TwoWay}"
FrozenColumnCount="1" RowHeight="34"
VerticalAlignment="Top" HorizontalAlignment="Left"
IsReadOnly="True"
CanUserResizeColumns="False" CanUserResizeRows="False" SelectionMode="Single"
CanUserReorderColumns="False" AlternationCount="2" RowHeaderWidth="0" CanUserAddRows="False">
</Expander>-->
<!--配料录入-->
<Expander Grid.Row="1" Style="{StaticResource ExpanderStyle}">
<Expander.Header>
<TextBlock Text="本地配料录入" />
</Expander.Header>
<Expander.Content>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="70"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Button Content="保存物料位置名称" Grid.ColumnSpan="2" Style="{StaticResource buttonNormal}" Height="34" Width="200"
Command="{Binding UpdateMaterialPosionCommand}"/>
<ListView ItemsSource="{Binding localMaterails}" Grid.Row="1"
Width="800" ScrollViewer.HorizontalScrollBarVisibility="Disabled"
HorizontalAlignment="Center" VerticalAlignment="Center">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Margin="10"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
</Grid>
</Expander.Content>
</Expander>
<!--奶茶清单-->
<Expander Grid.Row="2" Style="{StaticResource ExpanderStyle}" >
<Expander.Header>
<TextBlock Text="本地奶茶配方"/>
</Expander.Header>
<Expander.Content>
<DataGrid Grid.Row="4" Margin="100,5" AutoGenerateColumns="False" RowHeight="32" ItemsSource="{Binding localMaterialRecipes}" Width="500"
FrozenColumnCount="1"
VerticalAlignment="Top"
IsReadOnly="True"
CanUserResizeColumns="False" CanUserResizeRows="False" SelectionMode="Single"
CanUserReorderColumns="False" AlternationCount="2" RowHeaderWidth="0" CanUserAddRows="False">
<DataGrid.Columns>
<DataGridTemplateColumn Header="物料位置" Width="170">
<DataGridTemplateColumn Header="奶茶" Width="200">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" >
<TextBlock Foreground="Black" Text="{Binding MaterialPosion}"
VerticalAlignment="Center" HorizontalAlignment="Left"
Margin="5,0" FontSize="16"/>
<TextBlock Text="{Binding RecipeName}" Foreground="Black"
VerticalAlignment="Center" HorizontalAlignment="Center"
Margin="5,2" FontSize="16"/>
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="物料" Width="250">
<DataGridTemplateColumn Header="操作" Width="*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Text="{Binding MaterialName ,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
VerticalAlignment="Center" HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
Margin="2" Height="28"
Width="160" FontSize="16"/>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center">
<Button Content="删除" Margin="2"
Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.DeleteRecipeCommand}"
CommandParameter="{Binding RecipeID}"/>
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Expander.Content>
</Expander>
<!--奶茶清单-->
<Expander Grid.Row="2" Style="{StaticResource ExpanderStyle}" >
<Expander.Header>
<TextBlock Text="本地奶茶配方"/>
</Expander.Header>
<Expander.Content>
<DataGrid Grid.Row="4" Margin="100,5" AutoGenerateColumns="False" RowHeight="32" ItemsSource="{Binding localMaterialRecipes}" Width="500"
FrozenColumnCount="1"
VerticalAlignment="Top"
IsReadOnly="True"
CanUserResizeColumns="False" CanUserResizeRows="False" SelectionMode="Single"
CanUserReorderColumns="False" AlternationCount="2" RowHeaderWidth="0" CanUserAddRows="False">
<DataGrid.Columns>
<DataGridTemplateColumn Header="奶茶" Width="200">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" >
<TextBlock Text="{Binding GoodNames}" Foreground="Black"
VerticalAlignment="Center" HorizontalAlignment="Center"
Margin="5,2" FontSize="16"/>
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="操作" Width="*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center">
<Button Content="删除" Margin="2"
Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.DeleteRecipeCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}, Path=SelectedIndex}" />
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Expander.Content>
</Expander>
</StackPanel>
</ScrollViewer>
</Expander.Content>
</Expander>
</StackPanel>
</ScrollViewer>
</Grid>
</Grid>
</UserControl>

+ 8
- 1
BPASmartClient.MilkWithTea/View/LocalConfigureView.xaml.cs Переглянути файл

@@ -1,4 +1,5 @@
using System;
using BPASmartClient.MilkWithTea.ViewModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -24,5 +25,11 @@ namespace BPASmartClient.MilkWithTea.View
{
InitializeComponent();
}

private void Button_Click(object sender, RoutedEventArgs e)
{
RecipeConfige recipeConfige = new RecipeConfige();
recipeConfige.ShowDialog();
}
}
}

+ 4
- 4
BPASmartClient.MilkWithTea/View/MainControlView.xaml Переглянути файл

@@ -168,11 +168,11 @@
<TextBlock Text="配方" Grid.Row="2" Grid.Column="1" Margin="10" FontSize="22" />
<Border BorderBrush="#D5DFE5" BorderThickness="4" Grid.Row="3" Margin="20,0,0,0">
<ListBox ItemsSource="{Binding localTeaWithMilks}" SelectionChanged="ListBox_SelectionChanged" IsEnabled="{Binding MakeEnable}"
Foreground="LightSlateGray">
Foreground="LightSlateGray" SelectedValue="{Binding SelectedRecipe,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}">
<ListBox.ItemTemplate>
<DataTemplate >
<Grid>
<TextBlock Text="{Binding GoodNames}" Margin="5,10" FontSize="22"
<TextBlock Text="{Binding RecipeName}" Margin="5,10" FontSize="22"
Background="Transparent" />
</Grid>
</DataTemplate>
@@ -181,7 +181,7 @@
</Border>
<ListBox x:Name="recipeList" Grid.Row="3" Grid.Column="1" Margin="5,10"
ItemsSource="{Binding materialRecipes}" FontSize="18"
ItemsSource="{Binding localMaterails}" FontSize="18"
Width="200" HorizontalAlignment="Left" Foreground="LightSlateGray">
<ListBox.ItemTemplate>
<DataTemplate >
@@ -191,7 +191,7 @@
<ColumnDefinition Width="40"/>
<ColumnDefinition Width="15"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Material}" Margin="20,10" FontSize="16"/>
<TextBlock Text="{Binding MaterialName}" Margin="20,10" FontSize="16"/>
<TextBlock Text="{Binding MaterialWeight}" Margin="5,10,0,10" Grid.Column="1" HorizontalAlignment="Left" />
<TextBlock Text="g" Margin="0,10" HorizontalAlignment="Right" Grid.Column="2"/>
</Grid>


+ 2
- 3
BPASmartClient.MilkWithTea/View/MainControlView.xaml.cs Переглянути файл

@@ -1,5 +1,4 @@
using BPASmartClient.MilkWithTea.ViewModel;
using Model;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -29,9 +28,9 @@ namespace BPASmartClient.MilkWithTea.View

private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if((sender as ListBox).SelectedItem is LocalTeaWithMilkConfig config)
if((sender as ListBox).SelectedItem is LocalRecipe config)
{
recipeList.ItemsSource = config.materialRecipes;
recipeList.ItemsSource = config.localMaterails;
}
}
}


+ 23
- 14
BPASmartClient.MilkWithTea/View/ParameterSetting.xaml Переглянути файл

@@ -11,13 +11,7 @@
<vm:PatrameterSettiongViewModel/>
</UserControl.DataContext>
<UserControl.Resources>
<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="18"/>
<Setter Property="Foreground" Value="DarkSlateGray"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="FontSize" Value="18"/>
</Style>
</UserControl.Resources>
<Grid Background="#F3F6F9" Margin="20" >
<Grid.ColumnDefinitions>
@@ -40,18 +34,18 @@
<StackPanel Orientation="Horizontal">
<TextBlock Text="通道口:"/>
<ComboBox ItemsSource="{Binding materialPosions}"
SelectedIndex="{Binding MaterialID ,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
SelectedValue="{Binding MaterialID ,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
Margin="10,0" Width="120 " Style="{StaticResource cmbstyle}"/>
<TextBlock Text="出料量:" Margin="10,0,0,0" />
<TextBox Text="{Binding OutMaterailWeight}" Width="60" Margin="10,0" VerticalContentAlignment="Center"/>
<TextBlock Text="g" Margin="2,0"/>
<Button Content="出料" Style="{StaticResource buttonNormal}" Height="36" Width="100" Margin="30,0" Command="{Binding OutMaterailCommad}"/>
<TextBlock Text="转盘位置:" Margin="60,0,10,0"/>
<ComboBox ItemsSource="{Binding TurntablePosion}"
<!--<TextBlock Text="转盘位置:" Margin="60,0,10,0"/>-->
<!--<ComboBox ItemsSource="{Binding TurntablePosion}"
SelectedIndex="{Binding TurntableID,Mode=TwoWay ,UpdateSourceTrigger=PropertyChanged}"
Margin="10,0" Width="100 " Style="{StaticResource cmbstyle}"/>
<Button Content="转动" Style="{StaticResource buttonNormal}" Height="36" Width="80" Margin="30,0"
Command="{Binding TurntableCommad}"/>
Command="{Binding TurntableCommad}"/>-->
</StackPanel>
<CheckBox Grid.Row="2" Content="禁用本地奶茶下单" HorizontalAlignment="Left" Margin="0,10"
HorizontalContentAlignment="Center" VerticalContentAlignment="Center"
@@ -84,7 +78,7 @@
<TextBlock Text="校正后的重量" Grid.Column="5"/>
<TextBlock Text="出料时间" Grid.Column="3"/>

<ComboBox Grid.Row="1" Width="100" Style="{StaticResource cmbstyle}" ItemsSource="{Binding materialPosions}"
<ComboBox Grid.Row="1" Width="100" Style="{StaticResource cmbstyle}" ItemsSource="{Binding materialPosions}" Height="30"
SelectedIndex="{Binding CorrectPassway ,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" SelectionChanged="ComboBox_SelectionChanged" />
<TextBlock Grid.Row="1" Grid.Column="1" ></TextBlock>
<CheckBox x:Name="OpenIsCheck"
@@ -126,16 +120,31 @@
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="10"/>
</Grid.RowDefinitions>
<TextBlock Text="店铺名称:" Grid.ColumnSpan="2" FontSize="22" Height="28" Width="94" HorizontalAlignment="Left" Margin="20,0"/>
<TextBox Text="{Binding ShopName}" Grid.Column="2" Grid.ColumnSpan="2" Margin="-20,10,30,10" VerticalContentAlignment="Center"/>
<TextBlock Text="店铺ID:" Grid.Row="1" Height="23" Width="60" HorizontalAlignment="Left" Margin="20,0"/>
<TextBlock Text="设备ID:" Grid.Column="2" Grid.Row="1" Height="23" Width="60" />
<TextBlock Text="PLC地址:" Grid.Column="0" Grid.Row="2" Grid.ColumnSpan="2" Height="23" Width="72" HorizontalAlignment="Left" Margin="20,0"/>
<TextBox Text="{Binding ShopID}" Width="60" Grid.Column="1" Grid.Row="1" HorizontalAlignment="Left" VerticalContentAlignment="Center" Margin="0,12"/>
<TextBox Text="{Binding DeviceID}" Width="60" Grid.Column="3" Grid.Row="1" HorizontalAlignment="Left" VerticalContentAlignment="Center" Margin="0,12"/>
<TextBox Text="{Binding PLCAdress}" Grid.Column="2" Grid.Row="2" Grid.ColumnSpan="2" Margin="-20,10,30,10"

<RadioButton Content="网口" GroupName="a" Grid.Row="2" HorizontalAlignment="Center" VerticalAlignment="Center" VerticalContentAlignment="Center"
Command="{Binding ChangeCommunationCommand}"/>
<StackPanel Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="3" Orientation="Horizontal" Visibility="{Binding VsIP}"
HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock Text="IP:" Height="23" Margin="20,0"/>
<TextBox Text="{Binding PLCAdress}" Margin="0,10,30,10" Width="160"
VerticalContentAlignment="Center"/>
</StackPanel>
<RadioButton Content="串口" GroupName="a" Grid.Row="3" HorizontalAlignment="Center" VerticalAlignment="Center" VerticalContentAlignment="Center"
IsChecked="{Binding IsPort}" Command="{Binding ChangeCommunationCommand}"/>
<StackPanel Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="3" Orientation="Horizontal" Visibility="{Binding VsPort}">
<TextBlock Text="串口号:" />
<ComboBox Style="{DynamicResource cmbstyle}" Height="26" Width="100" ItemsSource="{Binding Ports}"
SelectedValue="{Binding Prot}"/>
</StackPanel>
<Button Style="{StaticResource buttonNormal}"
Grid.Column="4" Grid.ColumnSpan="2" Grid.Row="0" Grid.RowSpan="3"


+ 135
- 0
BPASmartClient.MilkWithTea/View/RecipeConfige.xaml Переглянути файл

@@ -0,0 +1,135 @@
<Window x:Class="BPASmartClient.MilkWithTea.View.RecipeConfige"
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:BPASmartClient.MilkWithTea.View"
xmlns:vm="clr-namespace:BPASmartClient.MilkWithTea.ViewModel"
mc:Ignorable="d"
Title="RecipeConfige"
Height="800" Width="800" WindowStartupLocation="CenterScreen" WindowStyle="None" AllowsTransparency="True"
>
<Window.DataContext>
<vm:RecipeConfigeViewModel/>
</Window.DataContext>
<Window.Resources>


</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="60"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>

</Grid.RowDefinitions>

<StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center">
<TextBlock Text="奶茶名称" Margin="10,0" />
<TextBox Text="{Binding Name}" Width="120" Foreground="DarkSlateGray" Margin="10,0"/>
<Button Content="添加配料" Margin="10,0" Width="100" Command="{Binding AddMaterialCommand}"/>
<Button Content="保存" Margin="10,0" Width="100" Command="{Binding SaveCommand}"/>
<Button Content="取消" Margin="10,0" Width="100" Click="Button_Click"/>
</StackPanel>
<Grid Grid.Row="1">
<ScrollViewer
HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding Materails}" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<RadioButton GroupName="all">
<RadioButton.Template>
<ControlTemplate TargetType="RadioButton">
<Grid Name="gr" Height="40" Margin="20,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions>
<ComboBox Name="cb" Width="120" Height="30"
ItemsSource="{Binding DataContext.materialNames, RelativeSource={RelativeSource AncestorType=Window, Mode=FindAncestor}}"
SelectedValue="{Binding MaterialID}"
SelectedValuePath="Key" DisplayMemberPath="Value"/>
<StackPanel Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBox Text="{Binding MaterialWeight}" Width="120" Margin="10,0"/>
<TextBlock Text="g" />
</StackPanel>
<Button Grid.Column="2"
Width="70"
Height="25"
Margin="15,0,0,0"
FontSize="16"
BorderBrush="#FF2AB2E7"
BorderThickness="1"
HorizontalAlignment="Left"
Command="{Binding DataContext.DeleteCommand, RelativeSource={RelativeSource AncestorType=Window, Mode=FindAncestor}}"
CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=ListBoxItem, Mode=FindAncestor}}"
Content="删 除" />

</Grid>


</ControlTemplate>
</RadioButton.Template>
</RadioButton>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
<Grid Grid.Row="2">
<ListBox x:Name="listview1" AllowDrop="True" SelectionMode="Extended" MouseMove="listview1_MouseMove"
ItemsSource="{Binding Materails}" PreviewMouseLeftButtonUp="listview1_MouseLeftButtonUp">
<ListBox.ItemTemplate>
<DataTemplate>
<Border PreviewMouseLeftButtonDown="listview1_MouseLeftButtonDown" Width="800" BorderBrush="Black" BorderThickness="1" Background="White"
>
<RadioButton GroupName="all" >
<RadioButton.Template>
<ControlTemplate TargetType="RadioButton">
<Grid Name="gr" Height="40" Margin="20,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions>
<ComboBox Name="cb" Width="120" Height="30"
ItemsSource="{Binding DataContext.materialNames, RelativeSource={RelativeSource AncestorType=Window, Mode=FindAncestor}}"
SelectedValue="{Binding MaterialID }"
SelectedValuePath="Key" DisplayMemberPath="Value"/>
<StackPanel Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBox Text="{Binding MaterialWeight}" Width="120" Margin="10,0"/>
<TextBlock Text="g" />
</StackPanel>
<Button Grid.Column="2"
Width="70"
Height="25"
Margin="15,0,0,0"
FontSize="16"
BorderBrush="#FF2AB2E7"
BorderThickness="1"
HorizontalAlignment="Left"
Command="{Binding DataContext.DeleteCommand, RelativeSource={RelativeSource AncestorType=Window, Mode=FindAncestor}}"
CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=ListBoxItem, Mode=FindAncestor}}"
Content="删 除" />
</Grid>


</ControlTemplate>
</RadioButton.Template>
</RadioButton>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Grid>
</Window>

+ 174
- 0
BPASmartClient.MilkWithTea/View/RecipeConfige.xaml.cs Переглянути файл

@@ -0,0 +1,174 @@
using BPASmartClient.MilkWithTea.ViewModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Effects;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace BPASmartClient.MilkWithTea.View
{
/// <summary>
/// RecipeConfige.xaml 的交互逻辑
/// </summary>
public partial class RecipeConfige : Window
{
double X,Y;
Border ultUE;
Popup mypopup;
ListBoxItem OldItem;

public RecipeConfige()
{
InitializeComponent();
ActionManage.GetInstance.CancelRegister("RecipeConfigeViewClose");
ActionManage.GetInstance.Register(new Action(()=> this.Close()), "RecipeConfigeViewClose");
}

private void Button_Click(object sender, RoutedEventArgs e)
{
this.Close();
}




private int GetCurrentIndex(GetPositionDelegate getPosition)
{
int index = -1;
for (int i = 0; i < listview1.Items.Count; ++i)
{
ListViewItem item = GetListViewItem(i);
if (item != null && this.IsMouseOverTarget(item, getPosition))
{
index = i;
break;
}
}
return index;
}

private bool IsMouseOverTarget(Visual target, GetPositionDelegate getPosition)
{
Rect bounds = VisualTreeHelper.GetDescendantBounds(target);
Point mousePos = getPosition((IInputElement)target);
return bounds.Contains(mousePos);
}

delegate Point GetPositionDelegate(IInputElement element);

ListViewItem GetListViewItem(int index)
{
if (listview1.ItemContainerGenerator.Status != GeneratorStatus.ContainersGenerated)
return null;
return listview1.ItemContainerGenerator.ContainerFromIndex(index) as ListViewItem;
}

private void CloneVisual(Border border, MouseButtonEventArgs e)
{
ListBoxItem listBoxItem = new ListBoxItem();
Point ptLeftUp = new Point(0, 0);
ptLeftUp = listview1.PointToScreen(ptLeftUp);
mypopup = new Popup();
double y = e.GetPosition(listview1).Y;
double x = e.GetPosition(listview1).X;
VisualBrush brush = new VisualBrush(border);
Rectangle rect = new Rectangle();
rect.Width = border.ActualWidth;
rect.Height = border.ActualHeight;
rect.Fill = brush;
rect.Opacity = border.Opacity;
border.Opacity = 0.8;
mypopup.Child = rect;
mypopup.AllowsTransparency = true;
mypopup.HorizontalOffset = ptLeftUp.X + x - ((FrameworkElement)ultUE).ActualWidth / 2;
mypopup.VerticalOffset = ptLeftUp.Y + y - ((FrameworkElement)ultUE).ActualHeight / 2;
mypopup.IsOpen = true;
}

private void listview1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var pos = e.GetPosition(listview1);
HitTestResult result = VisualTreeHelper.HitTest(listview1, pos);
OldItem = Utils.FindVisualParent<ListBoxItem>(result.VisualHit);
if(OldItem != null)
{
if (e.Source is Border)
{
ultUE = (Border)e.Source;
ultUE.CaptureMouse();
ultUE.Visibility = Visibility.Collapsed;
CloneVisual(ultUE, e);
}
}
}



private void listview1_MouseMove(object sender, MouseEventArgs e)
{
Point ptLeftUp = new Point(0, 0);
Point ptRightDown = new Point(this.ActualWidth, this.ActualHeight);
ptLeftUp = listview1.PointToScreen(ptLeftUp);
ptRightDown = listview1.PointToScreen(ptRightDown);
double y = e.GetPosition(listview1).Y;
double x = e.GetPosition(listview1).X;
if (mypopup != null)
{
mypopup.HorizontalOffset = ptLeftUp.X + x - ((FrameworkElement)ultUE).ActualWidth / 2;
mypopup.VerticalOffset = ptLeftUp.Y + y - ((FrameworkElement)ultUE).ActualHeight / 2;
}
}

private void listview1_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if(mypopup != null)
{
mypopup.IsOpen = false;
mypopup = null;
}
if (OldItem == null) return;
var pos = e.GetPosition(listview1);
HitTestResult result = VisualTreeHelper.HitTest(listview1, pos);
if(result == null) return;
var Newitem = Utils.FindVisualParent<ListBoxItem>(result.VisualHit);
if (Newitem == null) return;
if (OldItem == Newitem) return;
int iold = listview1.Items.IndexOf((LocalMaterail)OldItem.DataContext);
int inew = listview1.Items.IndexOf((LocalMaterail)Newitem.DataContext);
RecipeConfigeViewModel.Materails.Move(iold,inew);
}
}

internal static class Utils
{
//根据子元素查找父元素
public static T FindVisualParent<T>(DependencyObject obj) where T : class
{
while (obj != null)
{
if (obj is T)
return obj as T;

obj = VisualTreeHelper.GetParent(obj);
}
return null;
}
}
}

+ 30
- 169
BPASmartClient.MilkWithTea/ViewModel/LocalConfigureViewModel.cs Переглянути файл

@@ -1,7 +1,5 @@
using BPASmartClient.MorkTM;
using Microsoft.Toolkit.Mvvm.ComponentModel;
using Microsoft.Toolkit.Mvvm.Input;
using Model;
using BPASmartClient.MorkMOC;
using CommunityToolkit.Mvvm.Input;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
@@ -14,56 +12,34 @@ using System.Windows;

namespace BPASmartClient.MilkWithTea.ViewModel
{
public class LocalConfigureViewModel : ObservableObject

partial class LocalConfigureViewModel : ObservableObject
{
#region 奶茶配方录入
/// <summary>
/// 奶茶配方
/// </summary>
public ObservableCollection<MaterialRecipe> materialRecipes { get => materialRecipes1; set => materialRecipes1 = value; }
/// <summary>
/// 出料集合
/// </summary>
public ObservableCollection<string> MaterailList { get; set; } = new ObservableCollection<string>();
/// <summary>
/// 奶茶名称
/// </summary>
public string LocalGoodName { get { return _localGoodName; } set { _localGoodName = value; OnPropertyChanged(); } }
private string _localGoodName;

private ObservableCollection<MaterialRecipe> materialRecipes1 = new ObservableCollection<MaterialRecipe>();

/// <summary>
/// 添加一条配方
/// </summary>
public RelayCommand AddRecipeCommand { get; set; }
/// <summary>
/// 删除一条配方
/// </summary>
public RelayCommand<object> RemoveRecipeCommand { get; set; }
/// <summary>
/// 取消配方
/// </summary>
public RelayCommand RecipeCancelCommand { get; set; }
/// <summary>
/// 保存配方
/// </summary>
public RelayCommand SaveRecipeCommand { get; set; }

#endregion

#region 本地奶茶配方
/// <summary>
/// 本地奶茶配方列表
/// </summary>
public ObservableCollection<LocalTeaWithMilkConfig> localMaterialRecipes { get; set; } = GLobal.MaterialRecipes;
public ObservableCollection<LocalRecipe> localMaterialRecipes { get; set; } = Json<JsonLocalRecipes>.Data.localRecipes;

/// <summary>
/// 删除配方奶茶
/// </summary>
public RelayCommand<object> DeleteRecipeCommand { get; set; }
[RelayCommand]
private void DeleteRecipe(object o)
{
if (o == null) return;
if(o is string id)
{
var res = localMaterialRecipes.FirstOrDefault(p => p.RecipeID == id);
if (res != null)
{
localMaterialRecipes.Remove(res);
Json<JsonLocalRecipes>.Save();
}
}
}

#endregion

@@ -71,141 +47,26 @@ namespace BPASmartClient.MilkWithTea.ViewModel
/// <summary>
/// 物料位置名称集合
/// </summary>
public ObservableCollection<MaterailNameAndPosion> materailNameAndPosions { get; set; } = new ObservableCollection<MaterailNameAndPosion>();
public List<MaterailNameAndPosion> materail1 { get; set; } = new List<MaterailNameAndPosion>();
public List<MaterailNameAndPosion> materail2 { get; set; } = new List<MaterailNameAndPosion>();
public ObservableCollection<LocalMaterail> localMaterails { get; set; } = Json<JsonLocalRecipes>.Data.localMaterails;
/// <summary>
/// 更新物料位置
/// </summary>
public RelayCommand UpdateMaterialPosionCommand { get; set; }
[RelayCommand]
private void UpdateMaterialPosion()
{
Json<JsonLocalRecipes>.Save();
}
#endregion

public LocalConfigureViewModel()
{
materialRecipes.Add(new MaterialRecipe()
{
MaterialWeight = 10
});




AddRecipeCommand = new RelayCommand(new Action(() =>
{
materialRecipes.Add(new MaterialRecipe()
{
MaterialID = materialRecipes.Count() + 1
});

}));

RemoveRecipeCommand = new RelayCommand<object>((o =>
{
if (o != null && o is int index)
{
materialRecipes.RemoveAt(index);
for (int i = 0; i < materialRecipes.Count; i++)//ID排序
{
materialRecipes[i].MaterialID = i + 1;
}
}

}));

RecipeCancelCommand = new RelayCommand(new Action(() =>
{
materialRecipes.Clear();
LocalGoodName = String.Empty;
}));

SaveRecipeCommand = new RelayCommand(new Action(() =>
{
if (LocalGoodName == "" || LocalGoodName == null) return;
if (materialRecipes.Count == 0) return;

localMaterialRecipes.Insert(0, new LocalTeaWithMilkConfig()
{
GoodNames = LocalGoodName,
materialRecipes = materialRecipes

});

UpdateLocalJosnData<LocalTeaWithMilkConfig>(GLobal.recipePath, localMaterialRecipes);//更新奶茶配方json文件
MessageBox.Show("保存成功");
}));


DeleteRecipeCommand = new RelayCommand<object>((o =>
{
if (o != null && o is int index)
{
localMaterialRecipes.RemoveAt(index);
UpdateLocalJosnData<LocalTeaWithMilkConfig>(GLobal.recipePath, localMaterialRecipes);//更新奶茶配方json文件
}
}));

UpdateMaterialPosionCommand = new RelayCommand(new Action(() =>
{
materailNameAndPosions.Clear();
foreach(var item in materail1)
{
materailNameAndPosions.Add(item);
}
foreach (var item in materail2)
{
materailNameAndPosions.Add(item);
}
UpdateLocalJosnData<MaterailNameAndPosion>(GLobal.posionPath, materailNameAndPosions);//更新物料位置名称
MaterailList.Clear();
foreach (MaterailNameAndPosion m in materailNameAndPosions)
{
if (m.MaterialName != null) MaterailList.Add(m.MaterialName);

}
}));

Init();
}

/// <summary>
/// 界面初始化加载
/// </summary>
private void Init()
{

materailNameAndPosions = GLobal.GetJsonToT<MaterailNameAndPosion>(GLobal.posionPath);
if (materailNameAndPosions.Count == 0)
{
foreach (MaterialPosion item in Enum.GetValues(typeof(MaterialPosion)))
{
materailNameAndPosions.Add(new MaterailNameAndPosion()
{
MaterialPosion = item.ToString()
});
}
}
materail1 = materailNameAndPosions.Take<MaterailNameAndPosion>(14).ToList();
materail2 = materailNameAndPosions.TakeLast<MaterailNameAndPosion>(14).ToList();
foreach (MaterailNameAndPosion m in materailNameAndPosions)
{
if (m.MaterialName != null) MaterailList.Add(m.MaterialName);

}
}

/// <summary>
/// 更新Json文件数据
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="path"></param>
/// <param name="ts"></param>
private void UpdateLocalJosnData<T>(string path, ObservableCollection<T> ts)
{
if (ts != null) File.WriteAllText(path, JsonConvert.SerializeObject(ts));

}
}
}

+ 37
- 28
BPASmartClient.MilkWithTea/ViewModel/MainControlViewModel.cs Переглянути файл

@@ -1,29 +1,22 @@
using BPA.Message;
using BPA.Message.Enum;
using BPASmartClient.Device;
using BPASmartClient.EventBus;

global using CommunityToolkit.Mvvm.Input;
using BPASmartClient.Helper;
using BPASmartClient.Model;
using Microsoft.Toolkit.Mvvm.ComponentModel;
using Microsoft.Toolkit.Mvvm.Input;
using Model;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using BPASmartClient.Message;

namespace BPASmartClient.MilkWithTea.ViewModel
{
public class MainControlViewModel: ObservableObject
partial class MainControlViewModel: ObservableObject
{

public ObservableCollection<LocalTeaWithMilkConfig> localTeaWithMilks { get; set; } = GLobal.MaterialRecipes;
/// <summary>
/// 本地奶茶列表
/// </summary>
public ObservableCollection<LocalRecipe> localTeaWithMilks { get; set; } = Json<JsonLocalRecipes>.Data.localRecipes;

public ObservableCollection<MaterialRecipe> materialRecipes { get; set; } = new ObservableCollection<MaterialRecipe>();
/// <summary>
/// 奶茶对应的原料列表
/// </summary>
public ObservableCollection<LocalMaterail> materialRecipes { get; set; } = new ObservableCollection<LocalMaterail>();

/// <summary>
/// 订单状态列表
@@ -38,15 +31,16 @@ namespace BPASmartClient.MilkWithTea.ViewModel
/// <summary>
/// 当前正在制作的奶茶
/// </summary>
public string CurrentGood { get { return _currentGood; } set { _currentGood = value; OnPropertyChanged(); } }
[ObservableProperty]
private string _currentGood = "茉莉花茶";
/// <summary>
/// 奶茶制作百分比
/// </summary>
public string MakePercent { get { return _makePercent; } set { _makePercent = value; OnPropertyChanged(); } }
[ObservableProperty]
private string _makePercent = "0";


[ObservableProperty]
private LocalRecipe _selectedRecipe;

/// <summary>
/// 当前正在制作的奶茶
@@ -56,16 +50,31 @@ namespace BPASmartClient.MilkWithTea.ViewModel
/// <summary>
/// 本地奶茶制作
/// </summary>
public RelayCommand MakeGoodCommand { get; set; }
[RelayCommand]
private void MakeGood()
{
if(SelectedRecipe == null) return;
foreach(var item in SelectedRecipe.localMaterails)
{
var res = Json<JsonLocalRecipes>.Data.localMaterails.FirstOrDefault(p => p.MaterialID == item.MaterialID);
if ( res!= null)
{
item.MaterialPosition = res.MaterialPosition;
}
else
{
MessageLog.GetInstance.ShowEx($"配料:{item.MaterialName}不存在,下单失败");
return;
}
}
ActionManage.GetInstance.Send( "MakeGoods",SelectedRecipe);
}




public MainControlViewModel()
{
MakeGoodCommand = new RelayCommand(new Action(() =>
{

}));
Init();
MorkOrderPush morkOrderPush = new MorkOrderPush() { GoodsName = "珍珠奶茶", SortNum = 1 };
MorkOrderPush morkOrderPush1 = new MorkOrderPush() { GoodsName = "茉莉花茶", SortNum = 2 };


+ 16
- 17
BPASmartClient.MilkWithTea/ViewModel/MainWindowVeiwModel.cs Переглянути файл

@@ -1,7 +1,6 @@
using BPASmartClient.Helper;
global using Microsoft.Toolkit.Mvvm.ComponentModel;
using BPASmartClient.Helper;
using BPASmartClient.Model;
using Microsoft.Toolkit.Mvvm.ComponentModel;
using Model;
using System;
using System.Collections.Generic;
using System.IO;
@@ -17,23 +16,23 @@ namespace BPASmartClient.MilkWithTea.ViewModel

public MainWindowVeiwModel()
{
init();
}

private void init()
{
string path = Path.Combine(Environment.CurrentDirectory, "AccessFile", "Recipes");
//判断文件夹是否存在,如果不存在就创建file文件夹
if (!Directory.Exists(path))
Json<JsonLocalRecipes>.Read();
Json<JsonDeviceConfig>.Read();
if (Json<JsonLocalRecipes>.Data.localMaterails.Count<14)
{
Directory.CreateDirectory(path);
Json<JsonLocalRecipes>.Data.localMaterails.Clear();
for (int i = 1; i < 15; i++)
{
Json<JsonLocalRecipes>.Data.localMaterails.Add(new LocalMaterail
{
MaterialID = Guid.NewGuid().ToString(),
MaterialPosition = i
});;
}
}
GLobal.recipePath = Path.Combine(path, "LocalRecipes.json");
GLobal.posionPath = Path.Combine(path, "MaterialPosion.json");

GLobal.MaterialRecipes = GLobal.GetJsonToT<LocalTeaWithMilkConfig>(GLobal.recipePath);
GLobal.deviceConfig = GLobal.GetJsonToT<DeviceConfigModelJson>($"{LocaPath.GetInstance().GetDeviceConfigPath}奶茶味魔方.json");
}


}
}

+ 105
- 86
BPASmartClient.MilkWithTea/ViewModel/PatrameterSettiongViewModel.cs Переглянути файл

@@ -1,9 +1,7 @@
using BPASmartClient.Helper;
using BPASmartClient.Message;
using BPASmartClient.Model;
using BPASmartClient.MorkTM;
using Microsoft.Toolkit.Mvvm.ComponentModel;
using Microsoft.Toolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Input;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
@@ -15,164 +13,185 @@ using System.Threading.Tasks;

namespace BPASmartClient.MilkWithTea.ViewModel
{
public class PatrameterSettiongViewModel: ObservableObject
partial class PatrameterSettiongViewModel: ObservableObject
{
string FileName => GLobal.deviceConfig.Count > 0 ? GLobal.deviceConfig[0].ShopName : string.Empty;

/// <summary>
/// 物料通道口列表
/// </summary>
public ObservableCollection<MaterialPosion> materialPosions { get; set; } = new ObservableCollection<MaterialPosion>();
/// <summary>
/// 转盘位置列表
/// </summary>
public ObservableCollection<OutMaterialPosion> TurntablePosion { get; set; } = new ObservableCollection<OutMaterialPosion>();
public ObservableCollection<int> materialPosions { get; set; } = new ObservableCollection<int>();

/// <summary>
/// 出料位置ID
/// </summary>
public int MaterialID { get { return _materialID; } set { _materialID = value; OnPropertyChanged(); } }
[ObservableProperty]
private int _materialID = 0;

/// <summary>
/// 出料重量
/// </summary>
public float OutMaterailWeight { get { return _outMaterilWeight; } set { _outMaterilWeight = value; OnPropertyChanged(); } }
private float _outMaterilWeight;
/// <summary>
/// 装盘ID
/// </summary>
public int TurntableID { get { return _turntableID; } set { _turntableID = value; OnPropertyChanged(); } }
private int _turntableID = 0;
[ObservableProperty]
private int _outMaterilWeight;

/// <summary>
/// 矫正的通道号
/// </summary>
public int CorrectPassway { get { return _CorrectPassway; } set { _CorrectPassway = value; OnPropertyChanged(); } }
[ObservableProperty]
private int _CorrectPassway = 0;
/// <summary>
/// 通道是否开启
/// </summary>
public bool PasswayIsOpen { get { return _passwayIsOpen; } set { _passwayIsOpen = value; OnPropertyChanged(); } }
[ObservableProperty]
private bool _passwayIsOpen ;
/// <summary>
/// 矫正重量
/// </summary>
public float CorrectMatetailWeight { get { return _CorrectMatetailWeight; } set { _CorrectMatetailWeight = value; OnPropertyChanged(); } }
private float _CorrectMatetailWeight = 0;
[ObservableProperty]
private int _correctMatetailWeight = 0;
/// <summary>
/// 矫正时间
/// </summary>
public int OutTime { get { return _0utTime; } set { _0utTime = value; OnPropertyChanged(); } }
private int _0utTime = 0;
[ObservableProperty]
private int _outTime = 0;

public bool IsEnable { get { return !GLobal.makeEnable; } set { GLobal.makeEnable = !value; OnPropertyChanged(); } }
/// <summary>
/// 出料动作
/// </summary>
public RelayCommand OutMaterailCommad { get; set; }
/// <summary>
/// 转动转盘
/// </summary>
public RelayCommand TurntableCommad { get; set; }
[RelayCommand]
private void OutMaterial()
{
ActionManage.GetInstance.Send("通道口出料", new object[] { MaterialID, OutMaterilWeight });
}
/// <summary>
/// 开始矫正
/// </summary>
public RelayCommand CheckPasswayCommad { get; set; }
[RelayCommand]
private void CheckPassway()
{

}
/// <summary>
/// 开启通道
/// </summary>
public RelayCommand OpenPasswayCommand { get; set; }
[RelayCommand]
private void OpenPassway()
{

}
/// <summary>
/// 确认重量
/// </summary>
public RelayCommand CheckMaterailWeightCommand { get; set; }
[RelayCommand]
private void CheckMaterailWeight()
{

}
#region 设备配置
/// <summary>
/// 店铺名称
/// </summary>
public string ShopName { get { return _shopName; } set { _shopName = value; OnPropertyChanged(); } }
private string _shopName;
[ObservableProperty]
private string? _shopName = string.Empty;
/// <summary>
/// 店铺ID
/// </summary>
public string ShopID { get { return _shopID; } set { _shopID = value; OnPropertyChanged(); } }
private string _shopID;
[ObservableProperty]
private string? _shopID = string.Empty;
/// <summary>
/// 设备ID
/// </summary>
public string DeviceID { get { return _deviceID; } set { _deviceID = value; OnPropertyChanged(); } }
private string _deviceID;
[ObservableProperty]
private string? _deviceID = string.Empty;
/// <summary>
/// PLC地址
/// </summary>
public string PLCAdress { get { return _pLCAdress; } set { _pLCAdress = value; OnPropertyChanged(); } }
private string _pLCAdress;
[ObservableProperty]
private string? _pLCAdress = string.Empty;

public RelayCommand SaveDevicesCommand { get; set; }
#endregion
[ObservableProperty]
private bool _isPort = true;

public PatrameterSettiongViewModel()
{
OutMaterailCommad = new RelayCommand(new Action(() =>
{
ActionManage.GetInstance.Send("通道口出料", new object[] { MaterialID +1, OutMaterailWeight });
[ObservableProperty]
private Visibility _vsIP = Visibility.Hidden;

}));
[ObservableProperty]
private Visibility _vsPort = Visibility.Visible;

TurntableCommad = new RelayCommand(new Action(() =>
{
ActionManage.GetInstance.Send("转盘转动", new object[] { TurntableID });
}));

OpenPasswayCommand = new RelayCommand(new Action(() =>
{
if(PasswayIsOpen) ActionManage.GetInstance.Send("开启通道", new object[] { CorrectPassway + 1 });
[ObservableProperty]
private string[] _ports;

}));
[ObservableProperty]
private string _prot;

CheckPasswayCommad = new RelayCommand(new Action(() =>
[RelayCommand]
private void SaveDevices()
{
SaveDeviceMessage();
}
[RelayCommand]
private void ChangeCommunation()
{
if(IsPort)
{
ActionManage.GetInstance.Send("开始矫正", new object[] { CorrectPassway + 1,OutTime });
}));

CheckMaterailWeightCommand = new RelayCommand(new Action(() =>
VsPort = Visibility.Visible;
VsIP = Visibility.Hidden;
}
else
{
ActionManage.GetInstance.Send("矫正重量", new object[] { CorrectPassway + 1, CorrectMatetailWeight });
}));

SaveDevicesCommand = new RelayCommand(SaveDeviceMessage);
VsIP = Visibility.Visible;
VsPort = Visibility.Hidden;
}
}
#endregion

public PatrameterSettiongViewModel()
{
Ports = System.IO.Ports.SerialPort.GetPortNames();
init();
}
private void init()
{
foreach (MaterialPosion materialPosion in Enum.GetValues(typeof(MaterialPosion)))
for (int i = 1; i < 14; i++)
{
materialPosions.Add(materialPosion);
materialPosions.Add(i);
}

foreach (OutMaterialPosion outMaterialPosion in Enum.GetValues(typeof(OutMaterialPosion)))
if (GLobal.deviceConfig.Count > 0)
{
TurntablePosion.Add(outMaterialPosion);
ShopName = GLobal.deviceConfig.ElementAtOrDefault(0).ShopName ;
ShopID = GLobal.deviceConfig.ElementAtOrDefault(0).ShopId;
DeviceID = GLobal.deviceConfig.ElementAtOrDefault(0).deviceModels.ElementAt(0).DeviceId;
PLCAdress = GLobal.deviceConfig.ElementAtOrDefault(0).deviceModels.ElementAt(0).communicationDevcies.ElementAt(0).communicationPar.IPAddress;
}
ShopName = GLobal.deviceConfig.ElementAt(0).ShopName;
ShopID = GLobal.deviceConfig.ElementAt(0).ShopId;
DeviceID = GLobal.deviceConfig.ElementAt(0).deviceModels.ElementAt(0).DeviceId;
PLCAdress = GLobal.deviceConfig.ElementAt(0).deviceModels.ElementAt(0).communicationDevcies.ElementAt(0).communicationPar.IPAddress;
}

private void SaveDeviceMessage()
{
if (GLobal.deviceConfig.Count > 0)
{
GLobal.deviceConfig.ElementAt(0).ShopName = ShopName;
GLobal.deviceConfig.ElementAt(0).ShopId = ShopID;
GLobal.deviceConfig.ElementAt(0).deviceModels.ElementAt(0).DeviceId = DeviceID;
GLobal.deviceConfig.ElementAt(0).deviceModels.ElementAt(0).Id = Guid.NewGuid().ToString();
GLobal.deviceConfig.ElementAt(0).deviceModels.ElementAt(0).communicationDevcies.ElementAt(0).communicationPar.IPAddress = PLCAdress;
File.WriteAllText($"{LocaPath.GetInstance().GetDeviceConfigPath}奶茶味魔方.json", JsonConvert.SerializeObject(GLobal.deviceConfig));
GLobal.deviceConfig.ElementAtOrDefault(0).ShopName = ShopName;
GLobal.deviceConfig.ElementAtOrDefault(0).ShopId = ShopID;
GLobal.deviceConfig.ElementAtOrDefault(0).deviceModels.ElementAtOrDefault(0).DeviceId = DeviceID;
if(IsPort)
{
GLobal.deviceConfig.ElementAtOrDefault(0).deviceModels.ElementAtOrDefault(0).communicationDevcies.ElementAtOrDefault(0).communicationPar.IsSerialPort = true;
GLobal.deviceConfig.ElementAtOrDefault(0).deviceModels.ElementAtOrDefault(0).communicationDevcies.ElementAtOrDefault(0).communicationPar.SerialPort = Prot;
GLobal.deviceConfig.ElementAtOrDefault(0).deviceModels.ElementAtOrDefault(0).communicationDevcies.ElementAtOrDefault(0).communicationPar.BaudRate = 9600;
}
else
{
GLobal.deviceConfig.ElementAtOrDefault(0).deviceModels.ElementAtOrDefault(0).communicationDevcies.ElementAtOrDefault(0).communicationPar.IsSerialPort = false;
GLobal.deviceConfig.ElementAtOrDefault(0).deviceModels.ElementAtOrDefault(0).communicationDevcies.ElementAtOrDefault(0).communicationPar.IsNetworkPort = true;
GLobal.deviceConfig.ElementAtOrDefault(0).deviceModels.ElementAtOrDefault(0).communicationDevcies.ElementAtOrDefault(0).communicationPar.IPAddress = PLCAdress;
}
}
File.WriteAllText($"{LocaPath.GetInstance().GetDeviceConfigPath}MOC.json", JsonConvert.SerializeObject(GLobal.deviceConfig));


}

}
}

+ 75
- 0
BPASmartClient.MilkWithTea/ViewModel/RecipeConfigeViewModel.cs Переглянути файл

@@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;

namespace BPASmartClient.MilkWithTea.ViewModel
{
partial class RecipeConfigeViewModel:ObservableObject
{
public static ObservableCollection<LocalMaterail> Materails { get; set; } = new ObservableCollection<LocalMaterail>();

public Dictionary<string,string> materialNames { get; set; } = new Dictionary<string,string>();

[ObservableProperty]
private string _name = String.Empty;


[RelayCommand]
private void AddMaterial()
{
Materails.Add(new LocalMaterail());
}
[RelayCommand]
private void Delete(object o)
{
if (o == null) return;
if(o is ListBoxItem id)
{
Materails.Remove((LocalMaterail)id.DataContext);
}
}
[RelayCommand]
private void Save()
{
if(Name == String.Empty)
{
return;
}
if(Json<JsonLocalRecipes>.Data.localRecipes.FirstOrDefault(p=>p.RecipeName == Name)!= null)
{
return;
}
foreach(var materail in Materails)
{
materail.MaterialName = materialNames[materail.MaterialID];
}
Json<JsonLocalRecipes>.Data.localRecipes.Add(new LocalRecipe
{
RecipeID = Guid.NewGuid().ToString(),
RecipeName = Name,
localMaterails = Materails,
});

Json<JsonLocalRecipes>.Save();
ActionManage.GetInstance.Send("RecipeConfigeViewClose");
}

public RecipeConfigeViewModel()
{
if(Json<JsonLocalRecipes>.Data.localMaterails.Count > 0)
{
foreach(var item in Json<JsonLocalRecipes>.Data.localMaterails)
{
if(item.MaterialID!=null&&item.MaterialName!=null)
{
materialNames.Add(item.MaterialID, item.MaterialName);
}
}
}
Materails.Clear();
}
}
}

+ 54
- 13
BPASmartClient.Modbus/ModbusTcp.cs Переглянути файл

@@ -1,5 +1,5 @@
using BPASmartClient.Helper;
using BPASmartClient.Message;
//using BPASmartClient.Message;
using NModbus;
using System;
using System.Collections.Generic;
@@ -25,6 +25,8 @@ namespace BPASmartClient.Modbus
private ManualResetEvent mre = new ManualResetEvent(false);
public string IPAdress;
public int Port;
public Action<string> Show { get; set; }
public Action<string> ShowEx { get; set; }

/// <summary>
/// 连接plc 原料设备成功
@@ -49,7 +51,7 @@ namespace BPASmartClient.Modbus
/// <param name="port">端口号,默认502</param>
public void ModbusTcpConnect(string ip, int port = 502)
{
MessageLog.GetInstance.Show($"设备【{ip}:{port}】连接中。。。。");
Show?.Invoke($"设备【{ip}:{port}】连接中。。。。");
IPAdress = ip;
Port = port;
modbusFactory = new ModbusFactory();
@@ -60,7 +62,7 @@ namespace BPASmartClient.Modbus
master.Transport.WriteTimeout = 2000;//写入超时时间
master.Transport.Retries = 10;//重试次数
ConnectOk?.Invoke();
MessageLog.GetInstance.Show($"设备【{ip}:{port}】连接成功");
Show?.Invoke($"设备【{ip}:{port}】连接成功");
}
else
{
@@ -94,15 +96,15 @@ namespace BPASmartClient.Modbus
{
if (!ErrorFlag)
{
MessageLog.GetInstance.ShowEx($"ModbusTcp 连接失败,IP = {IPAdress},Port = {Port}");
MessageLog.GetInstance.ShowEx(ex.ToString());
ShowEx?.Invoke($"ModbusTcp 连接失败,IP = {IPAdress},Port = {Port}");
ShowEx?.Invoke(ex.ToString());
ErrorFlag = true;
}
if (!IsReconnect) break;
Thread.Sleep(3000);
}
}
if (ErrorFlag && IsReconnect) MessageLog.GetInstance.Show("ModbusTcp 重连成功!");
if (ErrorFlag && IsReconnect) Show?.Invoke("ModbusTcp 重连成功!");
}

/// <summary>
@@ -244,18 +246,54 @@ namespace BPASmartClient.Modbus
}
catch (Exception ex)
{
MessageLog.GetInstance.ShowEx($"读取地址:【{address}:= {startAddress}】,读取类型:【{commandType.ToString()}】出错,{ex.ToString()}");
ShowEx?.Invoke($"读取地址:【{address}:= {startAddress}】,读取类型:【{commandType.ToString()}】出错,{ex.ToString()}");
ExceptionHandling(ex);
}
return default(object);
}


/// <summary>
/// 写入数据
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="address">写入地址</param>
/// <param name="value">写入值</param>
/// <param name="Retries">重试次数</param>
/// <param name="slaveAddress">从站地址</param>
/// <returns></returns>
public bool Write<T>(string address, T value, int Retries = 1, byte slaveAddress = 1)
{
int count = 0;
if (Retries == 1 || Retries == 0)
{
return TempWrite(address, value, slaveAddress);
}
else if (Retries > 1)
{
bool isok = false;
while (count < Retries)
{
count++;
TempWrite(address, value, slaveAddress);
var res = Read(address);
if (res != null && res.ToString() == value.ToString())
{
isok = true;
break;
}
}
return isok;
}
return false;
}

public void Write<T>(string address, T value, byte slaveAddress = 1)
private bool TempWrite<T>(string address, T value, byte slaveAddress = 1)
{
if (address == null || tcpClient == null) return;
if (address == null || tcpClient == null)
{
Show?.Invoke("写入失败,地址为空或断开连接");
return false;
}
ushort startAddress = (ushort)GetAddress(address);
CommandType commandType = CommandType.Coils;
try
@@ -305,11 +343,14 @@ namespace BPASmartClient.Modbus
{
commandType = CommandType.Inputs;
}
Show?.Invoke($"成功,地址:{address},值:{value}");
return true;
}
catch (Exception ex)
{
MessageLog.GetInstance.ShowEx($"写入地址:【{address}:= {startAddress}】,写入类型:【{commandType.ToString()}】出错,{ex.ToString()}");
ShowEx?.Invoke($"写入地址:【{address}:= {startAddress}】,写入类型:【{commandType.ToString()}】出错,{ex.ToString()}");
ExceptionHandling(ex);
return false;
}
}

@@ -526,7 +567,7 @@ namespace BPASmartClient.Modbus
}
catch (Exception ex)
{
MessageLog.GetInstance.Show(ex.ToString());
ShowEx?.Invoke(ex.ToString());
tcpClient = null;
Connect();
}


+ 4
- 0
BPASmartClient.Model/BPASmartClient.Model.csproj Переглянути файл

@@ -21,4 +21,8 @@
<PackageReference Include="Microsoft.Toolkit.Mvvm" Version="7.1.2" />
</ItemGroup>

<ItemGroup>
<Folder Include="奶咖一体机\" />
</ItemGroup>

</Project>

+ 9
- 0
BPASmartClient.Model/柔性味魔方/RawMaterialModel.cs Переглянути файл

@@ -38,6 +38,15 @@ namespace BPASmartClient.Model
public ushort RawMaterialSource { get { return _mRawMaterialSource; } set { _mRawMaterialSource = value; OnPropertyChanged(); } }
private ushort _mRawMaterialSource;


/// <summary>
/// 选中索引
/// </summary>
[Newtonsoft.Json.JsonIgnore]
public int SelectIndex { get { return _mSelectIndex; } set { _mSelectIndex = value; OnPropertyChanged(); } }
private int _mSelectIndex;


/// <summary>
/// 原料类型 MW18
/// 1:液体


+ 78
- 165
BPASmartClient.MorkF/Control_MorkF.cs Переглянути файл

@@ -35,55 +35,38 @@ namespace BPASmartClient.MorkF
#region 调试代码
public void CommandRegist()
{
#region 设备控制
ActionManage.GetInstance.Register(PLCInite, "InitCommand");
ActionManage.GetInstance.Register(InitialData, "SimultaorOrder");
ActionManage.GetInstance.Register(MaterialOne, "MaterialOne");
ActionManage.GetInstance.Register(MaterialTwo, "MaterialTwo");
ActionManage.GetInstance.Register(MaterialThree, "MaterialThree");
ActionManage.GetInstance.Register(MaterialFour, "MaterialFour");
ActionManage.GetInstance.Register(MaterialFive, "MaterialFive");
ActionManage.GetInstance.Register(ManualOpenExhaust, "OpenExhaust");
ActionManage.GetInstance.Register(CloseExhaust, "CloaseExhaust");
ActionManage.GetInstance.Register(StartQX, "StartQXOne");
ActionManage.GetInstance.Register(StartQX, "StartQXTwo");

#endregion
ActionManage.GetInstance.Register(ShreddCabbage, "ShreddCabbage");
ActionManage.GetInstance.Register(FryPork, "FryPork");
ActionManage.GetInstance.Register(XingBaoGu, "XingBaoGu");

ActionManage.GetInstance.Register(TakePot, "TakePot");
ActionManage.GetInstance.Register(TakePotReset, "TakePotReset");
ActionManage.GetInstance.Register(TakeMaterial, "TakeMaterial");
ActionManage.GetInstance.Register(ManualOutMeal, "OutMeal");
#region 配料控制
ActionManage.GetInstance.Register(OutMaterials, "OutMaterials");
#endregion

#region 炒锅1
ActionManage.GetInstance.Register<Action>(AddOil, "AddOil");
ActionManage.GetInstance.Register(TakeOff, "TakeOff");
ActionManage.GetInstance.Register(OneBlock, "OneBlock");
ActionManage.GetInstance.Register(TwoBlock, "TwoBlock");
ActionManage.GetInstance.Register(ThreeBlock, "ThreeBlock");
ActionManage.GetInstance.Register(OverTurnOff, "OverTurnOff");
ActionManage.GetInstance.Register(OverOneBlock, "OverOneBlock");
ActionManage.GetInstance.Register(OverTwoBlock, "OverTwoBlock");
ActionManage.GetInstance.Register(OverThreeBlock, "OverThreeBlock");
ActionManage.GetInstance.Register(OverGoOn, "OverGoOn");
ActionManage.GetInstance.Register(OverGoDown, "OverGoDown");
ActionManage.GetInstance.Register(AutoModel, "AutoModel");
ActionManage.GetInstance.Register(ManualModel, "ManualModel");

ActionManage.GetInstance.Register<Action>(AddOil, "SecAddOil");
ActionManage.GetInstance.Register(TakeOff, "SecTakeOff");
ActionManage.GetInstance.Register(OneBlock, "SecOneBlock");
ActionManage.GetInstance.Register(TwoBlock, "SecTwoBlock");
ActionManage.GetInstance.Register(ThreeBlock, "SecThreeBlock");
ActionManage.GetInstance.Register(OverTurnOff, "SecOverTurnOff");
ActionManage.GetInstance.Register(OverOneBlock, "SecOverOneBlock");
ActionManage.GetInstance.Register(OverTwoBlock, "SecOverTwoBlock");
ActionManage.GetInstance.Register(OverThreeBlock, "SecOverThreeBlock");
ActionManage.GetInstance.Register(OverGoOn, "SecOverGoOn");
ActionManage.GetInstance.Register(OverGoDown, "SecOverGoDown");
ActionManage.GetInstance.Register(AutoModel, "SecAutoModel");
ActionManage.GetInstance.Register(ManualModel, "SecManualModel");
ActionManage.GetInstance.Register(StartFire, "StartFire");
ActionManage.GetInstance.Register(StopFire, "StopFire");
ActionManage.GetInstance.Register(StartStir, "StartStir");
ActionManage.GetInstance.Register(StopStir, "StopStir");
ActionManage.GetInstance.Register(OutFood, "OutFood");
ActionManage.GetInstance.Register(StirArmGoOrigin, "StirArmGoOrigin");
ActionManage.GetInstance.Register(StirArmGoWork, "StirArmGoWork");
ActionManage.GetInstance.Register(HBOTGoWork, "HBOTGoWork");
ActionManage.GetInstance.Register(OutMeal, "OutMeal");
ActionManage.GetInstance.Register(SetFire, "SetFire");
ActionManage.GetInstance.Register(SetStir, "SetStir");
#endregion

}

/// <summary>
/// 手撕包菜流程
/// </summary>
@@ -161,160 +144,91 @@ namespace BPASmartClient.MorkF
stirFryBom.AddAction(new StirFryAction() { Time = StirFryTime.T6, PotActions = new List<StirFryPotAction>() { StirFryPotAction.搅拌臂下位, StirFryPotAction.快速旋转 }, During = 55 });
stirFryBom.AddAction(new StirFryAction() { Time = StirFryTime.T11, RobotActions = new List<StirFryRobotAction>() { StirFryRobotAction.灶取锅 } });
}
public void StartQX(object obj)
//出配料
public void OutMaterials(object o)
{

if ((int)obj == 1)
WriteData("M1.4", true);
if ((int)obj == 2)
WriteData("M1.7", true);
}
public void ManualOpenExhaust()
{
WriteData("M0.7", true);
}
public void CloseExhaust()
{
WriteData("M0.7", false);
if (o == null) return;
if (o is List<int> ints && ints.Count == 2)
{
WriteControl(morkF.PassWayValue[ints[0]], ints[1]);//写入通道值
Thread.Sleep(500);
WriteControl(morkF.StartPassWay[ints[0]], true);//开启通道
}
}
public void TakeMaterial()

#region 炒锅1
//加热启动
public void StartFire()
{
WriteData("M14.1", true);
WriteControl("M0.1", true);
}
public void ManualOutMeal()
//加热停止
public void StopFire()
{
WriteData("M14.2", true);
WriteControl("M0.1", false);
}
public void MaterialOne()
//搅拌启动
public void StartStir()
{
WriteData("M13.0", true);
WriteControl("M0.2", true);
}
public void MaterialTwo()
//搅拌启停止
public void StopStir()
{
WriteData("M13.1", true);
WriteControl("M0.2", false);
}
public void MaterialThree()
//倒菜
public void OutFood()
{
WriteData("M13.2", true);
WriteControl("M0.3", true);
}
public void MaterialFour()
//搅拌臂去原点位
public void StirArmGoOrigin()
{
WriteData("M13.3", true);
WriteControl("M0.5", true);
}
public void MaterialFive()

//搅拌臂去炒制位
public void StirArmGoWork()
{
WriteData("M13.4", true);
WriteControl("M0.6", true);
}
public void AutoModel(object obj)
//HBOT放盒子到位
public void HBOTGoWork()
{

WriteData("0.3", true);

WriteControl("M0.7", true);
}
public void ManualModel()
//出餐启动
public void OutMeal()
{
WriteData("0.2", true);
WriteControl("M0.4", true);
}
public void AddOil(object obj)
//加热挡位设定
public void SetFire(object o)
{
if ((int)obj == 1)
if(o == null) return;
if(o is List<int> ints&&ints.Count == 1)
{
Task.Run(() => { WriteData("M2.7", true); Task.Delay(4000).Wait(); WriteData("M2.7", false); });
WriteControl("VW228",ints[0]);
}

if ((int)obj == 2)
{
Task.Run(() => { WriteData("M3.1", true); Task.Delay(4000).Wait(); WriteData("M3.1", false); });
}
}
public void TakePot(object obj)
{
WriteData("M14.0", true);
}

public void TakePotReset(object obj)
{
WriteData("M14.0", false);
}
public void TakeOff(object obj)
//搅拌挡位设定
public void SetStir(object o)
{
if ((int)obj == 1)
WriteData("M4.0", new bool[] { false, false, false, false, false, false, false, false });//0000 0000
if ((int)obj == 2)
WriteData("M5.0", new bool[] { false, false, false, false, false, false, false, false });//0000 0000
if (o == null) return;
if (o is List<int> ints && ints.Count == 1)
{
WriteControl("VW230", ints[0]);
}
}

public void OneBlock(object obj)
{
if ((int)obj == 1)
WriteData("M4.0", new bool[] { true, false, false, false, false, false, false, false });//0000 0001
if ((int)obj == 2)
WriteData("M5.0", new bool[] { true, false, false, false, false, false, false, false });//0000 0001

#endregion

}
public void TwoBlock(object obj)
{
if ((int)obj == 1)
WriteData("M4.0", new bool[] { false, true, false, false, false, false, false, false });//0000 0010
if ((int)obj == 2)
WriteData("M5.0", new bool[] { false, true, false, false, false, false, false, false });//0000 0010
}
public void ThreeBlock(object obj)
{
if ((int)obj == 1)
WriteData("M4.0", new bool[] { true, true, false, false, false, false, false, false });//0000 0011
if ((int)obj == 2)
WriteData("M5.0", new bool[] { true, true, false, false, false, false, false, false });//0000 0011
}
public void OverTurnOff(object obj)
{
if ((int)obj == 1)
WriteData("M7.0", true);
if ((int)obj == 2)
WriteData("M7.4", true);
}
public void OverOneBlock(object obj)
{
if ((int)obj == 1)
WriteData("M7.1", true);
if ((int)obj == 2)
WriteData("M7.5", true);
}
public void OverTwoBlock(object obj)
{
if ((int)obj == 1)
WriteData("M7.2", true);
if ((int)obj == 2)
WriteData("M7.6", true);
}
public void OverThreeBlock(object obj)
{
if ((int)obj == 1)
WriteData("M7.3", true);
if ((int)obj == 2)
WriteData("M7.7", true);
}
public void OverGoOn(object obj)
{
if ((int)obj == 1)
WriteData("M8.0", true);
if ((int)obj == 2)
WriteData("M8.4", true);
}

public void OverGoDown(object obj)
{
if ((int)obj == 1)
WriteData("M8.2", true);
if ((int)obj == 2)
WriteData("M8.6", true);
}
public void FlowInite()
{

}
/// <summary>
/// 订单初始化
/// </summary>
@@ -594,7 +508,6 @@ namespace BPASmartClient.MorkF
morkF.TakePlateQueue.Enqueue(new OrderLocInfo()
{
SuborderId = order.MorkOrder.SuborderId,

});
}
//}


+ 38
- 0
BPASmartClient.MorkF/GVL_MorkF.cs Переглянути файл

@@ -299,6 +299,44 @@ namespace BPASmartClient.MorkF
/// </summary>
public string CurrentOrderId { get; set; }
#endregion


public Dictionary<int,string> StartPassWay { get; set; } = new Dictionary<int, string>()
{
{1,"M3.0" },
{2,"M3.1" },
{3,"M3.2" },
{4,"M3.3" },
{5,"M3.4" },
{6,"M3.5" },
{7,"M3.6" },
{8,"M3.7" },
{9,"M4.0" },
{10,"M4.1" },
{11,"M4.2" },
{12,"M4.3" },
{13,"M4.4" },
{13,"M4.5" },

};

public Dictionary<int, string> PassWayValue { get; set; } = new Dictionary<int, string>()
{
{1,"VW200" },
{2,"VW202" },
{3,"VW204" },
{4,"VW206" },
{5,"VW208" },
{6,"VW210" },
{7,"VW212" },
{8,"VW214" },
{9,"VW216" },
{10,"VW218" },
{11,"VW220" },
{12,"VW222" },
{13,"VW224" },
{13,"VW226" },
};
}
}


+ 38
- 18
BPASmartClient.MorkF/View/DebugView.xaml Переглянути файл

@@ -47,29 +47,49 @@
</WrapPanel>
</GroupBox>
<StackPanel Orientation="Vertical" Grid.Row="2">
<GroupBox Header="机器人控制" FontSize="15" Foreground="Aqua" VerticalAlignment="Center" Height="95">
<GroupBox Header="配料仓控制" FontSize="15" Foreground="Aqua" VerticalAlignment="Center" Height="95">
<WrapPanel Orientation="Horizontal" Grid.RowSpan="2" VerticalAlignment="Top" Margin="0,5,0,0" >
<Button Content="取锅" Command="{Binding TakePot}" Margin="10,0,10,0"></Button>
<!--<Button Content="取锅复位" Command="{Binding TakePotReset}" Margin="10,0,10,0"></Button>-->
<Button Content="取料" Command="{Binding TakeMaterial}" Margin="10,0,10,0"></Button>
<Button Content="出餐" Command="{Binding OutMeal}" Margin="10,0,10,0"></Button>
<TextBlock Text="通道号" Margin="5,0"/>
<ComboBox ItemsSource="{Binding PassageWays}" Width="120" Margin="5,0"
SelectedIndex="{Binding PassagePosition}"/>
<TextBlock Text="出料量" Margin="5,0"/>
<TextBox Text="{Binding Weight}" Margin="5,0" Width="100"/>
<TextBlock Text="g" Margin="0,0,10,0"/>
<Button Content="出料" Margin="10,0" Command="{Binding OutMaterials}"/>
</WrapPanel>
</GroupBox>

<GroupBox Header="炒锅1" FontSize="15" Foreground="Aqua" VerticalAlignment="Center" Height="140">
<WrapPanel VerticalAlignment="Top" Margin="0,5,0,0">
<Button Content="注油" Command="{Binding AddOil}" Margin="10,0,10,0"></Button>
<Button Content="加热关闭" Command="{Binding TempTurnOff}" Margin="10,0,10,0"></Button>
<Button Content="加热1挡" Command="{Binding OneBlock}" Margin="10,0,10,0"></Button>
<Button Content="加热2挡" Command="{Binding TwoBlock}" Margin="10,0,10,0"></Button>
<Button Content="加热3挡" Command="{Binding ThreeBlock}" Margin="10,0,10,0"></Button>
<Button Content="翻炒机关闭" Command="{Binding OverTurnOff}" Margin="10,0,10,0" Cursor="Hand"></Button>
<Button Content="翻炒机上升" Command="{Binding OverGoOn}" Margin="10,0,15,0" Cursor="Hand"></Button>
<Button Content="翻炒机下降" Command="{Binding OverGoDown}" Margin="10,0,10,0"></Button>
<Button Content="翻炒机1挡" Command="{Binding OverOneBlock}" Margin="10,0,10,0"></Button>
<Button Content="翻炒机2挡" Command="{Binding OverTwoBlock}" Margin="10,0,10,0"></Button>
<Button Content="翻炒机3挡" Command="{Binding OverThreeBlock}" Margin="10,0,10,0"></Button>
</WrapPanel>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<WrapPanel VerticalAlignment="Top" Margin="0,5,0,0">
<Button Content="注油" Command="{Binding AddOil}" Margin="10,0,10,0"></Button>
<Button Content="加热启动" Command="{Binding StartFire}" Margin="10,0,10,0"></Button>
<Button Content="加热停止" Command="{Binding StopFire}" Margin="10,0,10,0"></Button>
<Button Content="搅拌启动" Command="{Binding StartStir}" Margin="10,0,10,0" Cursor="Hand"></Button>
<Button Content="搅拌停止" Command="{Binding StopStir}" Margin="10,0,15,0" Cursor="Hand"></Button>
<Button Content="倒菜启动" Command="{Binding OutFood}" Margin="10,0,15,0" Cursor="Hand"/>
<Button Content="搅拌臂去原点位" Command="{Binding StirArmGoOrigin}" Margin="10,0,10,0"></Button>
<Button Content="搅拌臂去炒制位" Command="{Binding StirArmGoWork}" Margin="10,0,10,0"></Button>
<Button Content="HBOT放盒子到位" Command="{Binding HBOTGoWork}" Margin="10,0,10,0"></Button>
<Button Content="出餐启动" Command="{Binding OutMeal}" Margin="10,0,10,0"></Button>
</WrapPanel>
<WrapPanel Grid.Row="2">
<TextBlock Text="加热挡位:" Margin="10,0,0,0" />
<ComboBox ItemsSource="{Binding lstFire}" Width="80" Margin="10,0,10,0" HorizontalAlignment="Center" VerticalAlignment="Center"
SelectedValue="{Binding FireGear}"/>
<Button Content="设定" Margin="0,0,30,0" Command="{Binding SetFire}"/>
<TextBlock Text="搅拌挡位:" Margin="10,0,0,0" />
<ComboBox ItemsSource="{Binding lstStir}" Width="80" Margin="10,0,10,0" HorizontalAlignment="Center" VerticalAlignment="Center"
SelectedValue="{Binding StirGear}"/>
<Button Content="设定" Margin="0,0,30,0" Command="{Binding SetStir}"/>
</WrapPanel>
</Grid>
</GroupBox>
<GroupBox Header="炒锅2" FontSize="15" Foreground="Aqua" VerticalAlignment="Center" Height="140">
<WrapPanel VerticalAlignment="Top" Margin="0,5,0,0">


+ 83
- 42
BPASmartClient.MorkF/ViewModel/DebugViewModel.cs Переглянути файл

@@ -13,7 +13,7 @@ namespace BPASmartClient.MorkF.ViewModel
internal class DebugViewModel : ObservableObject
{
public bool SimOrderEnable { get { return General_Config.SimOrderAllow; } set { General_Config.SimOrderAllow = value; OnPropertyChanged(); } }
#region 设备控制
public RelayCommand PlcInite { get; set; }
public RelayCommand SimulateOrder { get; set; }
public RelayCommand MaterialOne { get; set; }
@@ -25,31 +25,64 @@ namespace BPASmartClient.MorkF.ViewModel
public RelayCommand CloaseExhaust { get; set; }
public RelayCommand StartQXOne { get; set; }
public RelayCommand StartQXTwo { get; set; }
#endregion

#region 菜品控制

public RelayCommand ShreddCabbage { get; set; }
public RelayCommand FryPork { get; set; }
public RelayCommand XingBaoGu { get; set; }
#endregion

public RelayCommand TakePot { get; set; }
public RelayCommand TakePotReset { get; set; }
public RelayCommand TakeMaterial { get; set; }
public RelayCommand OutMeal { get; set; }

#region 配料仓控制
public List<string> PassageWays = new List<string>()
{
"通道1",
"通道2",
"通道3",
"通道4",
"通道5",
"通道6",
"通道7",
"通道8",
"通道9",
"通道10",
"通道11",
"通道12",
"通道13",
"通道14",
};
public int PassagePosition { get { return _passagePosition; } set { _passagePosition = value; OnPropertyChanged(); } }
private int _passagePosition;
public int Weight { get { return _weight; } set { _weight = value; OnPropertyChanged(); } }
private int _weight;
public RelayCommand OutMaterials { get; set; }
#endregion

#region 炒锅1
public RelayCommand AddOil { get; set; }
public RelayCommand TempTurnOff { get; set; }
public RelayCommand OneBlock { get; set; }
public RelayCommand TwoBlock { get; set; }
public RelayCommand ThreeBlock { get; set; }
public RelayCommand OverTurnOff { get; set; }
public RelayCommand OverOneBlock { get; set; }
public RelayCommand OverTwoBlock { get; set; }
public RelayCommand OverThreeBlock { get; set; }
public RelayCommand OverGoOn { get; set; }
public RelayCommand OverGoDown { get; set; }
public RelayCommand AutoModel { get; set; }
public RelayCommand ManualModel { get; set; }
public RelayCommand StartFire { get; set; }
public RelayCommand StopFire { get; set; }
public RelayCommand StartStir { get; set; }
public RelayCommand StopStir { get; set; }
public RelayCommand OutFood { get; set; }
public RelayCommand StirArmGoOrigin { get; set; }
public RelayCommand StirArmGoWork { get; set; }
public RelayCommand HBOTGoWork { get; set; }
public RelayCommand OutMeal { get; set; }
public RelayCommand SetFire { get; set; }
public RelayCommand SetStir { get; set; }
public List<int> lstFire { get; set; } = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
public List<int> lstStir { get; set; } = new List<int>() { 1, 2, 3 };
public int FireGear { get { return _fireGear; } set { _fireGear = value; OnPropertyChanged(); } }
private int _fireGear;
public int StirGear { get { return _stirGear; } set { _stirGear = value; OnPropertyChanged(); } }
private int _stirGear;
#endregion


#region 炒锅2
public RelayCommand SecAddOil { get; set; }
public RelayCommand SecTempTurnOff { get; set; }
public RelayCommand SecOneBlock { get; set; }
@@ -63,44 +96,51 @@ namespace BPASmartClient.MorkF.ViewModel
public RelayCommand SecOverGoDown { get; set; }
public RelayCommand SecAutoModel { get; set; }
public RelayCommand SecManualModel { get; set; }
#endregion

public DebugViewModel()
{
#region 设备控制
PlcInite = new RelayCommand(() => { ActionManage.GetInstance.Send("InitCommand"); });

SimulateOrder = new RelayCommand(() => {ActionManage.GetInstance.Send("SimultaorOrder"); });
MaterialOne= new RelayCommand(() => { ActionManage.GetInstance.Send("MaterialOne"); });
SimulateOrder = new RelayCommand(() => { ActionManage.GetInstance.Send("SimultaorOrder"); });
MaterialOne = new RelayCommand(() => { ActionManage.GetInstance.Send("MaterialOne"); });
MaterialTwo = new RelayCommand(() => { ActionManage.GetInstance.Send("MaterialTwo"); });
MaterialThree = new RelayCommand(() => { ActionManage.GetInstance.Send("MaterialThree"); });
MaterialFour = new RelayCommand(() => { ActionManage.GetInstance.Send("MaterialFour"); });
MaterialFive = new RelayCommand(() => { ActionManage.GetInstance.Send("MaterialFive"); });
OpenExhaust = new RelayCommand(() => { ActionManage.GetInstance.Send("OpenExhaust"); });
CloaseExhaust = new RelayCommand(() => { ActionManage.GetInstance.Send("CloseExhaust"); });
StartQXOne=new RelayCommand(() => { ActionManage.GetInstance.Send("StartQXOne",1); });
StartQXTwo = new RelayCommand(() => { ActionManage.GetInstance.Send("StartQXTwo",2); });
StartQXOne = new RelayCommand(() => { ActionManage.GetInstance.Send("StartQXOne", 1); });
StartQXTwo = new RelayCommand(() => { ActionManage.GetInstance.Send("StartQXTwo", 2); });
#endregion
ShreddCabbage = new RelayCommand(() => { ActionManage.GetInstance.Send("ShreddCabbage"); });
FryPork = new RelayCommand(() => { ActionManage.GetInstance.Send("FryPork"); });
XingBaoGu = new RelayCommand(() => { ActionManage.GetInstance.Send("XingBaoGu"); });

TakePot = new RelayCommand(() => { ActionManage.GetInstance.Send("TakePot"); });
TakePotReset = new RelayCommand(() => { ActionManage.GetInstance.Send("TakePotReset"); });
TakeMaterial= new RelayCommand(() => { ActionManage.GetInstance.Send("TakeMaterial"); });
OutMeal = new RelayCommand(() => { ActionManage.GetInstance.Send("OutMeal"); });

AddOil = new RelayCommand(() => { ActionManage.GetInstance.Send("AddOil", 1); });
TempTurnOff = new RelayCommand(() => { ActionManage.GetInstance.Send("TakeOff", 1); });
OneBlock = new RelayCommand(() => { ActionManage.GetInstance.Send("OneBlock",1); });
TwoBlock = new RelayCommand(() => { ActionManage.GetInstance.Send("TwoBlock",1); });
ThreeBlock = new RelayCommand(() => { ActionManage.GetInstance.Send("ThreeBlock",1); });
OverTurnOff = new RelayCommand(() => { ActionManage.GetInstance.Send("OverTurnOff",1); });
OverOneBlock = new RelayCommand(() => { ActionManage.GetInstance.Send("OverOneBlock",1); });
OverTwoBlock = new RelayCommand(() => { ActionManage.GetInstance.Send("OverTwoBlock",1); });
OverThreeBlock = new RelayCommand(() => { ActionManage.GetInstance.Send("OverThreeBlock",1); });
OverGoOn = new RelayCommand(() => { ActionManage.GetInstance.Send("OverGoOn",1); });
OverGoDown = new RelayCommand(() => { ActionManage.GetInstance.Send("OverGoDown",1); });
AutoModel = new RelayCommand(()=>{ActionManage.GetInstance.Send("AutoModel",1); });
ManualModel = new RelayCommand(() => { ActionManage.GetInstance.Send("ManualModel",1); });

#region 配料仓控制
OutMaterials = new RelayCommand(() => { ActionManage.GetInstance.Send("OutMaterials" ,new List<int> { PassagePosition,Weight } ); });
#endregion


#region 炒锅1
AddOil = new RelayCommand(() => { ActionManage.GetInstance.Send("AddOil", 1); });//加油
StartFire = new RelayCommand(() => { ActionManage.GetInstance.Send("StartFire"); });//加热启动
StopFire = new RelayCommand(() => { ActionManage.GetInstance.Send("StopFire"); });//加热停止
StartStir = new RelayCommand(() => { ActionManage.GetInstance.Send("StartStir"); });//搅拌启动
StopStir = new RelayCommand(() => { ActionManage.GetInstance.Send("StopStir"); });//搅拌停止
OutFood = new RelayCommand(() => { ActionManage.GetInstance.Send("OutFood"); });//倒菜启动
StirArmGoOrigin = new RelayCommand(() => { ActionManage.GetInstance.Send("StirArmGoOrigin"); });//搅拌臂去原点位
StirArmGoWork = new RelayCommand(() => { ActionManage.GetInstance.Send("StirArmGoWork"); });//搅拌臂去炒制位
HBOTGoWork = new RelayCommand(() => { ActionManage.GetInstance.Send("HBOTGoWork"); });//放盒子到位
OutMeal = new RelayCommand(() => { ActionManage.GetInstance.Send("OutMeal"); });//出餐启动
SetFire = new RelayCommand(() => { ActionManage.GetInstance.Send("SetFire", new List<int> { FireGear }); });//加热挡位设定
SetStir = new RelayCommand(() => { ActionManage.GetInstance.Send("SetStir", new List<int> { StirGear }); });//搅拌挡位设定
#endregion



#region 炒锅2
SecAddOil = new RelayCommand(() => { ActionManage.GetInstance.Send("AddOil", 2); });
SecTempTurnOff = new RelayCommand(() => { ActionManage.GetInstance.Send("TakeOff", 2); });
SecOneBlock = new RelayCommand(() => { ActionManage.GetInstance.Send("OneBlock", 2); });
@@ -114,7 +154,8 @@ namespace BPASmartClient.MorkF.ViewModel
SecOverGoDown = new RelayCommand(() => { ActionManage.GetInstance.Send("OverGoDown", 2); });
SecAutoModel = new RelayCommand(() => { ActionManage.GetInstance.Send("AutoModel", 2); });
SecManualModel = new RelayCommand(() => { ActionManage.GetInstance.Send("ManualModel", 2); });
#endregion
}
}
}

+ 6
- 1
BPASmartClient.MorkMOC/BPASmartClient.MorkMOC.csproj Переглянути файл

@@ -1,11 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<OutputType>Library</OutputType>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.0.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\BPASmartClient.Device\BPASmartClient.Device.csproj" />
</ItemGroup>


+ 23
- 4
BPASmartClient.MorkMOC/Control_MorkMOC.cs Переглянути файл

@@ -1,6 +1,7 @@
using BPA.Message.Enum;
using BPASmartClient.Device;
using BPASmartClient.EventBus;
using BPASmartClient.Helper;
using BPASmartClient.Model;
using System;
using System.Collections.Generic;
@@ -13,15 +14,15 @@ namespace BPASmartClient.MorkMOC
{
public class Control_MorkMOC : BaseDevice
{
public override global::BPA.Message.Enum.DeviceClientType DeviceType { get { return BPA.Message.Enum.DeviceClientType.TMC_MT; } }

GVL_MorkMOC morkMoc = new GVL_MorkMOC();

PolymerBatching polymerBatching = new PolymerBatching();

//放大倍数
const int expand = 10;

public override DeviceClientType DeviceType => throw new NotImplementedException();

public override void DoMain()
{
ServerInit();
@@ -178,7 +179,25 @@ namespace BPASmartClient.MorkMOC

public override void SimOrder()
{
throw new NotImplementedException();
ActionManage.GetInstance.Register(new Action<object>((o) =>
{
if (o == null) return;
if(o is LocalRecipe recipe)
{
Dictionary<int, int> OrderPushes = new Dictionary<int, int>();
foreach(var item in recipe.localMaterails)
{
OrderPushes.Add(Convert.ToInt32(item.MaterialPosition), Convert.ToInt32(item.MaterialWeight));
}
morkMoc.morkOrderPushes.Enqueue(new OrderLocInfo()
{
GoodName = recipe.RecipeName,
SuborderId = Guid.NewGuid().ToString(),
GoodPushes = OrderPushes
});
}
}),"MakeGoods");
}

public override void Stop()


+ 55
- 0
BPASmartClient.MorkMOC/Model/LocalMaterail.cs Переглянути файл

@@ -0,0 +1,55 @@
using Microsoft.Toolkit.Mvvm.ComponentModel;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BPASmartClient.MorkMOC
{
public partial class LocalMaterail:ObservableObject
{
/// <summary>
/// 物料ID
/// </summary>
[ObservableProperty]
private string? _materialID;
/// <summary>
/// 物料本地名称
/// </summary>
[ObservableProperty]
private string? _materialName;
/// <summary>
/// 物料位置
/// </summary>
[ObservableProperty]
private int? _materialPosition;
/// <summary>
/// 物料重量
/// </summary>
[ObservableProperty]
private string? _materialWeight;


}

public partial class LocalRecipe:ObservableObject
{
/// <summary>
/// 配方ID
/// </summary>
[ObservableProperty]
private string? _recipeID;
/// <summary>
/// 配方名称
/// </summary>
[ObservableProperty]
private string? _recipeName;
/// <summary>
/// 原料集合
/// </summary>
public ObservableCollection<LocalMaterail> localMaterails { get; set; } = new ObservableCollection<LocalMaterail>();
}
}

+ 3
- 0
BPASmartClient.MorkMOC/OrderLocInfo.cs Переглянути файл

@@ -10,6 +10,9 @@ namespace BPASmartClient.MorkMOC
public string SuborderId { get; set; }
public ushort RecipeNumber { get; set; }
public string GoodName { get; set; }
/// <summary>
/// 物料位置,物料重量
/// </summary>
public Dictionary<int, int> GoodPushes { get; set; }
}



+ 2
- 0
BPASmartClient.MorkS/Control_Morks.cs Переглянути файл

@@ -271,9 +271,11 @@ namespace BPASmartClient.MorkS
{
mORKS.doOrderEvents.Add(order);
if (order.MorkOrder.GoodBatchings == null) return;
if (mORKS.HistorySuborderId.Contains(order.MorkOrder.SuborderId)) return;
OrderCount++;
OrderChange(order.MorkOrder.SuborderId, ORDER_STATUS.WAIT);
DeviceProcessLogShow($"接收到{OrderCount}次订单,订单ID:{order.MorkOrder.SuborderId}");
mORKS.HistorySuborderId.Add(order.MorkOrder.SuborderId);
foreach (var item in order.MorkOrder.GoodBatchings)
{
var res = orderMaterialDelivery?.BatchingInfo?.FirstOrDefault(p => p.BatchingId == item.BatchingId);


+ 1
- 0
BPASmartClient.MorkS/GVL_MORKS.cs Переглянути файл

@@ -12,6 +12,7 @@ namespace BPASmartClient.MorkS
{
public class GVL_MORKS : IStatus
{
public List<string> HistorySuborderId { get; set; } = new List<string>();
/// <summary>
/// 机器人取面
/// PLC -> M0.3


+ 4
- 0
BPASmartClient.MorkTM/Model/LocalTeaWithMilkConfig.cs Переглянути файл

@@ -29,6 +29,10 @@ namespace Model
public int MaterialID { get { return _materialID; } set { _materialID = value; OnPropertyChanged(); } }
private int _materialID =1;
/// <summary>
/// 物料本地名称
/// </summary>
public string MaterialName;
/// <summary>
/// 物料位置
/// </summary>
public string Material { get { return _material; } set { _material = value; OnPropertyChanged(); } }


+ 10
- 2
BPASmartClient.S7Net/SiemensHelper.cs Переглянути файл

@@ -58,9 +58,17 @@ namespace BPASmartClient.S7Net
return myPlc?.Read(dataType, db, address, varType, count);
}

public void Write<TValue>(string address, TValue value)
public string Write<TValue>(string address, TValue value)
{
if (IsConnected) myPlc?.Write(address, value);
if (IsConnected)
{
myPlc?.Write(address, value);
return $"成功,地址:{address},值:{value}";
}
else
{
return $"失败,地址:{address},值:{value},断开连接";
}
}

public TResult ReadClass<TResult>(int db, int startByteAdr = 0) where TResult : class, new()


+ 8
- 0
BPASmartClient.SCADAControl/BPASmartClient.SCADAControl.csproj Переглянути файл

@@ -23,6 +23,7 @@
<None Remove="Images\Cb_HalfChecked.png" />
<None Remove="Images\databj.png" />
<None Remove="Images\Exp.png" />
<None Remove="Images\Image_32x32.png" />
<None Remove="Images\leftImage.png" />
<None Remove="Images\mqtt.png" />
<None Remove="Images\mqttrun.png" />
@@ -53,6 +54,7 @@
<None Remove="Images\拉出.png" />
<None Remove="Images\收缩.png" />
<None Remove="Images\日期1.png" />
<None Remove="Images\暂无图片.png" />
<None Remove="Images\矩形边框.png" />
<None Remove="Images\矩形边框1.png" />
<None Remove="Images\系统名称.png" />
@@ -124,6 +126,9 @@
<Resource Include="Images\Exp.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Images\Image_32x32.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Images\leftImage.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
@@ -223,6 +228,9 @@
<Resource Include="Images\日期1.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Images\暂无图片.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Images\矩形边框.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>


+ 37
- 0
BPASmartClient.SCADAControl/CustomerControls/FYFTheListBox.xaml Переглянути файл

@@ -0,0 +1,37 @@
<UserControl x:Class="BPASmartClient.SCADAControl.CustomerControls.FYFTheListBox"
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:BPASmartClient.SCADAControl.CustomerControls"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<ListView
ItemsSource="{Binding ViewItems,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
Background="{x:Null}" Foreground="White"
PreviewMouseMove="ListView_PreviewMouseMove"
PreviewMouseLeftButtonUp="lisbox_PreviewMouseLeftButtonUp">
<ListBox.ItemTemplate>
<ItemContainerTemplate>
<Border x:Name="border" Tag="border" BorderBrush="Aquamarine" MouseLeftButtonDown="Border_MouseLeftButtonDown" BorderThickness="1" Padding="5" Background="#FF18888A">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="60"/>
<ColumnDefinition/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="60"/>
</Grid.ColumnDefinitions>
<TextBlock Margin="10,0,10,0" Grid.Column="0" Text="{Binding Name,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"></TextBlock>
<TextBlock Grid.Column="1" Text="{Binding Ph,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"></TextBlock>
<TextBox Width="100" Grid.Column="1"></TextBox>
<ComboBox Grid.Column="2" Width="60">
<ComboBoxItem>sdsds</ComboBoxItem>
<ComboBoxItem>sdsds</ComboBoxItem>
<ComboBoxItem>sdsds</ComboBoxItem>
</ComboBox>
</Grid>
</Border>
</ItemContainerTemplate>
</ListBox.ItemTemplate>
</ListView>
</UserControl>

+ 391
- 0
BPASmartClient.SCADAControl/CustomerControls/FYFTheListBox.xaml.cs Переглянути файл

@@ -0,0 +1,391 @@
using BPASmartClient.Compiler;
using Microsoft.Toolkit.Mvvm.ComponentModel;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Effects;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace BPASmartClient.SCADAControl.CustomerControls
{
/// <summary>
/// FYFTheListBox.xaml 的交互逻辑
/// </summary>
public partial class FYFTheListBox : UserControl
{
/// <summary>
/// 数据model
/// </summary>
public ListBoxDataModel TheListBoxModel = new ListBoxDataModel();
public event EventHandler PropertyChange; //声明一个事件
ListView listView = null;
public FYFTheListBox()
{
InitializeComponent();
this.DataContext = TheListBoxModel;
TheListBoxModel.ViewItems.Add(new ItemModel { Name = "张三", Ph = "125486545" });
TheListBoxModel.ViewItems.Add(new ItemModel { Name = "李四", Ph = "125486545" });
TheListBoxModel.ViewItems.Add(new ItemModel { Name = "王麻子", Ph = "125486545" });
TheListBoxModel.ViewItems.Add(new ItemModel { Name = "二货", Ph = "125486545" });
TheListBoxModel.ViewItems.Add(new ItemModel { Name = "张三1", Ph = "125486545" });
TheListBoxModel.ViewItems.Add(new ItemModel { Name = "李四2", Ph = "125486545" });
TheListBoxModel.ViewItems.Add(new ItemModel { Name = "王麻子3", Ph = "125486545" });
this.SizeChanged += Silos_SizeChanged; ;
}
private void Silos_SizeChanged(object sender, SizeChangedEventArgs e)
{
if (listView == null)
{
foreach (ListView tb in Utils.FindVisualChildren<ListView>(this))
{
// do something with tb here
listView = tb;
}
}
}

public string ControlType => "控件";

private bool isExecuteState;
public bool IsExecuteState
{
get { return isExecuteState; }
set
{
isExecuteState = value;
if (IsExecuteState)
{
Register();
}
}
}
public void Register()
{

}

#region 移动事件
/// <summary>
/// 当前拖动子控件流
/// </summary>
private UIElement ChildElement;
/// <summary>
/// 当前拖拽子控件Item
/// </summary>
private ListBoxItem ChildListBoxItem;
/// <summary>
/// 是否已经按下
/// </summary>
private bool isDown = false;
/// <summary>
/// 当前拖动的Pop窗体
/// </summary>
private Popup DropPopup = null;
/// <summary>
/// 鼠标按下事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Border_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
try
{
//isDown变量是防止多次操作。
if (isDown)
{
isDown = false;
return;
}

ChildElement = (UIElement)sender;
ChildElement.CaptureMouse();//设置了鼠标捕获,这样它可以不受到其它控件的影响。
ChildListBoxItem = Utils.FindVisualParent<ListBoxItem>(VisualTreeHelper.HitTest(ChildElement, e.GetPosition(ChildElement)).VisualHit);

//创建一个Pop,表明拖拽开始
CreatePopup(ChildElement, e);

isDown = true;
}
catch (Exception ex)
{

}
}
/// <summary>
/// 鼠标抬起事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void lisbox_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
try
{
//鼠标未按下返回
if (!isDown) return;

isDown = false;

//关闭Pop窗体
if (this.DropPopup != null)
{
this.DropPopup.IsOpen = false;
this.DropPopup.Child = null;
this.DropPopup = null;
}

//蒙层关闭,表明结束拖拽
MoveListBoxStyle(null, false);

//当控件具有鼠标捕获的话,则释放该捕获。
ChildElement.ReleaseMouseCapture();
}
catch (Exception ex)
{

}
}
/// <summary>
/// 鼠标移动事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ListView_PreviewMouseMove(object sender, MouseEventArgs e)
{
try
{
if (isDown == false) return;

if (e.LeftButton != MouseButtonState.Pressed)
lisbox_PreviewMouseLeftButtonUp(null, null);

Point ptLeftUp = new Point(0, 0);
Point ptRightDown = new Point(this.ActualWidth, this.ActualHeight);

ptLeftUp = this.PointToScreen(ptLeftUp);
ptRightDown = this.PointToScreen(ptRightDown);

double y = e.GetPosition(this).Y;
double x = e.GetPosition(this).X;

if (DropPopup != null)//下面两句是设置Popup控件的位置除以2是想让鼠标在它的中心
{
DropPopup.HorizontalOffset = ptLeftUp.X + x - ((FrameworkElement)ChildElement).ActualWidth / 2;
DropPopup.VerticalOffset = ptLeftUp.Y + y - ((FrameworkElement)ChildElement).ActualHeight / 2;
}

//蒙层打开,表明拖拽开始,设置透明度和显示状态
MoveListBoxStyle(e, true);
}
catch (Exception ex)
{
}
}
/// <summary>
/// 移动效果
/// </summary>
/// <param name="boxItem"></param>
private void MoveListBoxStyle(MouseEventArgs e, bool isBool)
{
try
{
if (isBool)//为真,根据鼠标位置设置行透明度和显示状态
{
//移动到某行减轻某行 暗黑
foreach (ListBoxItem item in Utils.FindVisualChildren<ListBoxItem>(listView))
{
if (item != ChildListBoxItem)//这就是其他控件
{
double item_width = item.ActualWidth; //当前行宽
double item_height = item.ActualHeight; //当前行高
double item_x = e.GetPosition(item).X; //鼠标相对当前行X位移
double item_y = e.GetPosition(item).Y; //鼠标相对当前行Y位移

if (item_y <= item_height && item_y > 0 && item_x > 0 && item_x <= item_width)//鼠标进入哪一行,则将那一行变灰
{
item.Opacity = 0.5;
int lao_index = TheListBoxModel.ViewItems.IndexOf(item.Content as ItemModel);
int new_index = TheListBoxModel.ViewItems.IndexOf(ChildListBoxItem.Content as ItemModel);
TheListBoxModel.ViewItems.Move(lao_index, new_index);
}
else //鼠标没在哪一行,则保持原状
{
item.Opacity = 1;
}
}
else
{
item.Visibility = Visibility.Hidden;
}
}
}
else//为假 恢复所有行透明度和显示状态
{
//移动到某行减轻某行 暗黑
foreach (ListBoxItem item in Utils.FindVisualChildren<ListBoxItem>(listView))
{
item.Opacity = 1;
item.Visibility = Visibility.Visible;
}
}
}
catch (Exception ex)
{
}
}
/// <summary>
/// 创建浮动窗口
/// </summary>
/// <param name="dragElement"></param>
/// <param name="e"></param>
private void CreatePopup(Visual dragElement, MouseButtonEventArgs e)
{
//使用PointToScreen函数可以将点转换为屏幕坐标
//首先获取当前窗体的左上角和右下角两点的坐标
Point ptLeftUp = new Point(0, 0);
//转换获取到这个窗口相对于屏幕两个坐标
ptLeftUp = this.PointToScreen(ptLeftUp);
//获取myGrid的实际宽高,主
double y = e.GetPosition(this).Y;
double x = e.GetPosition(this).X;

//拖拽Popup框
this.DropPopup = new Popup();
Border border = new Border();
border.Margin = new Thickness(0, 0, 8, 8);
DropShadowEffect effect = new DropShadowEffect();
effect.Opacity = 1;
effect.ShadowDepth = -14;
effect.BlurRadius = 9;
effect.Color = Color.FromArgb(100, 0, 0, 0);
border.Effect = effect;

//矩阵框
Rectangle r = new Rectangle();
r.Width = ((FrameworkElement)dragElement).ActualWidth;
r.Height = ((FrameworkElement)dragElement).ActualHeight;
r.Fill = new VisualBrush(dragElement);
border.Child = r;
this.DropPopup.Child = border;
DropPopup.AllowsTransparency = true;
DropPopup.HorizontalOffset = ptLeftUp.X + x - ((FrameworkElement)dragElement).ActualWidth / 2;
DropPopup.VerticalOffset = ptLeftUp.Y + y - ((FrameworkElement)dragElement).ActualHeight / 2;
this.DropPopup.IsOpen = true;
}
#endregion
}
/// <summary>
/// 当前项数据Model
/// </summary>
public class ListBoxDataModel : ObservableObject
{
private ObservableCollection<ItemModel> _ViewItems;
public ObservableCollection<ItemModel> ViewItems
{
get
{
return _ViewItems;
}
set
{
_ViewItems = value;
OnPropertyChanged("ViewItems");
}
}
public ListBoxDataModel()
{
ViewItems = new ObservableCollection<ItemModel>();
}
}
/// <summary>
/// 行数据Model
/// </summary>
public class ItemModel : ObservableObject
{
private string _Name;
public string Name
{
get
{
return _Name;
}
set
{
_Name = value;
OnPropertyChanged("Name");
}
}
private string _Ph;
public string Ph
{
get
{
return _Ph;
}
set
{
_Ph = value;
OnPropertyChanged("Ph");
}
}
}
/// <summary>
/// 帮助类
/// </summary>
internal static class Utils
{
/// <summary>
/// 根据子元素查找父元素
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="obj"></param>
/// <returns></returns>
public static T FindVisualParent<T>(DependencyObject obj) where T : class
{
while (obj != null)
{
if (obj is T)
return obj as T;

obj = VisualTreeHelper.GetParent(obj);
}
return null;
}
/// <summary>
/// 查询子控件
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="obj"></param>
/// <returns></returns>
public static IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
{
if (depObj != null)
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
if (child != null && child is T)
{
yield return (T)child;
}

foreach (T childOfChild in FindVisualChildren<T>(child))
{
yield return childOfChild;
}
}
}
}
}
}

+ 11
- 1
BPASmartClient.SCADAControl/CustomerControls/TheCheckBox.xaml.cs Переглянути файл

@@ -31,10 +31,20 @@ namespace BPASmartClient.SCADAControl.CustomerControls
public TheCheckBox()
{
InitializeComponent();
Content = "勾选框";
VerticalContentAlignment = VerticalAlignment.Center;
this.Loaded += TheButton_Loaded;
}
private void TheButton_Loaded(object sender, RoutedEventArgs e)
{
if (this.ActualWidth == 54 && this.Content.ToString()== "勾选框")
{
Content = "勾选框";
Width = 60;
Height = 30;
}
}

public string ControlType => "控件";




+ 1
- 1
BPASmartClient.SCADAControl/CustomerControls/TheImage.xaml Переглянути файл

@@ -5,5 +5,5 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:BPASmartClient.SCADAControl.CustomerControls"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800" Source="/BPASmartClient.SCADAControl;component/Images/State0.png">
d:DesignHeight="450" d:DesignWidth="800" Source="/BPASmartClient.SCADAControl;component/Images/暂无图片.png" Stretch="Fill">
</Image>

+ 6
- 7
BPASmartClient.SCADAControl/CustomerControls/TheImage.xaml.cs Переглянути файл

@@ -29,8 +29,7 @@ namespace BPASmartClient.SCADAControl.CustomerControls
public TheImage()
{
InitializeComponent();
Stretch = Stretch.UniformToFill;
//SetCurrentValue(SourceProperty, new BitmapImage(new Uri("pack://application:,,,/Images/借出.png", UriKind.Absolute)));
Stretch = Stretch.Fill;
Width = 80;
Height = 80;
}
@@ -58,9 +57,10 @@ namespace BPASmartClient.SCADAControl.CustomerControls
}
private void Refresh()
{
if (!string.IsNullOrEmpty(ImageStartPath) && File.Exists(ImageStartPath))
string path = $"{System.AppDomain.CurrentDomain.BaseDirectory}Images\\{ImageStartPath}";
if (!string.IsNullOrEmpty(ImageStartPath) && File.Exists(path))
{
Source = new BitmapImage(new Uri(ImageStartPath));
Source = new BitmapImage(new Uri(path));
}
}
public string ControlType => "控件";
@@ -83,11 +83,10 @@ namespace BPASmartClient.SCADAControl.CustomerControls
{
if (!string.IsNullOrEmpty(ImageStartPath))
{
string path = $"{System.AppDomain.CurrentDomain.BaseDirectory}Images\\{System.IO.Path.GetFileName(ImageStartPath)}";
string path = $"{System.AppDomain.CurrentDomain.BaseDirectory}Images\\{ImageStartPath}";
if (File.Exists(path))
{
ImageStartPath = path;
Source = new BitmapImage(new Uri(ImageStartPath));
Source = new BitmapImage(new Uri(path));
}
}
this.MouseLeftButtonDown += TheImage_MouseLeftButtonDown;


+ 10
- 0
BPASmartClient.SCADAControl/CustomerControls/TheRadioButton.cs Переглянути файл

@@ -27,6 +27,16 @@ namespace BPASmartClient.SCADAControl.CustomerControls
languageResDic.Source = new Uri(@"/BPASmartClient.SCADAControl;component/Themes/Generic.xaml",UriKind.RelativeOrAbsolute);
this.Resources.MergedDictionaries.Add(languageResDic);
SetCurrentValue(ContentProperty, "单选按钮");
this.Loaded += TheButton_Loaded;
}
private void TheButton_Loaded(object sender, RoutedEventArgs e)
{
if (this.ActualWidth <= 70 && this.Content.ToString() == "单选按钮")
{
Content = "单选按钮";
Width = 78;
Height = 24;
}
}
static TheRadioButton()
{


+ 1
- 1
BPASmartClient.SCADAControl/CustomerControls/TheTabControl.xaml.cs Переглянути файл

@@ -42,7 +42,7 @@ namespace BPASmartClient.SCADAControl.CustomerControls
{
try
{
object _header = (this.SelectedItem as TabItem).Header;
object _header = (this.SelectedItem as TabItem)?.Header;
TabItems?.ToList().ForEach(par =>
{
if (_header!=null && par.Header == (string)_header)





+ 15
- 36
BPASmartClient.SCADAControl/Themes/Generic.xaml Переглянути файл

@@ -395,7 +395,7 @@
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="Background">
<Setter.Value>
<ImageBrush ImageSource="../Images/button2.png" />
<ImageBrush ImageSource="../Images/button1.png" />
</Setter.Value>
</Setter>
<Setter Property="Foreground" Value="{DynamicResource ButtonSelectForeground}" />
@@ -427,20 +427,12 @@
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="true">
<Setter TargetName="BD" Property="Background">
<Setter.Value>
<ImageBrush ImageSource="../Images/button2.png" />
</Setter.Value>
</Setter>
<Setter TargetName="textBlock" Property="Foreground" Value="{DynamicResource MeunSelectForeground}" />
<Setter TargetName="BD" Property="Opacity" Value="1"/>
<Setter TargetName="textBlock" Property="Opacity" Value="1" />
</Trigger>
<Trigger Property="IsChecked" Value="False">
<Setter TargetName="BD" Property="Background">
<Setter.Value>
<ImageBrush ImageSource="../Images/button1.png" />
</Setter.Value>
</Setter>
<Setter TargetName="textBlock" Property="Foreground" Value="{DynamicResource ButtonSelectForeground}" />
<Setter TargetName="BD" Property="Opacity" Value="0.5"/>
<Setter TargetName="textBlock" Property="Opacity" Value="0.5" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="textBlock" Property="Foreground" Value="{DynamicResource ButtonUnSelectForeground}" />
@@ -500,7 +492,7 @@
</Style>

<Style TargetType="{x:Type ctrl:NumberBox}">
<Setter Property="BorderBrush" Value="{x:Static Themes1:ClassicBorderDecorator.ClassicBorderBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource borderBrush}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Padding" Value="0" />
<Setter Property="Foreground" Value="{DynamicResource foreground}" />
@@ -519,9 +511,10 @@
<ControlTemplate TargetType="{x:Type TextBox}">
<Themes1:ClassicBorderDecorator
x:Name="Bd"
BorderBrush="{DynamicResource borderBrush}"
BorderStyle="None"
BorderThickness="1">
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ScrollViewer x:Name="PART_ContentHost" />
</Themes1:ClassicBorderDecorator>
<ControlTemplate.Triggers>
@@ -758,14 +751,10 @@
SnapsToDevicePixels="True">
<Grid>
<Image
Width="12"
Height="14"
Source="../Images/Cb_HalfChecked.png" />
Source="../Images/Cb_HalfChecked.png" Margin="0,8,2,8" VerticalAlignment="Center" />
<Image
x:Name="image1"
Width="12"
Height="14"
Source="../Images/Cb_HalfChecked.png" />
Source="../Images/Cb_HalfChecked.png" Margin="0,8,2,8" VerticalAlignment="Center" />
</Grid>
<ContentPresenter
Margin="{TemplateBinding Padding}"
@@ -1505,23 +1494,13 @@
<ControlTemplate TargetType="{x:Type RadioButton}">
<BulletDecorator VerticalAlignment="Center" Background="Transparent">
<BulletDecorator.Bullet>
<Grid>
<Ellipse
x:Name="Border"
Width="10"
Height="10"
Fill="{TemplateBinding Background}" />
<Ellipse
x:Name="Dot"
Width="5"
Height="5"
Fill="#ff8a03"
Visibility="Hidden" />
<Grid Height="{TemplateBinding Height}" Width="{TemplateBinding Height}">
<Ellipse x:Name="Border" Margin="0,5,10,5" Fill="{TemplateBinding Background}" Stroke="{TemplateBinding BorderBrush}" StrokeThickness="{TemplateBinding BorderThickness}"/>
<Ellipse x:Name="Dot" Width="{Binding Width,ElementName=Border}" Height="{Binding Height,ElementName=Border}" Margin="0,5,10,5" Fill="{TemplateBinding Foreground}" />
</Grid>

</BulletDecorator.Bullet>
<ContentPresenter
Margin="{TemplateBinding Padding}"
Margin="-5,0,0,0"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
RecognizesAccessKey="True" />



+ 3
- 0
BPASmartClient.SmallBatchingSystem/Models/BaseModel.cs Переглянути файл

@@ -16,5 +16,8 @@ namespace BPASmartClient.SmallBatchingSystem
public RelayCommand SaveCommand { get; set; }
public RelayCommand<object> RemoveCommand { get; set; }
public RelayCommand<object> DetailsCommand { get; set; }
public string ErrorInfo { get { return _mErrorInfo; } set { _mErrorInfo = value; OnPropertyChanged(); } }
private string _mErrorInfo;

}
}

+ 27
- 4
BPASmartClient.SmallBatchingSystem/ViewModels/NewOutletViewModel.cs Переглянути файл

@@ -38,18 +38,41 @@ namespace BPASmartClient.SmallBatchingSystem.ViewModels
SiloInfos.ToList()?.ForEach(item => { SileNames.Add(item.RawMaterialName); });
if (Index >= 0 && Index < Json<ConfigInfoModel>.Data.OutletInfoModels.Count)
{
var array = Json<ConfigInfoModel>.Data.OutletInfoModels.ToArray();
var res = Array.FindIndex(array, p => p.OutletName == OutletName);
if (res >= 0 && res != Index)
{
ErrorInfo = "出料口名称已经存在!";
return;
}

var temp = Array.FindIndex(array, p => p.OutletLoc == OutletLoc);
if (temp >= 0 && temp != Index)
{
ErrorInfo = "出料口位置已存在!";
return;
}
Json<ConfigInfoModel>.Data.OutletInfoModels.ElementAt(Index).OutletName = OutletName;
Json<ConfigInfoModel>.Data.OutletInfoModels.ElementAt(Index).OutletLoc = OutletLoc;
Json<ConfigInfoModel>.Data.OutletInfoModels.ElementAt(Index).SiloInfos.Clear();
//SileNames.ToList()?.ForEach(temp =>
//{
// Json<ConfigInfoModel>.Data.OutletInfoModels.ElementAt(Index).SiloInfos.Add(temp);
//});
Json<ConfigInfoModel>.Data.OutletInfoModels.ElementAt(Index).SiloInfos = SileNames;
Control.GetInstance.OperationLog($"{OutletName} 编辑完成");
}
else
{
var res = Json<ConfigInfoModel>.Data.OutletInfoModels.FirstOrDefault(p => p.OutletName == OutletName);
if (res != null)
{
ErrorInfo = "出料口名称已经存在!";
return;
}

var temp = Json<ConfigInfoModel>.Data.OutletInfoModels.FirstOrDefault(p => p.OutletLoc == OutletLoc);
if (temp != null)
{
ErrorInfo = "出料口位置已存在!";
return;
}
Json<ConfigInfoModel>.Data.OutletInfoModels.Add(new OutletInfoModel()
{
OutletLoc = OutletLoc,


+ 15
- 1
BPASmartClient.SmallBatchingSystem/ViewModels/NewRecipeViewModel.cs Переглянути файл

@@ -22,7 +22,7 @@ namespace BPASmartClient.SmallBatchingSystem.ViewModels
RecipeName = tempRecipeInfo.RecipeName;
tempRecipeInfo.SiloInfoModels.ToList()?.ForEach(item =>
{
int tempIndex = Array.FindIndex(SileName.ToArray(), p => p.Contains(item.SiloName));
int tempIndex = Array.FindIndex(SileName.ToArray(), p => p == item.SiloName);
SiloInfos.Add(new RecipeRawMaterialInfo() { SiloName = item.SiloName, SiloWeight = item.SiloWeight, SelectIndex = tempIndex });
});
Index = Array.FindIndex(Json<ConfigInfoModel>.Data.Recipes.ToArray(), p => p.RecipeName == tempRecipeInfo.RecipeName);
@@ -34,6 +34,13 @@ namespace BPASmartClient.SmallBatchingSystem.ViewModels
{
if (Index >= 0 && Index < Json<ConfigInfoModel>.Data.OutletInfoModels.Count)
{
var res = Array.FindIndex(Json<ConfigInfoModel>.Data.Recipes.ToArray(), p => p.RecipeName == RecipeName);
if (res >= 0 && res != Index)
{
ErrorInfo = "配方名称已经存在!";
return;
}

Json<ConfigInfoModel>.Data.Recipes.ElementAt(Index).RecipeName = RecipeName;
Json<ConfigInfoModel>.Data.Recipes.ElementAt(Index).SiloInfoModels.Clear();
SiloInfos.ToList()?.ForEach(item =>
@@ -44,6 +51,13 @@ namespace BPASmartClient.SmallBatchingSystem.ViewModels
}
else
{
var res = Json<ConfigInfoModel>.Data.Recipes.FirstOrDefault(p => p.RecipeName == RecipeName);
if (res != null)
{
ErrorInfo = "配方名称已经存在!";
return;
}

Json<ConfigInfoModel>.Data.Recipes.Add(new RecipeInfo()
{
RecipeName = RecipeName,


+ 28
- 17
BPASmartClient.SmallBatchingSystem/ViewModels/NewSiloViewModel.cs Переглянути файл

@@ -16,28 +16,43 @@ namespace BPASmartClient.SmallBatchingSystem.ViewModels
CancelCommand = new RelayCommand(() => { ActionManage.GetInstance.Send("SiloClose"); });
SaveCommand = new RelayCommand(() =>
{
var res = Json<ConfigInfoModel>.Data.SiloInfoModels.FirstOrDefault(p => p.SiloName == SiloInfoModelObj.SiloName);
if (res != null)
if (Index >= 0 && Index < Json<ConfigInfoModel>.Data.SiloInfoModels.Count)
{
ErrorInfo = "料仓名称已经存在!";
return;
}
var array = Json<ConfigInfoModel>.Data.SiloInfoModels.ToArray();
var res = Array.FindIndex(array, p => p.SiloName == SiloInfoModelObj.SiloName);
if (res >= 0 && res != Index)
{
ErrorInfo = "料仓名称已经存在!";
return;
}

var temp = Json<ConfigInfoModel>.Data.SiloInfoModels.FirstOrDefault(p => p.SiloLoc == SiloInfoModelObj.SiloLoc);
if (temp != null)
{
ErrorInfo = "料仓位置已存在!";
return;
}
var temp = Array.FindIndex(array, p => p.SiloLoc == SiloInfoModelObj.SiloLoc);
if (temp >= 0 && temp != Index)
{
ErrorInfo = "料仓位置已存在!";
return;
}

if (Index >= 0 && Index < Json<ConfigInfoModel>.Data.SiloInfoModels.Count)
{
Json<ConfigInfoModel>.Data.SiloInfoModels.ElementAt(Index).SiloName = SiloInfoModelObj.SiloName;
Json<ConfigInfoModel>.Data.SiloInfoModels.ElementAt(Index).SiloLoc = SiloInfoModelObj.SiloLoc;
Control.GetInstance.OperationLog($"{SiloInfoModelObj.SiloName} 编辑完成");
}
else
{
var res = Json<ConfigInfoModel>.Data.SiloInfoModels.FirstOrDefault(p => p.SiloName == SiloInfoModelObj.SiloName);
if (res != null)
{
ErrorInfo = "料仓名称已经存在!";
return;
}

var temp = Json<ConfigInfoModel>.Data.SiloInfoModels.FirstOrDefault(p => p.SiloLoc == SiloInfoModelObj.SiloLoc);
if (temp != null)
{
ErrorInfo = "料仓位置已存在!";
return;
}

Json<ConfigInfoModel>.Data.SiloInfoModels.Add(new SiloInfoModel()
{
SiloLoc = SiloInfoModelObj.SiloLoc,
@@ -62,9 +77,5 @@ namespace BPASmartClient.SmallBatchingSystem.ViewModels
public SiloInfoModel SiloInfoModelObj { get { return _mSiloInfoModelObj; } set { _mSiloInfoModelObj = value; OnPropertyChanged(); } }
private SiloInfoModel _mSiloInfoModelObj = new SiloInfoModel();


public string ErrorInfo { get { return _mErrorInfo; } set { _mErrorInfo = value; OnPropertyChanged(); } }
private string _mErrorInfo;

}
}

+ 8
- 0
BPASmartClient.SmallBatchingSystem/Views/NewOutletView.xaml Переглянути файл

@@ -95,6 +95,14 @@
FontSize="20"
Style="{StaticResource TextBoxStyle}" />-->

<TextBlock
Margin="0,0,5,0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="20"
Foreground="#FFF53F62"
Text="{Binding ErrorInfo}" />

<Button
Width="90"
Height="30"


+ 9
- 1
BPASmartClient.SmallBatchingSystem/Views/NewRecipeView.xaml Переглянути файл

@@ -10,9 +10,9 @@
Title="NewPfView"
Width="500"
Height="300"
Topmost="True"
AllowsTransparency="True"
Background="{x:Null}"
Topmost="True"
WindowStartupLocation="CenterScreen"
WindowStyle="None"
mc:Ignorable="d">
@@ -51,6 +51,14 @@
Style="{StaticResource TextBlockStyle}"
Text="配方名称:" />

<TextBlock
Margin="0,0,10,0"
HorizontalAlignment="Right"
VerticalAlignment="Center"
FontSize="20"
Foreground="#FFF53F62"
Text="{Binding ErrorInfo}" />

<StackPanel
Grid.Row="1"
Margin="10,0,0,0"


+ 22
- 0
BPASmartClient.SmallBatchingSystem/Views/PromptView.xaml Переглянути файл

@@ -0,0 +1,22 @@
<Window
x:Class="BPASmartClient.SmallBatchingSystem.Views.PromptView"
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:local="clr-namespace:BPASmartClient.SmallBatchingSystem.Views"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="PromptView"
Width="400"
Height="200"
AllowsTransparency="True"
Background="{x:Null}"
WindowStartupLocation="CenterScreen"
WindowStyle="None"
mc:Ignorable="d">
<Grid>
<Grid.Background>
<ImageBrush ImageSource="/BPASmartClient.CustomResource;component/Image/弹窗.png" Stretch="Fill" />
</Grid.Background>

</Grid>
</Window>

+ 27
- 0
BPASmartClient.SmallBatchingSystem/Views/PromptView.xaml.cs Переглянути файл

@@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace BPASmartClient.SmallBatchingSystem.Views
{
/// <summary>
/// PromptView.xaml 的交互逻辑
/// </summary>
public partial class PromptView : Window
{
public PromptView()
{
InitializeComponent();
}
}
}

+ 10
- 6
BeDesignerSCADA/BeDesignerSCADA.csproj Переглянути файл

@@ -5,7 +5,8 @@
<TargetFramework>net6.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWPF>true</UseWPF>
<ApplicationIcon>Images\fyf.ico</ApplicationIcon>
<ApplicationIcon>Images\配置.ico</ApplicationIcon>
<AssemblyName>可视化配置工具</AssemblyName>
</PropertyGroup>

<ItemGroup>
@@ -74,10 +75,7 @@
<None Remove="Images\wx.jpg" />
<None Remove="Images\zfb.jpg" />
<None Remove="Images\光柱.png" />
</ItemGroup>

<ItemGroup>
<Content Include="Images\fyf.ico" />
<None Remove="Images\配置.ico" />
</ItemGroup>

<ItemGroup>
@@ -89,6 +87,7 @@
<PackageReference Include="Microsoft.Toolkit.Mvvm" Version="7.1.2" />
<PackageReference Include="MQTTnet" Version="3.1.2" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="NPinyinPro" Version="0.3.3" />
<PackageReference Include="StackExchange.Redis" Version="2.6.66" />
</ItemGroup>

@@ -109,7 +108,12 @@
<Resource Include="Images\win.png" />
<Resource Include="Images\wx.jpg" />
<Resource Include="Images\zfb.jpg" />
<Resource Include="Images\光柱.png" />
<Resource Include="Images\光柱.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Images\配置.ico">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
</ItemGroup>

<ItemGroup>


+ 15
- 8
BeDesignerSCADA/Controls/CanvasPanelNew.xaml Переглянути файл

@@ -15,7 +15,8 @@
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/BeDesignerSCADA;component/Themes/Styles.xaml" />
<!--<ResourceDictionary Source="/BeDesignerSCADA;component/Themes/Styles.xaml" />-->
<ResourceDictionary Source="/可视化配置工具;component/Themes/Styles.xaml"></ResourceDictionary>
<ResourceDictionary Source="/BPASmartClient.SCADAControl;component/Themes/Generic.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
@@ -97,10 +98,16 @@
<TabItem Header="组件列表">
<Border BorderThickness="1" BorderBrush="#FFA9A9A9" Background="Transparent">
<ListBox x:Name="CtlList" Grid.Row="2" Background="Transparent" ScrollViewer.VerticalScrollBarVisibility="Auto"
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="35"/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBox Margin="5" TextChanged="TextBox_TextChanged" FontSize="16"></TextBox>
<ListBox x:Name="CtlList" Grid.Row="2" Background="Transparent" ScrollViewer.VerticalScrollBarVisibility="Auto"
ItemTemplate="{DynamicResource ToolBoxStyle}" FontSize="14" BorderThickness="0"
PreviewMouseMove="CtlList_PreviewMouseMove"
/>
PreviewMouseMove="CtlList_PreviewMouseMove"/>
</Grid>
</Border>
</TabItem>
@@ -168,7 +175,7 @@
<Setter.Value>
<StackPanel Orientation="Horizontal" Margin="8 0">
<icon:PackIconModern Kind="ControlPlay" VerticalAlignment="Center" Foreground="#28B60F" Width="8"/>
<TextBlock Text="运行" Margin="4 0" VerticalAlignment="Center"/>
<TextBlock Text="当前页" Margin="4 0" VerticalAlignment="Center"/>
</StackPanel>
</Setter.Value>
</Setter>
@@ -179,7 +186,7 @@
<Setter.Value>
<StackPanel Orientation="Horizontal" Margin="8 0">
<icon:PackIconModern Kind="ControlStop" VerticalAlignment="Center" Foreground="#B60F0F" Width="8"/>
<TextBlock Text="停止" Margin="4 0" VerticalAlignment="Center"/>
<TextBlock Text="当前页" Margin="4 0" VerticalAlignment="Center"/>
</StackPanel>
</Setter.Value>
</Setter>
@@ -191,7 +198,7 @@
<Button x:Name="Run1Btn" Margin="4 0 0 0" Padding="0" Click="MNRunBtn_Click">
<StackPanel Orientation="Horizontal" Margin="8 0">
<icon:PackIconModern Kind="ControlPlay" VerticalAlignment="Center" Foreground="#28B60F" Width="8"/>
<TextBlock Text="模拟运行" Margin="4 0" VerticalAlignment="Center"/>
<TextBlock Text="运行程序" Margin="4 0" VerticalAlignment="Center"/>
</StackPanel>
</Button>
<Button x:Name="SaveBtn" Margin="16 0 0 0" Padding="0" Click="SaveBtn_Click">
@@ -465,7 +472,7 @@


<!--代码绑定模块-->
<mypro:EditorTemplateDefinition TargetProperties="ClickExec,ValueChangedExecute,TikcExecute,CheckedExec,UnCheckedExec,ChuLiaoExecute,StopChuLiaoExecute" >
<mypro:EditorTemplateDefinition TargetProperties="ClickStr,ClickExec,ValueChangedExecute,TikcExecute,CheckedExec,UnCheckedExec,ChuLiaoExecute,StopChuLiaoExecute" >
<mypro:EditorTemplateDefinition.EditingTemplate>
<DataTemplate>
<Grid>


+ 39
- 1
BeDesignerSCADA/Controls/CanvasPanelNew.xaml.cs Переглянути файл

@@ -28,6 +28,7 @@ using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Media.Effects;
using BeDesignerSCADA.Helper;

namespace BeDesignerSCADA.Controls
{
@@ -44,9 +45,19 @@ namespace BeDesignerSCADA.Controls
viewModel.LayoutsPath = _Path;
this.DataContext = viewModel;
viewModel.Loaded(cav, runCanvas);

//控件加载
Assembly assembly = Assembly.LoadFile($"{System.AppDomain.CurrentDomain.BaseDirectory}\\BPASmartClient.SCADAControl.dll"); //Assembly.GetExecutingAssembly();
CtlList.ItemsSource = assembly.GetTypes().Where(t => t.GetInterface("IExecutable") != null).OrderBy(o => o.Name)?.ToList();
List<Type> types = assembly.GetTypes().Where(t => t.GetInterface("IExecutable") != null)?.ToList();
List<Type> typesView = new List<Type>();
viewModel.ControlsNameValues.ToList().OrderBy(o => o.Value)?.ToList().ForEach(par =>
{
Type type= types?.Find(p => p.Name == par.Key);
if (type != null)
typesView.Add(type);
});
CtlList.ItemsSource = typesView;

//读取文件
FileRead(_Path);
}
@@ -191,6 +202,33 @@ namespace BeDesignerSCADA.Controls

#region 执行操作事件
/// <summary>
/// 查询输入框
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
try
{
System.Windows.Controls.TextBox textBox = sender as System.Windows.Controls.TextBox;
var info = viewModel.ControlsNameValues?.ToList().Find(par => par.Value.ToLower().StartsWith(textBox.Text.ToLower()));
if (info.Value.Key != null)
{
foreach (var item in CtlList.Items)
{
if ((item as Type).Name== info.Value.Key)
{
CtlList.ScrollIntoView(item);
CtlList.SelectedItem = item;
}
}
}
}
catch (Exception ex)
{
}
}
/// <summary>
/// 运行
/// </summary>
/// <param name="sender"></param>


+ 1
- 1
BeDesignerSCADA/Controls/MainCanvasPanel.xaml Переглянути файл

@@ -16,7 +16,7 @@
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/BeDesignerSCADA;component/Themes/Styles.xaml" />
<ResourceDictionary Source="/可视化配置工具;component/Themes/Styles.xaml"/>
<ResourceDictionary Source="/BPASmartClient.SCADAControl;component/Themes/Generic.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>


+ 136
- 52
BeDesignerSCADA/Helper/SystemHelper.cs Переглянути файл

@@ -3,10 +3,14 @@ using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;

namespace BeDesignerSCADA.Helper
{
@@ -33,67 +37,63 @@ namespace BeDesignerSCADA.Helper
/// 创建桌面快捷方式
/// </summary>
/// <returns>成功或失败</returns>
public bool CreateDesktopShortcut()
public void CreateShortcutOnDesktop()
{
//1、在COM对象中找到 Windows Script Host Object Model
//2、添加引用 using IWshRuntimeLibrary;
string deskTop = string.Empty;
try
//添加引用 (com->Windows Script Host Object Model),using IWshRuntimeLibrary;
String shortcutPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), $"{AppDomain.CurrentDomain.FriendlyName}.lnk");
if (!System.IO.File.Exists(shortcutPath))
{
deskTop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\";
if (System.IO.File.Exists(deskTop + GetApplicationName + ".lnk")) //
// 获取当前应用程序目录地址
String exePath = Process.GetCurrentProcess().MainModule.FileName;
IWshShell shell = new WshShell();
// 确定是否已经创建的快捷键被改名了
foreach (var item in Directory.GetFiles(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), "*.lnk"))
{
return true;
WshShortcut tempShortcut = (WshShortcut)shell.CreateShortcut(item);
if (tempShortcut.TargetPath == exePath)
{
return;
}
}
WshShell shell = new WshShell();
//快捷键方式创建的位置、名称
IWshShortcut shortcut = shell.CreateShortcut(deskTop + GetApplicationName + ".lnk") as IWshShortcut;
shortcut.TargetPath = GetApplicationPath; //目标文件
//该属性指定应用程序的工作目录,当用户没有指定一个具体的目录时,快捷方式的目标应用程序将使用该属性所指定的目录来装载或保存文件。
shortcut.WorkingDirectory = System.Environment.CurrentDirectory;
shortcut.WindowStyle = 1; //目标应用程序的窗口状态分为普通、最大化、最小化【1,3,7】
shortcut.Description = GetApplicationName; //描述
//shortcut.IconLocation = exePath + "\\logo.ico"; //快捷方式图标
shortcut.Arguments = "";
//shortcut.Hotkey = "CTRL+ALT+F11"; // 快捷键
shortcut.Save(); //必须调用保存快捷才成创建成功
return true;
}
catch (Exception ex)
{
return false;
WshShortcut shortcut = (WshShortcut)shell.CreateShortcut(shortcutPath);
shortcut.TargetPath = exePath;
shortcut.Arguments = "";// 参数
shortcut.Description = AppDomain.CurrentDomain.FriendlyName;
shortcut.WorkingDirectory = Environment.CurrentDirectory;//程序所在文件夹,在快捷方式图标点击右键可以看到此属性
shortcut.IconLocation = exePath;//图标,该图标是应用程序的资源文件
//shortcut.Hotkey = "CTRL+SHIFT+W";//热键,发现没作用,大概需要注册一下
shortcut.WindowStyle = 1;
shortcut.Save();
}
}

public bool CreateDesktopShortcut(string Name)
public void CreateShortcutOnDesktop(string Name)
{
//1、在COM对象中找到 Windows Script Host Object Model
//2、添加引用 using IWshRuntimeLibrary;
string deskTop = string.Empty;
try
//添加引用 (com->Windows Script Host Object Model),using IWshRuntimeLibrary;
String shortcutPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), $"{Name}.lnk");
if (!System.IO.File.Exists(shortcutPath))
{
deskTop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\";
if (System.IO.File.Exists(deskTop + Name + ".lnk")) //
// 获取当前应用程序目录地址
String exePath = $"{AppDomain.CurrentDomain.BaseDirectory}{Name}.exe";// Process.GetCurrentProcess().MainModule.FileName;
IWshShell shell = new WshShell();
// 确定是否已经创建的快捷键被改名了
foreach (var item in Directory.GetFiles(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), "*.lnk"))
{
return true;
WshShortcut tempShortcut = (WshShortcut)shell.CreateShortcut(item);
if (tempShortcut.TargetPath == exePath)
{
return;
}
}
WshShell shell = new WshShell();
//快捷键方式创建的位置、名称
IWshShortcut shortcut = shell.CreateShortcut(deskTop + Name + ".lnk") as IWshShortcut;
shortcut.TargetPath = GetApplicationPath; //目标文件
//该属性指定应用程序的工作目录,当用户没有指定一个具体的目录时,快捷方式的目标应用程序将使用该属性所指定的目录来装载或保存文件。
shortcut.WorkingDirectory = System.Environment.CurrentDirectory;
shortcut.WindowStyle = 1; //目标应用程序的窗口状态分为普通、最大化、最小化【1,3,7】
shortcut.Description = Name; //描述
//shortcut.IconLocation = exePath + "\\logo.ico"; //快捷方式图标
shortcut.Arguments = "";
//shortcut.Hotkey = "CTRL+ALT+F11"; // 快捷键
shortcut.Save(); //必须调用保存快捷才成创建成功
return true;
}
catch (Exception ex)
{
return false;
WshShortcut shortcut = (WshShortcut)shell.CreateShortcut(shortcutPath);
shortcut.TargetPath = exePath;
shortcut.Arguments = "";// 参数
shortcut.Description = AppDomain.CurrentDomain.FriendlyName;
shortcut.WorkingDirectory = Environment.CurrentDirectory;//程序所在文件夹,在快捷方式图标点击右键可以看到此属性
shortcut.IconLocation = exePath;//图标,该图标是应用程序的资源文件
//shortcut.Hotkey = "CTRL+SHIFT+W";//热键,发现没作用,大概需要注册一下
shortcut.WindowStyle = 1;
shortcut.Save();
}
}

@@ -142,7 +142,6 @@ namespace BeDesignerSCADA.Helper
private const int DBT_DEVICEREMOVECOMPLETE = 0x8004; //移除设备
public const int DBT_DEVTYP_PORT = 0x00000003;
public const int DBT_DEVTYP_VOLUME = 0x00000002;

public IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if (msg == WM_DEVICECHANGE)
@@ -217,9 +216,94 @@ namespace BeDesignerSCADA.Helper
return drives[i];
return nona;
}
#endregion

/// <summary>
/// 垂直方向滚动到顶部
/// </summary>
/// <param name="element"></param>
/// <param name="scrollViewer"></param>
public static void ScrollViewToVerticalTop(FrameworkElement element, ScrollViewer scrollViewer)
{
var scrollViewerOffset = scrollViewer.VerticalOffset;
var point = new System.Windows.Point(0, scrollViewerOffset);
var tarPos = element.TransformToVisual(scrollViewer).Transform(point);
scrollViewer.ScrollToVerticalOffset(tarPos.Y);
}

/// <summary>
/// 水平方向滚动到右侧
/// </summary>
/// <param name="element"></param>
/// <param name="scrollViewer"></param>
public static void ScrollViewToHorizontalRight(FrameworkElement element, ScrollViewer scrollViewer)
{
var scrollViewerOffset = scrollViewer.HorizontalOffset;
var point = new System.Windows.Point(scrollViewerOffset, 0);
var tarPos = element.TransformToVisual(scrollViewer).Transform(point);
scrollViewer.ScrollToHorizontalOffset(tarPos.X);
}

#endregion
/// <summary>
/// 汉字转全拼
/// </summary>
/// <param name="strChinese"></param>
/// <returns></returns>
public static string ConvertToAllSpell(string strChinese)
{
try
{
if (strChinese.Length != 0)
{
StringBuilder fullSpell = new StringBuilder();
for (int i = 0; i < strChinese.Length; i++)
{
var chr = strChinese[i];
fullSpell.Append(GetSpell(chr));
}
return fullSpell.ToString().ToUpper();
}
}
catch (Exception e)
{
Console.WriteLine("出错!" + e.Message);
}
return string.Empty;
}

/// <summary>
/// 汉字转首字母
/// </summary>
/// <param name="strChinese"></param>
/// <returns></returns>
public static string GetFirstSpell(string strChinese)
{
try
{
if (strChinese.Length != 0)
{
StringBuilder fullSpell = new StringBuilder();
for (int i = 0; i < strChinese.Length; i++)
{
var chr = strChinese[i];
fullSpell.Append(GetSpell(chr)[0]);
}
return fullSpell.ToString().ToUpper();
}
}
catch (Exception e)
{
Console.WriteLine("出错!" + e.Message);
}

return string.Empty;
}

private static string GetSpell(char chr)
{
var coverchr = NPinyin.Pinyin.GetPinyin(chr);
return coverchr;
}
}

[StructLayout(LayoutKind.Sequential)]



+ 1
- 1
BeDesignerSCADA/View/ChildEditWindow.xaml Переглянути файл

@@ -14,7 +14,7 @@
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/BeDesignerSCADA;component/Themes/Styles.xaml" />
<ResourceDictionary Source="/可视化配置工具;component/Themes/Styles.xaml"></ResourceDictionary>
<ResourceDictionary Source="/BPASmartClient.SCADAControl;component/Themes/Generic.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>


+ 1
- 1
BeDesignerSCADA/View/RunWindows.xaml Переглянути файл

@@ -12,7 +12,7 @@
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/BeDesignerSCADA;component/Themes/Styles.xaml" />
<ResourceDictionary Source="/可视化配置工具;component/Themes/Styles.xaml"></ResourceDictionary>
<ResourceDictionary Source="/BPASmartClient.SCADAControl;component/Themes/Generic.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>


Деякі файли не було показано, через те що забагато файлів було змінено

Завантаження…
Відмінити
Зберегти