Browse Source

解决冲突

master
pengliangyang 1 year ago
parent
commit
aa4111f90f
100 changed files with 5318 additions and 1037 deletions
  1. +7
    -7
      BPASmart.RecipeManagement/App.xaml
  2. +1
    -0
      BPASmart.RecipeManagement/BPASmart.RecipeManagement.csproj
  3. +1
    -2
      BPASmart.RecipeManagement/View/RecipesConfigure.xaml
  4. +4
    -1
      BPASmart.RecipeManagement/ViewModel/RecipeManagerViewModel.cs
  5. +1
    -1
      BPASmart.VariableManager/ServiceCenter.cs
  6. +0
    -6
      BPASmartClient.CustomResource/BPASmartClient.CustomResource.csproj
  7. +8
    -3
      BPASmartClient.CustomResource/Pages/Model/MessageLog.cs
  8. +56
    -18
      BPASmartClient.CustomResource/Pages/View/PromptView.xaml
  9. +13
    -0
      BPASmartClient.CustomResource/Pages/View/PromptView.xaml.cs
  10. +88
    -0
      BPASmartClient.CustomResource/RecDictionarys/RecToggleButton.xaml
  11. +70
    -49
      BPASmartClient.CustomResource/UserControls/ConveyBelt2.xaml
  12. +201
    -120
      BPASmartClient.CustomResource/UserControls/MaterialStock.xaml
  13. BIN
     
  14. +1
    -1
      BPASmartClient.DosingProject/Model/RawMaterial/DeviceInquire.cs
  15. +1
    -1
      BPASmartClient.DosingProject/ViewModel/RecipeInfosViewModel.cs
  16. +6
    -6
      BPASmartClient.DosingProject/ViewModel/RecipeReceiveViewModel.cs
  17. +4
    -4
      BPASmartClient.JXJFoodSmallStation/Model/RawMaterial/DeviceInquire.cs
  18. +12
    -4
      BPASmartClient.MilkWithTea/App.xaml
  19. +19
    -8
      BPASmartClient.MilkWithTea/App.xaml.cs
  20. +6
    -1
      BPASmartClient.MilkWithTea/BPASmartClient.MilkWithTea.csproj
  21. +30
    -0
      BPASmartClient.MilkWithTea/Control/ContextMenuToggleButton.cs
  22. +225
    -0
      BPASmartClient.MilkWithTea/Control/ScrollViewer.cs
  23. +111
    -0
      BPASmartClient.MilkWithTea/Control/ScrollViewerAttach.cs
  24. +426
    -0
      BPASmartClient.MilkWithTea/Control/TabControl.cs
  25. +509
    -0
      BPASmartClient.MilkWithTea/Control/TabItem.cs
  26. +200
    -0
      BPASmartClient.MilkWithTea/Control/TabPanel.cs
  27. +12
    -0
      BPASmartClient.MilkWithTea/Data/CancelRoutedEventArgs.cs
  28. +69
    -0
      BPASmartClient.MilkWithTea/Data/ValueBoxes.cs
  29. +5
    -36
      BPASmartClient.MilkWithTea/GLobal.cs
  30. +49
    -2
      BPASmartClient.MilkWithTea/MainWindow.xaml.cs
  31. +13
    -0
      BPASmartClient.MilkWithTea/Model/JsonDeviceConfig.cs
  32. +23
    -0
      BPASmartClient.MilkWithTea/Model/JsonLocalRecipes.cs
  33. +93
    -154
      BPASmartClient.MilkWithTea/View/LocalConfigureView.xaml
  34. +8
    -1
      BPASmartClient.MilkWithTea/View/LocalConfigureView.xaml.cs
  35. +4
    -4
      BPASmartClient.MilkWithTea/View/MainControlView.xaml
  36. +2
    -3
      BPASmartClient.MilkWithTea/View/MainControlView.xaml.cs
  37. +23
    -14
      BPASmartClient.MilkWithTea/View/ParameterSetting.xaml
  38. +135
    -0
      BPASmartClient.MilkWithTea/View/RecipeConfige.xaml
  39. +174
    -0
      BPASmartClient.MilkWithTea/View/RecipeConfige.xaml.cs
  40. +30
    -169
      BPASmartClient.MilkWithTea/ViewModel/LocalConfigureViewModel.cs
  41. +37
    -28
      BPASmartClient.MilkWithTea/ViewModel/MainControlViewModel.cs
  42. +16
    -17
      BPASmartClient.MilkWithTea/ViewModel/MainWindowVeiwModel.cs
  43. +105
    -86
      BPASmartClient.MilkWithTea/ViewModel/PatrameterSettiongViewModel.cs
  44. +75
    -0
      BPASmartClient.MilkWithTea/ViewModel/RecipeConfigeViewModel.cs
  45. +1
    -1
      BPASmartClient.Modbus/ModbusTcp.cs
  46. +4
    -0
      BPASmartClient.Model/BPASmartClient.Model.csproj
  47. +9
    -0
      BPASmartClient.Model/柔性味魔方/RawMaterialModel.cs
  48. +78
    -165
      BPASmartClient.MorkF/Control_MorkF.cs
  49. +38
    -0
      BPASmartClient.MorkF/GVL_MorkF.cs
  50. +38
    -18
      BPASmartClient.MorkF/View/DebugView.xaml
  51. +83
    -42
      BPASmartClient.MorkF/ViewModel/DebugViewModel.cs
  52. +6
    -1
      BPASmartClient.MorkMOC/BPASmartClient.MorkMOC.csproj
  53. +23
    -4
      BPASmartClient.MorkMOC/Control_MorkMOC.cs
  54. +55
    -0
      BPASmartClient.MorkMOC/Model/LocalMaterail.cs
  55. +3
    -0
      BPASmartClient.MorkMOC/OrderLocInfo.cs
  56. +2
    -0
      BPASmartClient.MorkS/Control_Morks.cs
  57. +1
    -0
      BPASmartClient.MorkS/GVL_MORKS.cs
  58. +4
    -0
      BPASmartClient.MorkTM/Model/LocalTeaWithMilkConfig.cs
  59. +60
    -0
      BPASmartClient.SCADAControl/BPASmartClient.SCADAControl.csproj
  60. +35
    -0
      BPASmartClient.SCADAControl/CustomerControls/FYFTheListBox.xaml
  61. +435
    -0
      BPASmartClient.SCADAControl/CustomerControls/FYFTheListBox.xaml.cs
  62. +11
    -1
      BPASmartClient.SCADAControl/CustomerControls/TheCheckBox.xaml.cs
  63. +1
    -1
      BPASmartClient.SCADAControl/CustomerControls/TheImage.xaml
  64. +1
    -2
      BPASmartClient.SCADAControl/CustomerControls/TheImage.xaml.cs
  65. +12
    -0
      BPASmartClient.SCADAControl/CustomerControls/TheMessage.xaml
  66. +109
    -0
      BPASmartClient.SCADAControl/CustomerControls/TheMessage.xaml.cs
  67. +12
    -0
      BPASmartClient.SCADAControl/CustomerControls/ThePopMessage.xaml
  68. +89
    -0
      BPASmartClient.SCADAControl/CustomerControls/ThePopMessage.xaml.cs
  69. +10
    -0
      BPASmartClient.SCADAControl/CustomerControls/TheRadioButton.cs
  70. +1
    -1
      BPASmartClient.SCADAControl/CustomerControls/TheTabControl.xaml.cs
  71. BIN
     
  72. BIN
     
  73. BIN
     
  74. BIN
     
  75. BIN
     
  76. BIN
     
  77. BIN
     
  78. BIN
     
  79. BIN
     
  80. BIN
     
  81. BIN
     
  82. BIN
     
  83. BIN
     
  84. BIN
     
  85. +15
    -36
      BPASmartClient.SCADAControl/Themes/Generic.xaml
  86. +255
    -0
      BPASmartClient.SCADAControl/Windows/ControlEnum.cs
  87. +47
    -0
      BPASmartClient.SCADAControl/Windows/MyMessageBox.xaml
  88. +126
    -0
      BPASmartClient.SCADAControl/Windows/MyMessageBox.xaml.cs
  89. +42
    -0
      BPASmartClient.SCADAControl/Windows/MyMessageBoxViewModel.cs
  90. +90
    -0
      BPASmartClient.SCADAControl/Windows/NoticeDemoViewModel.cs
  91. +145
    -0
      BPASmartClient.SCADAControl/Windows/Notifiaction.xaml
  92. +353
    -0
      BPASmartClient.SCADAControl/Windows/Notifiaction.xaml.cs
  93. +1
    -1
      BPASmartClient.SmallBatchingSystem/ViewModels/NewRecipeViewModel.cs
  94. +1
    -0
      BeDesignerSCADA/BeDesignerSCADA.csproj
  95. +1
    -1
      BeDesignerSCADA/Common/PropertyHelper.cs
  96. +8
    -8
      BeDesignerSCADA/Controls/CanvasPanelNew.xaml
  97. +159
    -1
      BeDesignerSCADA/Controls/CanvasPanelNew.xaml.cs
  98. +0
    -3
      BeDesignerSCADA/Controls/MainCanvasPanel.xaml.cs
  99. +21
    -2
      BeDesignerSCADA/Controls/MenuRunCanvas.xaml.cs
  100. +60
    -3
      BeDesignerSCADA/Helper/SystemHelper.cs

+ 7
- 7
BPASmart.RecipeManagement/App.xaml View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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, "提示", $"配方下发成功!");
}
}
}


+ 1
- 1
BPASmart.VariableManager/ServiceCenter.cs View File

@@ -55,8 +55,8 @@ namespace BPASmart.VariableManager
Thread.Sleep(100);
}), "客户端管道消息控制");
pipeClient.PushCommand = new Action<string>((s) => { if (pipeClient.IsConnected) msg.Enqueue(s); });
pipeClient.StartPipeStream();
MessageLog.GetInstance.NotifyShow = new Action<string>((o) => { if (pipeClient.IsConnected) pipeClient.SendCommand(o); });
pipeClient.StartPipeStream();

}



+ 0
- 6
BPASmartClient.CustomResource/BPASmartClient.CustomResource.csproj View File

@@ -269,12 +269,6 @@
</EmbeddedResource>
</ItemGroup>

<ItemGroup>
<Content Include="Videos\Login.mp4">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>

<ItemGroup>
<Resource Include="Fonts\80号-萌趣小鱼体.ttf" />
<Resource Include="Fonts\font\iconfont.ttf" />


+ 8
- 3
BPASmartClient.CustomResource/Pages/Model/MessageLog.cs View File

@@ -102,26 +102,31 @@ namespace BPASmartClient.CustomResource.Pages.Model
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.TextBlockInfo = $"警告:{info}";
PV.infoType.Text = "警告:";
//PV.Cancel.Visibility = Visibility.Collapsed;
break;
case DialogType.Error:
PV.TextBlockIcon = "&#xed1a;";
PV.TextBlockForeground = Brushes.Red;
PV.TextBlockInfo = $"错误:{info}";
PV.infoType.Text = "错误:";
//PV.Cancel.Visibility = Visibility.Collapsed;
break;
case DialogType.Information:
PV.TextBlockIcon = "&#xe657;";
PV.TextBlockForeground = Brushes.DeepSkyBlue;
PV.TextBlockInfo = $"提示:{info}";
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;
}


+ 56
- 18
BPASmartClient.CustomResource/Pages/View/PromptView.xaml View File

@@ -19,16 +19,17 @@
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid>
</Grid>
<Border
BorderBrush="DeepSkyBlue"
BorderThickness="2"
CornerRadius="8" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<Grid Name="main">
<Grid.Background>
<ImageBrush ImageSource="/BPASmartClient.CustomResource;component/Image/弹窗.png" Stretch="Fill" />
</Grid.Background>
@@ -43,29 +44,66 @@
BorderThickness="0"
Click="Button_Click" />

<Grid>
<Grid Margin="0,40,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.2*" />
<ColumnDefinition Width="0.15*" />
<ColumnDefinition />
</Grid.ColumnDefinitions>

<TextBlock Name="icon" Text="&#xe61f;" FontSize="30" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="DeepSkyBlue" FontFamily="../../Fonts/#iconfont"/>
<TextBlock Name="info" Text="警告:" Grid.Column="1" TextWrapping="Wrap" VerticalAlignment="Center" Foreground="DeepSkyBlue"/>
<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>

<Grid Grid.Row="1">
<Button/>
</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.7*" />
<RowDefinition Height="0.5*" />
</Grid.RowDefinitions>
</Grid>





</Grid>
</Window>

+ 13
- 0
BPASmartClient.CustomResource/Pages/View/PromptView.xaml.cs View File

@@ -23,6 +23,7 @@ namespace BPASmartClient.CustomResource.Pages.View
public PromptView()
{
InitializeComponent();
this.main.MouseLeftButtonDown += (o, e) => { if (e.LeftButton == MouseButtonState.Pressed) this.DragMove(); };
}

public string TextBlockIcon
@@ -58,5 +59,17 @@ namespace BPASmartClient.CustomResource.Pages.View
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();
}
}
}

+ 88
- 0
BPASmartClient.CustomResource/RecDictionarys/RecToggleButton.xaml View File

@@ -57,4 +57,92 @@
</Setter>
</Style>
<!--#endregion-->

<!--#region 切换开关 ToggleButton 样式-->
<Style x:Key="SwitchToggleButtonStyle" TargetType="{x:Type ToggleButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Viewbox>
<Grid x:Name="gr" Opacity="0.8">
<Border
x:Name="border2"
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
HorizontalAlignment="Left"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Background="Red"
BorderBrush="{TemplateBinding BorderBrush}"
CornerRadius="15">
<ContentPresenter
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Border>

<Ellipse
Name="ell"
Width="{TemplateBinding Height}"
Height="{TemplateBinding Height}"
Margin="0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Fill="#ddd" />

<TextBlock
Name="tb"
Margin="10,0,10,0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="White"
Text="开" />

</Grid>
</Viewbox>
<ControlTemplate.Triggers>
<!--<Trigger Property="IsPressed" Value="true">
<Setter Property="Background" Value="#FFd2e7f4" />
</Trigger>-->

<!-- 控件选中 -->
<Trigger Property="IsChecked" Value="true">
<!--<Setter Property="Foreground" Value="#ff1002E9" />-->
<Setter TargetName="ell" Property="HorizontalAlignment" Value="Right" />
<Setter TargetName="border2" Property="Background" Value="#00c2f4" />
<Setter TargetName="tb" Property="Text" Value="关" />
<Setter TargetName="tb" Property="Margin" Value="0,0,15,0" />
<!--<Setter TargetName="ell" Property="Fill" Value="#ff1002E9"/>-->
</Trigger>

<!-- 控件未选中 -->
<Trigger Property="IsChecked" Value="false">
<!--<Setter Property="Foreground" Value="#ff2AB2E7" />-->
<Setter TargetName="border2" Property="Background" Value="gray" />
<Setter TargetName="tb" Property="Text" Value="开" />
<Setter TargetName="tb" Property="Margin" Value="15,0,0,0" />
<!--<Setter TargetName="ell" Property="Fill" Value="#ddd"/>-->
</Trigger>

<!-- 鼠标进入 -->
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="gr" Property="Opacity" Value="1" />
</Trigger>

<!-- 控件禁用 -->
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="gr" Property="Opacity" Value="0.5" />
</Trigger>

<!-- 控件启用 -->
<Trigger Property="IsEnabled" Value="True">
<Setter TargetName="gr" Property="Opacity" Value="0.8" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--#endregion-->
</ResourceDictionary>

+ 70
- 49
BPASmartClient.CustomResource/UserControls/ConveyBelt2.xaml View File

@@ -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 View File

@@ -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>

BIN
View File


+ 1
- 1
BPASmartClient.DosingProject/Model/RawMaterial/DeviceInquire.cs View File

@@ -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


+ 1
- 1
BPASmartClient.DosingProject/ViewModel/RecipeInfosViewModel.cs View File

@@ -24,7 +24,7 @@ namespace BPASmartClient.DosingHKProject.ViewModel
{
RecipeName = rm.RecipeName;
RecipeCode = rm.RecipeCode;
TrayCode = rm.TrayCode;
//TrayCode = rm.TrayCode;
foreach (var item in rm.RawMaterial)
{
RawMaterialsInfo.Add(item);


+ 6
- 6
BPASmartClient.DosingProject/ViewModel/RecipeReceiveViewModel.cs View File

@@ -29,7 +29,7 @@ namespace BPASmartClient.DosingHKProject.ViewModel
public RecipeReceiveViewModel()
{
Recipes = Json<LocalRecipeDataColl>.Data.Recipes;
NewRecipe = new RelayCommand(() =>
{
NewLocalRecipeView NewLocalRecipe = new NewLocalRecipeView();
@@ -76,7 +76,7 @@ namespace BPASmartClient.DosingHKProject.ViewModel
});
NewSimulateRecipe = new RelayCommand(() =>
{
ObservableCollection<RemoteRecipeRawMaterial> RawMaterials = new ObservableCollection<RemoteRecipeRawMaterial>();
ObservableCollection<RemoteRecipeRawMaterial> RawMaterials = new ObservableCollection<RemoteRecipeRawMaterial>();
string recipeName = "配方" + (Json<LocalRecipeDataColl>.Data.Recipes.Count + 1) + "";
go:
string recipeCode = new Random().Next(1000, 9999).ToString();
@@ -105,21 +105,21 @@ namespace BPASmartClient.DosingHKProject.ViewModel
{
RecipeName = recipeName,
RecipeCode = recipeCode,
TrayCode = trayCode,
//TrayCode = trayCode,
RawMaterial = RawMaterials,
});
}

});
ClearAllRecipe = new RelayCommand(() =>
ClearAllRecipe = new RelayCommand(() =>
{
Json<LocalRecipeDataColl>.Data.Recipes.Clear();
});
}
}
public RelayCommand<object> DetailsCommand { get; set; }
public RelayCommand<object> IssueRecipe { get; set; }
public RelayCommand<object> RemoveRecipe { get; set; }
public RelayCommand NewSimulateRecipe { get;set; }
public RelayCommand NewSimulateRecipe { get; set; }
public RelayCommand ClearAllRecipe { get; set; }
public RelayCommand NewRecipe { get; set; }
public ObservableCollection<RemoteRecipeData> Recipes { get; set; }


+ 4
- 4
BPASmartClient.JXJFoodSmallStation/Model/RawMaterial/DeviceInquire.cs View File

@@ -71,7 +71,7 @@ namespace BPASmartClient.JXJFoodSmallStation.Model
DeviceNum = i + 1,
RunStatus = 1,
Weight = new Random().Next(100, 10000) / 100.0
});

devices.Add(new Devices()
@@ -216,7 +216,7 @@ namespace BPASmartClient.JXJFoodSmallStation.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
@@ -327,7 +327,7 @@ namespace BPASmartClient.JXJFoodSmallStation.Model
AlarmHelper<AlarmInfo>.Alarm.EStop2 = deviceStatus.DeviceAlarmCode.Get16bitValue(7);
AlarmHelper<AlarmInfo>.Alarm.SiloUpperLimit = deviceStatus.DeviceAlarmCode.Get16bitValue(8);
AlarmHelper<AlarmInfo>.Alarm.SiloLowerLimit = deviceStatus.DeviceAlarmCode.Get16bitValue(9);
Thread.Sleep(10);
}), $"{DeviceName} 开始监听", true);
}
@@ -341,7 +341,7 @@ namespace BPASmartClient.JXJFoodSmallStation.Model

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



+ 12
- 4
BPASmartClient.MilkWithTea/App.xaml View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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();
}
}
}

+ 1
- 1
BPASmartClient.Modbus/ModbusTcp.cs View File

@@ -567,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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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(); } }


+ 60
- 0
BPASmartClient.SCADAControl/BPASmartClient.SCADAControl.csproj View File

@@ -17,18 +17,23 @@
<None Remove="Images\biogebj.png" />
<None Remove="Images\bj.png" />
<None Remove="Images\btnkeys.png" />
<None Remove="Images\btn_close.png" />
<None Remove="Images\button1.png" />
<None Remove="Images\button2.png" />
<None Remove="Images\Cb_Checked.png" />
<None Remove="Images\Cb_HalfChecked.png" />
<None Remove="Images\databj.png" />
<None Remove="Images\error.png" />
<None Remove="Images\Exp.png" />
<None Remove="Images\Image_32x32.png" />
<None Remove="Images\info.png" />
<None Remove="Images\leftImage.png" />
<None Remove="Images\mqtt.png" />
<None Remove="Images\mqttrun.png" />
<None Remove="Images\mqttstop.png" />
<None Remove="Images\nbbj.png" />
<None Remove="Images\Pop_bg.png" />
<None Remove="Images\question.png" />
<None Remove="Images\redis.png" />
<None Remove="Images\redisrun.png" />
<None Remove="Images\redisstop.png" />
@@ -48,14 +53,24 @@
<None Remove="Images\光柱.png" />
<None Remove="Images\右1.png" />
<None Remove="Images\右2.png" />
<None Remove="Images\告警.png" />
<None Remove="Images\左1.png" />
<None Remove="Images\左2.png" />
<None Remove="Images\弹窗消息.png" />
<None Remove="Images\报错.png" />
<None Remove="Images\拉出 - 副本.png" />
<None Remove="Images\拉出.png" />
<None Remove="Images\收缩 - 副本.png" />
<None Remove="Images\收缩.png" />
<None Remove="Images\日期1.png" />
<None Remove="Images\暂无图片.png" />
<None Remove="Images\正常.png" />
<None Remove="Images\消息.png" />
<None Remove="Images\消息提示.png" />
<None Remove="Images\矩形边框.png" />
<None Remove="Images\矩形边框1.png" />
<None Remove="Images\系统名称.png" />
<None Remove="Images\背景2.png" />
<None Remove="Images\返回按钮1.png" />
<None Remove="Images\返回按钮2.png" />
<None Remove="Images\返回按钮图标.png" />
@@ -112,6 +127,9 @@
<Resource Include="Images\btnkeys.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Images\btn_close.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Images\Cb_Checked.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
@@ -121,9 +139,18 @@
<Resource Include="Images\databj.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Images\error.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Images\Exp.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Images\Image_32x32.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Images\info.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Images\leftImage.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
@@ -142,6 +169,9 @@
<Resource Include="Images\Pop_bg.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Images\question.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Images\redis.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
@@ -208,21 +238,48 @@
<Resource Include="Images\右2.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Images\告警.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Images\左1.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Images\左2.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Images\弹窗消息.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Images\报错.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Images\拉出 - 副本.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Images\拉出.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Images\收缩 - 副本.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Images\收缩.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<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>
<Resource Include="Images\消息.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Images\消息提示.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Images\矩形边框.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
@@ -232,6 +289,9 @@
<Resource Include="Images\系统名称.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Images\背景2.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Images\返回按钮1.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>


+ 35
- 0
BPASmartClient.SCADAControl/CustomerControls/FYFTheListBox.xaml View File

@@ -0,0 +1,35 @@
<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" >
<ListBox.ItemTemplate>
<ItemContainerTemplate>
<Border Tag="border" BorderBrush="Aquamarine" 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>

+ 435
- 0
BPASmartClient.SCADAControl/CustomerControls/FYFTheListBox.xaml.cs View File

@@ -0,0 +1,435 @@
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, IExecutable
{
/// <summary>
/// 数据model
/// </summary>
public ListBoxDataModel TheListBoxModel = new ListBoxDataModel();
public event EventHandler PropertyChange; //声明一个事件
ListView listView = null;
public FYFTheListBox()
{
InitializeComponent();
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;
listView.PreviewMouseMove += ListView_PreviewMouseMove;
listView.PreviewMouseLeftButtonUp += lisbox_PreviewMouseLeftButtonUp;
listView.PreviewMouseLeftButtonDown += ListView_PreviewMouseLeftButtonDown;
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.DataContext = TheListBoxModel;
}
}
}


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>
/// <exception cref="NotImplementedException"></exception>
private void ListView_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
try
{
//isDown变量是防止多次操作。
if (isDown)
{
isDown = false;
return;
}
var pos = e.GetPosition(listView);
HitTestResult result = VisualTreeHelper.HitTest(listView, pos);
if (result != null)
{
ChildElement = Utils.FindVisualParent<ListBoxItem>(result.VisualHit);
if (ChildElement != null)
{
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 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 View File

@@ -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 View File

@@ -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>

+ 1
- 2
BPASmartClient.SCADAControl/CustomerControls/TheImage.xaml.cs View File

@@ -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;
}


+ 12
- 0
BPASmartClient.SCADAControl/CustomerControls/TheMessage.xaml View File

@@ -0,0 +1,12 @@
<UserControl x:Class="BPASmartClient.SCADAControl.CustomerControls.TheMessage"
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="40" d:DesignWidth="40">
<Grid>
<Image Source="../Images/消息提示.png" Tag="正常" Visibility="Visible"/>
</Grid>
</UserControl>

+ 109
- 0
BPASmartClient.SCADAControl/CustomerControls/TheMessage.xaml.cs View File

@@ -0,0 +1,109 @@
using BPASmartClient.Compiler;
using BPASmartClient.SCADAControl.Windows;
using System;
using System.Collections.Generic;
using System.ComponentModel;
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.SCADAControl.CustomerControls
{
/// <summary>
/// TheMessage.xaml 的交互逻辑
/// </summary>
public partial class TheMessage : UserControl, IExecutable
{
public event EventHandler PropertyChange; //声明一个事件
public string ControlType => "控件";
private bool isExecuteState;
public bool IsExecuteState
{
get { return isExecuteState; }
set
{
isExecuteState = value;
if (IsExecuteState)
{
Register();
}
}
}
public TheMessage()
{
InitializeComponent();
Width = 40;
Height = 40;
}
public void Register()
{

}

#region 弹窗属性
[Category("消息类型")]
public MessageBoxStyle MessageLX
{
get { return (MessageBoxStyle)GetValue(MessageLXProperty); }
set { SetValue(MessageLXProperty, value); }
}
public static readonly DependencyProperty MessageLXProperty =
DependencyProperty.Register("MessageLX", typeof(MessageBoxStyle), typeof(TheMessage), new PropertyMetadata(MessageBoxStyle.info));
[Category("消息数据")]
public string Message
{
get { return (string)GetValue(MessageProperty); }
set
{
SetValue(MessageProperty, value);
MessageDataRefresh();
}
}
public static readonly DependencyProperty MessageProperty =
DependencyProperty.Register("Message", typeof(string), typeof(TheMessage), new PropertyMetadata(string.Empty));
[Category("消息数据")]
public bool ReturnValue
{
get { return (bool)GetValue(ReturnValueProperty); }
set
{
SetValue(ReturnValueProperty, value);
}
}
public static readonly DependencyProperty ReturnValueProperty =
DependencyProperty.Register("ReturnValue", typeof(bool), typeof(TheMessage), new PropertyMetadata(false));
public void MessageDataRefresh()
{
try
{
if (!string.IsNullOrEmpty(Message))
{
if (MessageBoxStyle.question == MessageLX)
{
ReturnValue = false;
bool? bo= new MyMessageBox(MessageLX, Message).ShowDialog();
ReturnValue=bo.Value;
}
else
{
new MyMessageBox(MessageLX, Message).ShowDialog();
}
}
}
catch (Exception ex)
{

}
}
#endregion
}
}

+ 12
- 0
BPASmartClient.SCADAControl/CustomerControls/ThePopMessage.xaml View File

@@ -0,0 +1,12 @@
<UserControl x:Class="BPASmartClient.SCADAControl.CustomerControls.ThePopMessage"
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="40" d:DesignWidth="40" >
<Grid>
<Image Source="../Images/弹窗消息.png" Tag="正常" Visibility="Visible"/>
</Grid>
</UserControl>

+ 89
- 0
BPASmartClient.SCADAControl/CustomerControls/ThePopMessage.xaml.cs View File

@@ -0,0 +1,89 @@
using BPASmartClient.Compiler;
using BPASmartClient.SCADAControl.Windows;
using System;
using System.Collections.Generic;
using System.ComponentModel;
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.SCADAControl.CustomerControls
{
/// <summary>
/// ThePopMessage.xaml 的交互逻辑
/// </summary>
public partial class ThePopMessage : UserControl, IExecutable
{
public event EventHandler PropertyChange; //声明一个事件
public string ControlType => "控件";
private bool isExecuteState;
public bool IsExecuteState
{
get { return isExecuteState; }
set
{
isExecuteState = value;
if (IsExecuteState)
{
Register();
}
}
}
public ThePopMessage()
{
InitializeComponent();
Width = 40;
Height = 40;
}
public void Register()
{
}

#region 弹窗属性
[Category("消息类型")]
public EnumPromptType MessageLX
{
get { return (EnumPromptType)GetValue(MessageLXProperty); }
set { SetValue(MessageLXProperty, value); }
}
public static readonly DependencyProperty MessageLXProperty =
DependencyProperty.Register("MessageLX", typeof(EnumPromptType), typeof(ThePopMessage), new PropertyMetadata(EnumPromptType.Info));
[Category("消息数据")]
public string Message
{
get { return (string)GetValue(MessageProperty); }
set
{
SetValue(MessageProperty, value);
MessageDataRefresh();
}
}
public static readonly DependencyProperty MessageProperty =
DependencyProperty.Register("Message", typeof(string), typeof(ThePopMessage), new PropertyMetadata(string.Empty));
public void MessageDataRefresh()
{
try
{
if (!string.IsNullOrEmpty(Message))
{
NoticeDemoViewModel.OpenMsg(MessageLX, Window.GetWindow(this), "通知", Message);
}
}
catch (Exception ex)
{

}
}
#endregion
}
}

+ 10
- 0
BPASmartClient.SCADAControl/CustomerControls/TheRadioButton.cs View File

@@ -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 View File

@@ -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)


BIN
View File


BIN
View File


BIN
View File


BIN
View File


BIN
View File


BIN
View File


BIN
View File


BIN
View File


BIN
View File


BIN
View File


BIN
View File


BIN
View File


BIN
View File


BIN
View File


+ 15
- 36
BPASmartClient.SCADAControl/Themes/Generic.xaml View File

@@ -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" />


+ 255
- 0
BPASmartClient.SCADAControl/Windows/ControlEnum.cs View File

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

namespace BPASmartClient.SCADAControl.Windows
{
#region EnumDatePickerType
public enum EnumDatePickerType
{
/// <summary>
/// 单个日期
/// </summary>
SingleDate,
/// <summary>
/// 连续的多个日期
/// </summary>
SingleDateRange,
/// <summary>
/// 只显示年份
/// </summary>
Year,
/// <summary>
/// 只显示月份
/// </summary>
Month,
/// <summary>
/// 显示一个日期和时间
/// </summary>
DateTime,
/// <summary>
/// 显示连续的日期和时间
/// </summary>
DateTimeRange,
}
#endregion

#region FlatButtonSkinEnum
/// <summary>
/// Button类型
/// </summary>
public enum FlatButtonSkinEnum
{
Yes,
No,
Default,
primary,
ghost,
dashed,
text,
info,
success,
error,
warning,
}
#endregion

#region EnumPromptType
/// <summary>
/// 提示类型
/// </summary>
public enum EnumPromptType
{
/// <summary>
/// 消息
/// </summary>
Info,
/// <summary>
/// 警告
/// </summary>
Warn,
/// <summary>
/// 失败
/// </summary>
Error,
/// <summary>
/// 成功
/// </summary>
Success,
}
#endregion

/// <summary>
/// 加载类型
/// </summary>
#region EnumLoadingType
public enum EnumLoadingType
{
/// <summary>
/// 两个圆
/// </summary>
DoubleRound,
/// <summary>
/// 一个圆
/// </summary>
SingleRound,
/// <summary>
/// 仿Win10加载条
/// </summary>
Win10,
/// <summary>
/// 仿Android加载条
/// </summary>
Android,
/// <summary>
/// 仿苹果加载条
/// </summary>
Apple,
Cogs,
Normal,
/// <summary>
/// 线条动画
/// </summary>
Lines,
/// <summary>
/// 方格动画
/// </summary>
Grids,
/// <summary>
/// 中心旋转动画
/// </summary>
Rotate,
/// <summary>
/// 版块加载
/// </summary>
Block,
/// <summary>
/// 自定义图标动画
/// </summary>
PathAnimation
}
#endregion

/// <summary>
/// 方向
/// </summary>
#region EnumPlacement
public enum EnumPlacement
{
/// <summary>
/// 左上
/// </summary>
LeftTop,
/// <summary>
/// 左中
/// </summary>
LeftCenter,
/// <summary>
/// 左下
/// </summary>
LeftBottom,
/// <summary>
/// 右上
/// </summary>
RightTop,
/// <summary>
/// 右中
/// </summary>
RightCenter,
/// <summary>
/// 右下
/// </summary>
RightBottom,
/// <summary>
/// 上左
/// </summary>
TopLeft,
/// <summary>
/// 上中
/// </summary>
TopCenter,
/// <summary>
/// 上右
/// </summary>
TopRight,
/// <summary>
/// 下左
/// </summary>
BottomLeft,
/// <summary>
/// 下中
/// </summary>
BottomCenter,
/// <summary>
/// 下右
/// </summary>
BottomRight,
}
#endregion

/// <summary>
/// 动画容器类型
/// </summary>
public enum TransitionMode
{
Right2Left,
Left2Right,
Bottom2Top,
Top2Bottom,
Right2LeftWithFade,
Left2RightWithFade,
Bottom2TopWithFade,
Top2BottomWithFade,
Fade,
Custom
}
/// <summary>
/// 联系人类型
/// </summary>
public enum ContactType
{
SerialNumber,
Single,
Group,
AddUser,
CutUser
}
/// <summary>
/// 进度条类型
/// </summary>
public enum ProgressBarType
{
Line,
Round
}
/// <summary>
/// XAML显示类型
/// </summary>
public enum Scope
{
None,
This,
ThisAndChildren
}
/// <summary>
/// 加减数字控件
/// </summary>
public enum EnumCompare
{
/// <summary>
/// 小于
/// </summary>
Less,
/// <summary>
/// 等于
/// </summary>
Equal,
/// <summary>
/// 大于
/// </summary>
Large,
None,
}
}

+ 47
- 0
BPASmartClient.SCADAControl/Windows/MyMessageBox.xaml View File

@@ -0,0 +1,47 @@
<Window x:Class="BPASmartClient.SCADAControl.Windows.MyMessageBox"
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.SCADAControl.Windows"
mc:Ignorable="d"
x:Name="frmMessageBox"
WindowState="Normal"
WindowStyle="None"
WindowStartupLocation="CenterScreen"
Title="提示" Height="150" Width="393">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="19"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid Grid.Row="0" Grid.ColumnSpan="2">
<TextBlock Margin="10,0,0,0" FontSize="18" FontFamily="宋体" VerticalAlignment="Center" HorizontalAlignment="Left">提示</TextBlock>
<Image Margin="0,0,10,0" VerticalAlignment="Center" HorizontalAlignment="Right" Source="../Images/报错.png" Cursor="Hand" MouseLeftButtonDown="Image_MouseLeftButtonDown"></Image>
</Grid>
<Image Grid.Row="1" x:Name="picICO" Width="70" Height="70" HorizontalAlignment="Center" VerticalAlignment="Center" Source="../Images/bj.png" Stretch="Fill"></Image>
<Grid Grid.Column="1" Grid.Row="1" >
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<Border Padding="10">
<TextBlock x:Name="labInfo" Grid.Row="0" Text="确定要删除数据吗?" FontSize="18" FontFamily="宋体" TextWrapping="Wrap" HorizontalAlignment="Left" VerticalAlignment="Center"></TextBlock>
</Border>
<Grid Grid.Row="1">
<StackPanel x:Name="panel2" Orientation="Horizontal">
<Button x:Name="btnYes" Cursor="Hand" Width="110" Height="31" Content="是(Y)" HorizontalAlignment="Left" VerticalAlignment="Top" ></Button>
<Button x:Name="btnNo" Cursor="Hand" Width="110" Margin="30,0,0,0" Height="31" Content="否(N)" HorizontalAlignment="Left" VerticalAlignment="Top"></Button>
</StackPanel>
<StackPanel x:Name="panel1" Orientation="Horizontal" Visibility="Collapsed">
<Button x:Name="btnOk" Cursor="Hand" Width="250" Height="31" Content="确定(O)" HorizontalAlignment="Left" VerticalAlignment="Top" ></Button>
</StackPanel>
</Grid>
</Grid>
</Grid>
</Window>

+ 126
- 0
BPASmartClient.SCADAControl/Windows/MyMessageBox.xaml.cs View File

@@ -0,0 +1,126 @@
using System;
using System.Collections.Generic;
using System.Drawing;
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.Forms;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace BPASmartClient.SCADAControl.Windows
{
/// <summary>
/// MyMessageBox.xaml 的交互逻辑
/// </summary>
public partial class MyMessageBox : Window
{
public MyMessageBox(MessageBoxStyle messageBoxStyle, string msg)
{
InitializeComponent();
this.Width = 393;
btnYes.Click += BtnYes_Click;
btnNo.Click += BtnNo_Click;
btnOk.Click += BtnOk_Click;
this.KeyDown += MyMessageBox_KeyDown;
if (messageBoxStyle == MessageBoxStyle.info)
{
picICO.Source = new BitmapImage(new Uri("../Images/info.png", UriKind.Relative));
//picICO.Image = global::myAlarmSystem.Properties.Resources.info;
this.Title = "提示";
panel1.Visibility = Visibility.Visible;
panel2.Visibility = Visibility.Collapsed;
}
else if (messageBoxStyle == MessageBoxStyle.question)
{
picICO.Source = new BitmapImage(new Uri("../Images/question.png", UriKind.Relative));
//picICO.Image = global::myAlarmSystem.Properties.Resources.question;
this.Title = "询问";
panel1.Visibility = Visibility.Collapsed;
panel2.Visibility = Visibility.Visible;
}
else if (messageBoxStyle == MessageBoxStyle.error)
{
picICO.Source = new BitmapImage(new Uri("../Images/error.png", UriKind.Relative));
//picICO.Image = global::myAlarmSystem.Properties.Resources.error;
this.Title = "错误";
panel1.Visibility = Visibility.Visible;
panel2.Visibility = Visibility.Collapsed;
}

this.labInfo.Text = msg;

SizeF size = TextRenderer.MeasureText(msg, new Font("宋体", 15, System.Drawing.FontStyle.Regular));

int TempWidth = (int)size.Width;
if (TempWidth <= 289) { return; }

this.Height = 150+((int)size.Width/289)*20;
//this.panel1.Width = TempWidth - 20;
//this.panel2.Width = TempWidth - 20;
//btnYes.Width = TempWidth / 2 - 20;
//btnNo.Width = TempWidth / 2 - 20;
}

private void MyMessageBox_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
{
if (e.KeyStates == Keyboard.GetKeyStates(Key.N))
{
BtnNo_Click(null, null);
}
else if (e.KeyStates == Keyboard.GetKeyStates(Key.Y))
{
BtnYes_Click(null, null);
}
else if (e.KeyStates == Keyboard.GetKeyStates(Key.O))
{
BtnOk_Click(null, null);
}
}

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

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

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

private void Image_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
this.Close();
}
}

/// <summary>
/// 消息样式类型
/// </summary>
public enum MessageBoxStyle
{
/// <summary>
/// 通知
/// </summary>
info = 0,
/// <summary>
/// 选择
/// </summary>
question = 1,
/// <summary>
/// 错误
/// </summary>
error = 2
};
}

+ 42
- 0
BPASmartClient.SCADAControl/Windows/MyMessageBoxViewModel.cs View File

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

namespace BPASmartClient.SCADAControl.Windows
{
/// <summary>
/// 消息提示框
/// </summary>
public class MyMessageBoxViewModel
{
/// <summary>
/// 提示对话框
/// </summary>
/// <param name="msg">消息内容</param>
public static void ShowMessageBoxInfo(string msg)
{
new MyMessageBox(MessageBoxStyle.info, msg).ShowDialog();
}

/// <summary>
/// 错误对话框
/// </summary>
/// <param name="msg">消息内容</param>
public static void ShowMessageBoxError(string msg)
{
new MyMessageBox(MessageBoxStyle.error, msg).ShowDialog();
}

/// <summary>
/// 询问对话框
/// </summary>
/// <param name="msg">消息内容</param>
/// <returns></returns>
public static bool? ShowMessageBoxQuestion(string msg)
{
return new MyMessageBox(MessageBoxStyle.question, msg).ShowDialog();
}
}
}

+ 90
- 0
BPASmartClient.SCADAControl/Windows/NoticeDemoViewModel.cs View File

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

namespace BPASmartClient.SCADAControl.Windows
{
/// <summary>
/// 弹出提示
/// </summary>
public class NoticeDemoViewModel
{
public static Notifiaction NotifiactionShow { get; set; }

#region 右侧弹框
/// <summary>
/// 初始化
/// </summary>
public static void OnStartup()
{
//初始化通知弹框
if (NotifiactionShow == null)
{
NotifiactionShow = new Notifiaction();
}
}
/// <summary>
/// 手动关闭
/// </summary>
public static void OnExit(string e)
{
switch (e)
{
case "Error":
NotifiactionShow.Clear(EnumPromptType.Error);
return;
case "Success":
NotifiactionShow.Clear(EnumPromptType.Success);
return;
case "Warm":
NotifiactionShow.Clear(EnumPromptType.Warn);
return;
case "Info":
NotifiactionShow.Clear(EnumPromptType.Info);
return;
default:
break;
}
//NoticeManager.ExitNotifiaction();

}

/// <summary>
/// 屏幕右下角信息提示弹窗
/// </summary>
/// <param name="e">弹窗类型:Error、Success、Warm、Info,分别对应不同颜色</param>
/// <param name="title">弹窗消息类型:属性判证、XX告警...</param>
/// <param name="content">弹窗消息内容</param>
/// <param name="kcmbbh">一般为对应目标的目标编号</param>
/// <param name="id">该条消息的ID</param>
public static void OpenMsg(EnumPromptType type, System.Windows.Window window, string title, string content)
{
string text = string.Empty;
if (content != null)
{
if (content.Length < 40)
{
int count = 40 - content.Length;
for (int i = 0; i < count * 2; i++)
{
content += " ";
}

}
text = content;
}
if (NotifiactionShow == null) NotifiactionShow = new Notifiaction();
NotifiactionShow.AddNotifiaction(new NotifiactionModel()
{
Title = title,//"这是Error通知标题",
Content = text,//"这条通知不会自动关闭,需要点击关闭按钮",
ContentToolTip = content,
NotifiactionType = type,
window = window
});
}
#endregion
}
}

+ 145
- 0
BPASmartClient.SCADAControl/Windows/Notifiaction.xaml View File

@@ -0,0 +1,145 @@
<Window x:Class="BPASmartClient.SCADAControl.Windows.Notifiaction"
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.SCADAControl.Windows"
mc:Ignorable="d"
Title="Notifiaction" Width="300" MinHeight="700"
AllowsTransparency="True"
Background="Transparent" ShowActivated="False"
ShowInTaskbar="False"
UseLayoutRounding="True" WindowStyle="None" >

<Window.Resources>
<PathGeometry x:Key="Icon_Close" Figures="M754.782 212.596 512 455.368 269.218 212.596c-13.081-13.081-34.29-13.081-47.369 0-13.081 13.081-13.081 34.288 0 47.367l242.782 242.771L221.849 745.507c-13.081 13.081-13.081 34.288 0 47.367 13.081 13.081 34.29 13.081 47.369 0L512 550.103l242.782 242.771c13.081 13.081 34.289 13.081 47.37 0 13.081-13.081 13.081-34.288 0-47.367L559.37 502.735l242.782-242.771c13.081-13.081 13.081-34.288 0-47.367C789.07 199.517 767.862 199.517 754.782 212.596z" />
<PathGeometry x:Key="InfoIcon" Figures="M512 0C229.206 0 0 229.289 0 512s229.206 512 512 512 512-229.378 512-512C1024 229.289 794.794 0 512 0z m80.3 700.333c-38.656 58.028-77.911 102.656-144.128 102.656-45.139-7.339-63.66-39.678-53.844-72.617l85.078-281.683c2.05-6.911-1.367-14.25-7.678-16.467-6.228-2.216-18.6 5.972-29.267 17.578l-51.372 61.867c-1.367-10.328-0.083-27.561-0.083-34.473 38.572-58.027 102.06-103.766 145.15-103.766 40.872 4.183 60.16 36.95 53.077 72.872l-85.677 283.044c-1.112 6.484 2.216 12.8 8.105 15.017 6.228 2.133 19.539-5.972 30.206-17.667l51.455-61.866c1.284 10.333-1.022 28.505-1.022 35.505z m-11.433-367.96c-32.6 0-58.878-23.64-58.878-58.623s26.367-58.622 58.878-58.622c32.427 0 58.966 23.639 58.966 58.622s-26.455 58.622-58.966 58.622z" />
<!--<PathGeometry x:Key="WarnIcon" Figures="M514.63547095 64.50557607c-245.79772937 0-445.80505747 199.97978336-445.80505745 445.7795534 0 245.85077718 200.0073271 445.85810529 445.80505745 445.85810529 245.79875019 0 445.80505747-200.0073271 445.80505749-445.85810529C960.44052743 264.48535941 760.43422017 64.50557607 514.63547095 64.50557607zM572.44016637 798.25683382c-13.74446534 14.26678179-31.36753754 21.5057584-52.45401459 21.50575839-22.03113538 0-40.59886489-7.55216231-55.33899569-22.3453409-14.635056-14.79113893-22.03113538-32.5213256-22.03113537-52.66416523 0-19.46035985 6.87172326-35.87659514 20.50907311-48.78045812 17.93931743-17.04770793 36.61314256-25.70265117 55.39102367-25.70265118 20.40399732 0 38.08011732 7.3960794 52.55909039 21.92605961 14.58200819 14.47693239 21.92503973 32.31117502 21.92503974 53.08242667C593.00126648 766.25884451 586.0785361 784.14613494 572.44016637 798.25683382zM592.89721153 384.50077378l-26.12091168 136.06541617c-6.82071513 41.07119406-14.47693239 74.6932599-22.7656421 99.76545928l-0.94363748 3.04208384c0 0-8.28768988 0.42030118-11.59195128 0.42030118l-41.91077658-0.21015058-35.51138249-160.14195009c-12.43153382-62.47187666-20.40501816-106.16587322-24.39175932-133.59971641-2.09844638-17.73018767-3.09411183-30.84216056-3.09411182-39.34000105 0-2.51772771 0.7865347-7.92043552 2.5697547-16.10407044 1.5730694-17.57104421 8.39276469-31.21043477 20.24689454-40.23263136 11.43484853-8.60291527 27.48587116-13.74242565 47.89088833-15.21144013 10.85846444-1.67916503 18.25454379-2.57077553 21.55880619-2.57077552 23.28897839 0 43.22064757 6.03214073 59.16761426 17.99236524 16.4713238 12.27341122 24.75799285 29.68837249 24.75799287 51.87661064C602.75797079 305.71467607 599.50675619 337.81672134 592.89721153 384.50077378z" />-->
<PathGeometry x:Key="ErrorIcon" Figures="M881.510752 573.386092c-15.745612-6.138814-21.400403-6.851035-48.313356-8.439206-26.912953-1.588171-31.004131 0.221034-59.474556 2.077312-128.870066 0.884137-257.154801 16.884552-382.724705 47.590901-80.273255 19.629059-159.52218 45.809325-235.43001 78.411861-48.994877 21.038152-57.654095 69.491701-15.294334 103.485933 50.149167 40.246633 118.762871-8.394181 164.725692-31.022551 78.463026-38.626739 315.544653-119.546723 404.01766-135.841851 99.574856-18.339694 186.075953-8.589632 187.662077-32.692586C894.074905 591.861886 897.256364 579.524906 881.510752 573.386092z M912.098397 578.64077c-23.939225 14.811334 6.349615 37.685297 27.733645 32.69975 25.548886-5.955642 18.216897-25.934672-0.203638-34.332946C929.971463 572.610426 919.367965 574.147432 912.098397 578.64077 M271.709285 387.416564c19.113313-8.293897 38.860053-15.419178 57.628512-24.099884 26.979468-12.481266 54.486962-30.454616 58.508555-62.534242 4.055362-32.310893-16.281825-58.32743-43.281759-73.349565-64.283072-35.768645-136.454812-2.146896-194.184631 30.063713-30.356378 16.941857-53.135174 43.911092-66.342987 75.990718-34.590819 83.989903-7.642051 197.990307 18.917862 254.121721 18.296715 38.675858 60.662615 56.901964 101.754498 55.561433 22.150486-0.723477 45.067428-6.814196 65.925479-13.956873 13.036921-4.461615 25.762757-9.830903 38.068014-16.030092 6.14393-3.099594 12.186554-6.405897 18.096147-9.934257 4.305049-2.569522 10.900258-9.100262 15.659655-10.091846 1.880837-0.38988 3.752464-1.033539 5.611811-1.943258 18.915815-9.314133 29.03836-26.543539 27.069519-46.076408-1.451048-14.461363-13.455453-29.566386-42.797735-28.596292-7.640004 0.252757-15.519462 1.623987-22.781866 3.963265-15.020088 4.845355-100.891851 58.340733-110.154819 37.502126-5.955642-13.403265 32.605605-27.402093 41.409109-31.347962 21.132296-9.466606 44.182268-13.373589 65.581648-22.104437 26.91193-10.980076 71.130014-32.04074 75.275427-65.014736 5.104251-40.612976-44.633546-45.369304-72.502267-40.136116-27.031657 5.078669-52.896744 12.673647-77.589123 25.018813-1.862417 0.933255-3.859911 1.889023-5.930059 1.648546-13.731746-1.593288 2.78237-15.542998 6.14086-17.753339C244.361427 400.046209 257.868045 393.427464 271.709285 387.416564 M566.432727 365.658004c-12.226462-11.811-32.686447-10.939143-48.75747-11.757788-20.536732-1.043772-41.192168 0.070608-61.497633 3.350304-75.191516 12.137435-54.967916 133.555785-40.393989 185.121208 6.725168 23.793916 40.133046 46.989197 57.488319 19.673062 9.198499-14.473643 1.916653-33.547047 1.585101-49.431829-0.313132-15.392572-0.656963-30.79026-0.86981-46.182832-0.319272-23.76424 8.90788-46.573735 31.006178-57.501622 22.234397-10.998495 53.559846-0.539282 64.325028-29.865191 0.887206-2.419096 1.520633-5.052063 0.957815-7.571443C569.845453 369.570103 568.390311 367.549074 566.432727 365.658004 M582.388117 392.262942c-11.023054 13.939477-10.873652 47.750537-11.437493 64.707744-0.586354 17.634636 1.388627 35.198663 4.034896 52.608172 0.832971 5.485945 2.725064 43.529399 16.673751 33.727149 3.596921-2.52859 8.435113-0.706081 12.378935-5.194302 12.890588-14.678304 17.025769-34.983769 18.679431-53.875025 0.952698-10.960633-2.405793-22.618137 0.553609-33.388435 4.76042-17.334807 17.551748-12.81998 31.66314-17.21508 25.586748-7.980765 41.24231-30.269397 12.945847-45.13906C649.435139 378.801349 597.08791 373.672538 582.388117 392.262942z M736.139873 496.272807c-3.832282 2.353604-8.368598 3.053546-13.228279 1.078565-24.283056-9.867742-4.149507-47.554062 21.378913-36.992519-0.147356 0.293689-0.25992 0.595564-0.38681 0.896416 0.309038 0.308015 0.688685 0.539282 0.949628 0.917906C751.596913 472.068546 746.357586 490.011196 736.139873 496.272807zM752.159732 413.68688c-15.767102-6.786567-31.175023-7.724938-45.830815 2.731204-10.084683 7.192819-17.23657 17.887392-22.060435 29.274744-10.021238 23.608697-19.142989 51.077306 2.40477 70.483284 13.657045 12.298094 37.884842 25.13547 56.625672 18.027585 13.382798-5.070482 22.468734-17.929348 28.14399-30.451546 11.054777-24.421202 15.767102-65.370847-8.566096-83.972507C759.845785 417.461857 756.147556 415.401941 752.159732 413.68688z M831.934636 482.111273c0.164752-0.167822 0.306992-0.357134 0.477884-0.522909 17.013489-16.610306 39.110763-10.090822 60.309574-12.124132 3.007497-0.289596 5.5279-3.162016 3.490497-6.037507-9.083889-12.839423-22.604834-18.491143-37.19104-23.449062-8.798387-2.995217-16.394389 3.368724-21.968337 10.380418-1.974981-12.604062-8.864902-22.789029-24.152073-16.647145-22.857591 9.17701-22.583344 48.02069-21.716604 67.3929 0.652869 14.504342 5.808286 45.686529 25.759687 29.064966 10.776438-8.977465 11.877515-33.568537 14.491039-45.938262C831.585689 483.510132 831.766814 482.812237 831.934636 482.111273" />
<PathGeometry x:Key="SelectedIcon" Figures="M512 0C229.231 0 0 229.231 0 512 0 794.771 229.231 1024 512 1024 794.771 1024 1024 794.771 1024 512 1024 229.231 794.769 0 512 0ZM805.671 379.193 474.533 710.332C474.533 710.332 474.529 710.336 474.524 710.342 459.258 725.612 435.98 727.996 418.209 717.5 414.918 715.555 411.815 713.166 408.989 710.342 408.987 710.338 408.983 710.336 408.983 710.336L218.331 519.684C200.235 501.587 200.235 472.244 218.331 454.144 236.427 436.048 265.771 436.048 283.867 454.144L441.759 612.036 740.136 313.659C758.235 295.563 787.578 295.563 805.675 313.659 823.766 331.755 823.766 361.097 805.671 379.193Z" />

<Storyboard x:Key="CollapseStoryboard">
<DoubleAnimation Duration="0:0:0.3" From="70" Storyboard.TargetProperty="Height" To="0" />
</Storyboard>

<DataTemplate x:Key="NotifiactionTemplate">
<Grid x:Name="NoticeGrid" Margin="5" Tag="{Binding Path=Id}"
RenderTransformOrigin="1,0.5" SizeChanged="NoticeGrid_SizeChanged">
<Grid.RenderTransform>
<TransformGroup>
<ScaleTransform />
<RotateTransform />
<SkewTransform />
<TranslateTransform />
</TransformGroup>
</Grid.RenderTransform>

<Border x:Name="border" Margin="5,0,0,0" BorderBrush="#419aff" CornerRadius="2" Padding="5" BorderThickness="1" VerticalAlignment="Center" HorizontalAlignment="Center">
<Border.Background>
<ImageBrush Stretch="Fill" ImageSource="../Images/背景2.png" />
</Border.Background>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image x:Name="Icon" Grid.RowSpan="2" MaxWidth="26" Margin="10,0,10,0" VerticalAlignment="Center" Stretch="Uniform" ></Image>
<Grid Grid.Row="0" Grid.Column="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock x:Name="title" Grid.Column="0" VerticalAlignment="Center" FontSize="14"
Text="{Binding Title}" FontWeight="Bold">
<TextBlock.Foreground>
<SolidColorBrush Color="{Binding Path=color}" Opacity="1"/>
</TextBlock.Foreground>
</TextBlock>
<TextBlock x:Name="count" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="14"
Text="{Binding count, StringFormat='1/{0}'}" FontWeight="Bold">
<TextBlock.Foreground>
<SolidColorBrush Color="{Binding Path=color}" Opacity="1"/>
</TextBlock.Foreground>
</TextBlock>
</Grid>
<TextBlock x:Name="text" Grid.Row="1" Grid.Column="1" Margin="0,8,30,0"
Text="{Binding Content}"
TextWrapping="Wrap" Background="Transparent">
<TextBlock.Foreground>
<SolidColorBrush Color="#f4f4f5" Opacity="1"/>
</TextBlock.Foreground>
</TextBlock>
<Image x:Name="PART_CloseButton" Grid.ColumnSpan="2" ToolTip="关闭窗口" Margin="0,0,5,0" Source="../Images/btn_close.png" HorizontalAlignment="Right" Width="12" Height="12" VerticalAlignment="Center" MouseLeftButtonDown="PART_CloseButton_MouseLeftButtonDown" Cursor="Hand"></Image>
</Grid>
</Border>
</Grid>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding NotifiactionType}" Value="Info">
<Setter TargetName="Icon" Property="Source" Value="../Images/消息.png"/>
</DataTrigger>
<DataTrigger Binding="{Binding NotifiactionType}" Value="Warn">
<Setter TargetName="Icon" Property="Source" Value="../Images/告警.png"/>
</DataTrigger>
<DataTrigger Binding="{Binding NotifiactionType}" Value="Error">
<Setter TargetName="Icon" Property="Source" Value="../Images/报错.png"/>
</DataTrigger>
<DataTrigger Binding="{Binding NotifiactionType}" Value="Success">
<Setter TargetName="Icon" Property="Source" Value="../Images/正常.png"/>
</DataTrigger>
<EventTrigger RoutedEvent="Grid.Loaded" SourceName="NoticeGrid">
<BeginStoryboard x:Name="FadeInStoryBoard">
<Storyboard>

<DoubleAnimation Duration="0:0:0.2" From="0.01" Storyboard.TargetName="NoticeGrid"
Storyboard.TargetProperty="Opacity"
To="1" />
<DoubleAnimation From="50" To="0" Duration="0:0:0.4" Storyboard.TargetName="NoticeGrid" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)">
<DoubleAnimation.EasingFunction>
<CubicEase EasingMode="EaseOut"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>


<DoubleAnimation BeginTime="0:0:10" Duration="0:0:0.2" From="1"
Storyboard.TargetName="NoticeGrid"
Storyboard.TargetProperty="Opacity" To="0" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<SeekStoryboard BeginStoryboardName="FadeInStoryBoard" Offset="0:0:3" />
<PauseStoryboard BeginStoryboardName="FadeInStoryBoard" />
</Trigger.EnterActions>
<Trigger.ExitActions>
<SeekStoryboard BeginStoryboardName="FadeInStoryBoard" Offset="0:0:3" />
<ResumeStoryboard BeginStoryboardName="FadeInStoryBoard" />
</Trigger.ExitActions>
</Trigger>
<EventTrigger RoutedEvent="Button.Click" SourceName="PART_CloseButton">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0" From="1" Storyboard.TargetName="NoticeGrid"
Storyboard.TargetProperty="(Grid.Opacity)"
To="0" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<Trigger SourceName="NoticeGrid" Property="Opacity" Value="0">
<Setter TargetName="NoticeGrid" Property="Visibility" Value="Hidden" />
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource CollapseStoryboard}" />
</Trigger.EnterActions>
</Trigger>
</DataTemplate.Triggers>
</DataTemplate>
</Window.Resources>
<ItemsControl x:Name="NotificationsControl"
FocusVisualStyle="{x:Null}"
ItemTemplate="{StaticResource NotifiactionTemplate}"
ItemsSource="{Binding .}" />
</Window>

+ 353
- 0
BPASmartClient.SCADAControl/Windows/Notifiaction.xaml.cs View File

@@ -0,0 +1,353 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
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.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Threading;

namespace BPASmartClient.SCADAControl.Windows
{
/// <summary>
/// Notifiaction.xaml 的交互逻辑
/// </summary>
public partial class Notifiaction : Window
{
private const byte MAX_NOTIFICATIONS = 10;
private readonly ObservableCollection<NotifiactionModel> buffer = new ObservableCollection<NotifiactionModel>();
private ObservableCollection<NotifiactionModel> NotifiactionList = new ObservableCollection<NotifiactionModel>();
private const double topOffset = 40;
private const double leftOffset = 350;
public DispatcherTimer uptimer = null;
public Notifiaction()
{
InitializeComponent();
this.NotificationsControl.DataContext = this.NotifiactionList;
this.Top = 130;
this.Left = SystemParameters.WorkArea.Left + SystemParameters.WorkArea.Width - this.Width;
this.Height = SystemParameters.WorkArea.Height - 460;
this.WindowStartupLocation = System.Windows.WindowStartupLocation.Manual;
if (uptimer == null)
uptimer = new DispatcherTimer();
uptimer.Tick += new EventHandler(_timer_Tick);
uptimer.Interval = TimeSpan.FromSeconds(1);
uptimer.Start();
}

#region 显示控制
/// <summary>
/// 线程消失函数
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void _timer_Tick(object sender, EventArgs e)
{
NotifiactionList.ToList().ForEach(par =>
{
if (par.time > 0)
par.time = par.time - 1;
});
List<NotifiactionModel> Notifia = NotifiactionList.ToList().FindAll(x => x.time <= 0);
foreach (var item in Notifia)
{
RemoveNotification(item);
}
}
/// <summary>
/// 清除窗体显示函数
/// </summary>
/// <param name="type"></param>
public void Clear(EnumPromptType type)
{
List<NotifiactionModel> buff = buffer.ToList().FindAll(x => x.NotifiactionType == type);
foreach (var item in buff)
{
buffer.Remove(item);
}
List<NotifiactionModel> Notifia = NotifiactionList.ToList().FindAll(x => x.NotifiactionType == type);
foreach (var item in Notifia)
{
NotifiactionList.Remove(item);
}
}
/// <summary>
/// 增加一个消息弹框
/// </summary>
/// <param name="notification"></param>
public void AddNotifiaction(NotifiactionModel notification)
{
try
{
var window = Window.GetWindow(notification.window);
var intPtr = new WindowInteropHelper(window).Handle;
var screen = System.Windows.Forms.Screen.FromHandle(intPtr);
this.Left = screen.WorkingArea.Left + screen.WorkingArea.Width / 2 - this.Width / 2;// screen.WorkingArea.Left + screen.WorkingArea.Width - this.Width;

WindowInteropHelper helper = new WindowInteropHelper(this);
helper.Owner = new WindowInteropHelper(notification.window).Handle;
this.Topmost = false;
if (notification.window != null)
{
if (notification.window.WindowState == WindowState.Minimized)
{
this.WindowState = WindowState.Minimized;
}
else
{
this.WindowState = WindowState.Normal;
}
}

if (NotifiactionList.Count + 1 > MAX_NOTIFICATIONS)//且数量超过了限制
{
buffer.Add(notification);
}
else//已经显示的没找到,数量没有超过限制
{
NotifiactionList.Add(notification);
}

if (NotifiactionList.Count > 0 && !IsActive)
this.Show();
}
catch (Exception ex)
{

}
}
/// <summary>
/// 将显示窗体移除
/// </summary>
/// <param name="notification"></param>
public void RemoveNotification(NotifiactionModel notification)
{
if (notification == null)
return;

if (NotifiactionList.Contains(notification))
NotifiactionList.Remove(notification);

if (buffer.Count > 0)
{
if (notification.NotifiactionType == EnumPromptType.Warn)
{
NotifiactionModel mode = buffer.ToList().Find(par => par.NotifiactionType == EnumPromptType.Info);
if (mode == null)
{
NotifiactionModel mode1 = buffer.ToList().Find(par => par.NotifiactionType == EnumPromptType.Success);
if (mode1 == null)
{
NotifiactionList.Add(buffer[0]);
buffer.RemoveAt(0);
}
else
{
NotifiactionList.Add(mode1);
buffer.Remove(mode);
}
}
else
{
NotifiactionList.Add(mode);
buffer.Remove(mode);
}
}
else if (notification.NotifiactionType == EnumPromptType.Info)
{
NotifiactionModel mode = buffer.ToList().Find(par => par.NotifiactionType == EnumPromptType.Success);
if (mode == null)
{
NotifiactionModel mode1 = buffer.ToList().Find(par => par.NotifiactionType == EnumPromptType.Warn);
if (mode1 == null)
{
NotifiactionList.Add(buffer[0]);
buffer.RemoveAt(0);
}
else
{
NotifiactionList.Add(mode1);
buffer.Remove(mode);
}
}
else
{
NotifiactionList.Add(mode);
buffer.Remove(mode);
}
}
else if (notification.NotifiactionType == EnumPromptType.Success)
{
NotifiactionModel mode = buffer.ToList().Find(par => par.NotifiactionType == EnumPromptType.Warn);
if (mode == null)
{
NotifiactionModel mode1 = buffer.ToList().Find(par => par.NotifiactionType == EnumPromptType.Info);
if (mode1 == null)
{
NotifiactionList.Add(buffer[0]);
buffer.RemoveAt(0);
}
else
{
NotifiactionList.Add(mode1);
buffer.Remove(mode);
}
}
else
{
NotifiactionList.Add(mode);
buffer.Remove(mode);
}
}
else
{
NotifiactionList.Add(buffer[0]);
buffer.RemoveAt(0);
}
}

//Close window if there's nothing to show
if (NotifiactionList.Count < 1)
Hide();
}

private void NoticeGrid_SizeChanged(object sender, SizeChangedEventArgs e)
{

}
#endregion

#region 窗体事件

/// <summary>
/// 关闭窗口
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void PART_CloseButton_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Image border = (Image)sender;
NotifiactionModel mode = border.DataContext as NotifiactionModel;
RemoveNotification(mode);
}
#endregion
}

public class NotifiactionModel : INotifyPropertyChanged
{
private int _count;
private string _content;
private int _time;
/// <summary>
/// Id不需要赋值
/// </summary>
public string Id { get; set; }
/// <summary>
/// 通知标题
/// </summary>
public string Title { get; set; }
/// <summary>
/// 通知内容
/// </summary>
public string Content
{
get { return _content; }
set
{
_content = value;
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs("Content"));
}
}
}
/// <summary>
/// 通知内容-显示全体
/// </summary>
public string ContentToolTip { get; set; }
/// <summary>
/// 通知类型
/// </summary>
private EnumPromptType enumPromptType;
public EnumPromptType NotifiactionType
{
get { return enumPromptType; }
set
{
enumPromptType = value;
switch (enumPromptType)
{
case EnumPromptType.Info:
color = Color.FromRgb(35, 132, 190);
break;
case EnumPromptType.Warn:
color = Color.FromRgb(255, 170, 22);
break;
case EnumPromptType.Error:
color = Color.FromRgb(245, 49, 49);
break;
case EnumPromptType.Success:
color = Color.FromRgb(28, 194, 59);
break;
}
if (this.PropertyChanged != null)
this.PropertyChanged(this, new PropertyChangedEventArgs("enumPromptType"));
}
}
/// <summary>
/// 背景颜色主题
/// </summary>
public Color color { get; set; }
/// <summary>
/// 文本颜色
/// </summary>
public Color textColor { get; set; }
/// <summary>
/// 外部windows
/// </summary>
public System.Windows.Window window { get; set; }
/// <summary>
/// 弹窗显示时长
/// </summary>
public int time
{
get { return _time; }
set
{
_time = value;
if (this.PropertyChanged != null)
this.PropertyChanged(this, new PropertyChangedEventArgs("time"));
}
}
public int count
{
get { return _count; }
set
{
_count = value;
if (this.PropertyChanged != null)
this.PropertyChanged(this, new PropertyChangedEventArgs("count"));
}
}//超过1显示数量
/// <summary>
/// 设置默认之
/// </summary>
public NotifiactionModel()
{
Id = Guid.NewGuid().ToString();
time = 5;
count = 1;
}

public event PropertyChangedEventHandler PropertyChanged;
}
}

+ 1
- 1
BPASmartClient.SmallBatchingSystem/ViewModels/NewRecipeViewModel.cs View File

@@ -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);


+ 1
- 0
BeDesignerSCADA/BeDesignerSCADA.csproj View File

@@ -87,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>



+ 1
- 1
BeDesignerSCADA/Common/PropertyHelper.cs View File

@@ -21,7 +21,7 @@ namespace BeDesignerSCADA.Common
"StatusValue", "NumberValue", "Text",
"Direction","RefreshData",
"ChangedText","Content","SendText","LeftTogIsChecked","RightTogIsChecked",
"Visibility"
"Visibility","Message","ReturnValue"
};
public static List<ControlName> GetCustomerControlProperty(List<FrameworkElement> selectItems)
{


+ 8
- 8
BeDesignerSCADA/Controls/CanvasPanelNew.xaml View File

@@ -15,7 +15,6 @@
<UserControl.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>
@@ -41,6 +40,7 @@
Background="Transparent"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ItemTemplate="{DynamicResource PageBoxStyle}"
SelectionChanged="PageList_SelectionChanged"
FontSize="14" BorderThickness="0" >
<ListBox.ContextMenu>
<ContextMenu>
@@ -175,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>
@@ -186,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>
@@ -198,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">
@@ -220,6 +220,7 @@
<TextBlock Text="同步" Margin="4 0" VerticalAlignment="Center"/>
</StackPanel>
</Button>

<TextBlock HorizontalAlignment="Center" Margin="4 0 0 0" MaxWidth="200" TextWrapping="Wrap" Height="25" FontSize="10" VerticalAlignment="Bottom" Foreground="Red">温馨提示:布局完成点击“同步”按钮,保存布局到菜单页面,菜单页面“右键”可导出整体布局!</TextBlock>

<ToggleButton x:Name="showCode" Click="showCode_Click" DockPanel.Dock="Right" Margin="4 0 0 0" Padding="4 0">
@@ -325,6 +326,7 @@
<mypro:PropertyDefinition DisplayName="运行状态" Category="基本属性" DisplayOrder="2" Name="Direction" Description="Direction"/>
<mypro:PropertyDefinition DisplayName="Tag" Category="基本属性" DisplayOrder="2" Name="Tag" Description="Tag"/>
<mypro:PropertyDefinition DisplayName="启动路径" Category="基本属性" DisplayOrder="2" Name="StartPath" Description="StartPath"/>
<mypro:PropertyDefinition DisplayName="消息类型" Category="基本属性" DisplayOrder="2" Name="MessageLX" Description="MessageLX"/>

<mypro:PropertyDefinition DisplayName="最大值" Category="基本属性" DisplayOrder="3" Name="MaxValue" Description="MaxValue"/>
<mypro:PropertyDefinition DisplayName="最小值" Category="基本属性" DisplayOrder="3" Name="MinValue" Description="MinValue"/>
@@ -414,7 +416,6 @@
<mypro:EditorTemplateDefinition.EditingTemplate>
<DataTemplate>
<Slider Maximum="1" Minimum="0" Value="{Binding Value,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" ></Slider>
<!--<mypro: SelectedColor="{Binding Value,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged, Converter={x:Static s:ColorToStringConverter.Instance}}" />-->
</DataTemplate>
</mypro:EditorTemplateDefinition.EditingTemplate>
</mypro:EditorTemplateDefinition>
@@ -457,7 +458,6 @@
</mypro:EditorTemplateDefinition.EditingTemplate>
</mypro:EditorTemplateDefinition>


<!--子控件模板编辑-->
<mypro:EditorTemplateDefinition TargetProperties="ChildTemplateXml">
<mypro:EditorTemplateDefinition.EditingTemplate>
@@ -470,9 +470,8 @@
</mypro:EditorTemplateDefinition.EditingTemplate>
</mypro:EditorTemplateDefinition>


<!--代码绑定模块-->
<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>
@@ -518,6 +517,7 @@
</DataTemplate>
</mypro:EditorTemplateDefinition.EditingTemplate>
</mypro:EditorTemplateDefinition>
<mypro:EditorTemplateDefinition TargetProperties="Text,Title,Value,BindingIsChecked,Header,KgValue,WLText,WLTitle,DataSouceInformation,Direction,LeftTogIsChecked,RightTogIsChecked" >
<mypro:EditorTemplateDefinition.EditingTemplate>
<DataTemplate>


+ 159
- 1
BeDesignerSCADA/Controls/CanvasPanelNew.xaml.cs View File

@@ -37,7 +37,14 @@ namespace BeDesignerSCADA.Controls
/// </summary>
public partial class CanvasPanelNew : System.Windows.Controls.UserControl
{
/// <summary>
/// 界面Model
/// </summary>
public MainViewModelNew viewModel = new MainViewModelNew();
/// <summary>
/// 文件夹监视
/// </summary>
public FileSystemWatcher _watcher;
public CanvasPanelNew(string _Path)
{
InitializeComponent();
@@ -45,11 +52,27 @@ 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;

//读取文件
CreateDir();
FileRead(_Path);

cav.SelectedItemAction += new Action<FrameworkElement>(o => {
if (ReditSeleceTab.SelectedIndex!=1)
ReditSeleceTab.SelectedIndex = 1;
});
}

#region 位置调整
@@ -118,6 +141,130 @@ namespace BeDesignerSCADA.Controls
}
#endregion

#region 变量管理器文件夹监听事件
/// <summary>
/// 创建文件夹,监视文件夹
/// </summary>
public void CreateDir()
{
try
{
//不存在则创建布局文件夹
if (!Directory.Exists($"{System.AppDomain.CurrentDomain.BaseDirectory}Layouts"))
{
Directory.CreateDirectory($"{System.AppDomain.CurrentDomain.BaseDirectory}Layouts");
}
//不存在则创建变量管理器路径 AccessFile
if (!Directory.Exists($"{System.AppDomain.CurrentDomain.BaseDirectory}AccessFile"))
{
Directory.CreateDirectory($"{System.AppDomain.CurrentDomain.BaseDirectory}AccessFile");
}
if (!Directory.Exists($"{System.AppDomain.CurrentDomain.BaseDirectory}AccessFile/JSON"))
{
Directory.CreateDirectory($"{System.AppDomain.CurrentDomain.BaseDirectory}AccessFile/JSON");
}

try
{

this._watcher = new FileSystemWatcher();
_watcher.Path = $"{System.AppDomain.CurrentDomain.BaseDirectory}AccessFile/JSON";
_watcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.DirectoryName;
_watcher.IncludeSubdirectories = true;
_watcher.Created += new FileSystemEventHandler(FileWatcher_Created);
_watcher.Changed += new FileSystemEventHandler(FileWatcher_Changed);
_watcher.Deleted += new FileSystemEventHandler(FileWatcher_Deleted);
_watcher.Renamed += new RenamedEventHandler(FileWatcher_Renamed);
Start();
}

catch (Exception ex)
{
Console.WriteLine("Error:" + ex.Message);
}
}
catch (Exception ex)
{

}
}
/// <summary>
/// 监视启动
/// </summary>
public void Start()
{
this._watcher.EnableRaisingEvents = true;
Console.WriteLine("文件监控已经启动...");
ReadFileVlaue();
}
/// <summary>
/// 监视停止
/// </summary>
public void Stop()
{
this._watcher.EnableRaisingEvents = false;
this._watcher.Dispose();
this._watcher = null;
}
/// <summary>
/// 文件夹新增
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void FileWatcher_Created(object sender, FileSystemEventArgs e)
{
Console.WriteLine("新增:" + e.ChangeType + ";" + e.FullPath + ";" + e.Name);
ReadFileVlaue();
}
/// <summary>
/// 文件名变更-文件大小变化
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void FileWatcher_Changed(object sender, FileSystemEventArgs e)
{
Console.WriteLine("变更:" + e.ChangeType + ";" + e.FullPath + ";" + e.Name);
ReadFileVlaue();
}
/// <summary>
/// 删除
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void FileWatcher_Deleted(object sender, FileSystemEventArgs e)
{
Console.WriteLine("删除:" + e.ChangeType + ";" + e.FullPath + ";" + e.Name);
ReadFileVlaue();
}
/// <summary>
/// 文件名
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void FileWatcher_Renamed(object sender, RenamedEventArgs e)
{
Console.WriteLine("重命名: OldPath:{0} NewPath:{1} OldFileName{2} NewFileName:{3}", e.OldFullPath, e.FullPath, e.OldName, e.Name);
ReadFileVlaue();
}
/// <summary>
/// 读取文件变量
/// </summary>
public void ReadFileVlaue()
{
try
{
Directory.CreateDirectory(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "AccessFile\\JSON"));
viewModel.VariablePath = AppDomain.CurrentDomain.BaseDirectory + "AccessFile\\JSON\\CommunicationPar.json";
DataBusModel.GetInstance().RefreshVariableManager(viewModel.VariablePath);
}
catch (Exception ex)
{

}
}

#endregion

#region 外部调用事件
/// <summary>
/// 传入变量管理器地址
@@ -340,6 +487,15 @@ namespace BeDesignerSCADA.Controls

}
}
/// <summary>
/// 页选中改变事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void PageList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ReditSeleceTab.SelectedIndex = 0;
}
#endregion

#region 左侧控件栏移动
@@ -512,5 +668,7 @@ namespace BeDesignerSCADA.Controls
}
}
#endregion

}
}

+ 0
- 3
BeDesignerSCADA/Controls/MainCanvasPanel.xaml.cs View File

@@ -511,8 +511,5 @@ namespace BeDesignerSCADA.Controls
}
}
#endregion


}
}

+ 21
- 2
BeDesignerSCADA/Controls/MenuRunCanvas.xaml.cs View File

@@ -201,12 +201,21 @@ namespace BeDesignerSCADA.Controls
//拉出按钮
lachu.HorizontalAlignment = HorizontalAlignment.Right;
lachu.VerticalAlignment = VerticalAlignment.Stretch;
lachu.BorderThickness = new Thickness(1, 0, 0, 0);
lachu.BorderThickness = new Thickness(0, 0, 1, 0);
//closeGrid
closeGrid.HorizontalAlignment = HorizontalAlignment.Center;
closeGrid.VerticalAlignment = VerticalAlignment.Bottom;
closeGrid.Margin = new Thickness(10);
ButClose.Margin = new Thickness(0, 5, 0, 0);
FrameworkElement border = null;
foreach (FrameworkElement item in waibustack.Children)
{
if (item is Border)
border = item;
}
waibustack.Children.Remove(border);
waibustack.Children.Insert(0,border);

break;
case MenuAlignment.底部:
//左边菜单栏
@@ -236,16 +245,26 @@ namespace BeDesignerSCADA.Controls
//外部Stackpanl
waibustack.Orientation = Orientation.Vertical;
waibustack.VerticalAlignment = VerticalAlignment.Bottom;
waibustack.Margin = new Thickness(0, 0, 0, 25);
//拉出按钮
lachu.HorizontalAlignment = HorizontalAlignment.Stretch;
lachu.VerticalAlignment = VerticalAlignment.Bottom;
lachu.LayoutTransform = new RotateTransform() { Angle = 270 };
lachu.BorderThickness = new Thickness(0, 0, 1, 0);
lachu.BorderThickness = new Thickness(1, 0, 0, 0);
lachu.Margin = new Thickness(0, 0, 0, 0);
//closeGrid
closeGrid.HorizontalAlignment = HorizontalAlignment.Right;
closeGrid.VerticalAlignment = VerticalAlignment.Center;
closeGrid.Margin = new Thickness(10, 0, 10, 0);
ButClose.Margin = new Thickness(0, 5, 0, 0);
border = null;
foreach (FrameworkElement item in waibustack.Children)
{
if (item is Border)
border = item;
}
waibustack.Children.Remove(border);
waibustack.Children.Insert(0, border);
break;
default:
break;


+ 60
- 3
BeDesignerSCADA/Helper/SystemHelper.cs View File

@@ -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,8 +216,6 @@ namespace BeDesignerSCADA.Helper
return drives[i];
return nona;
}


#endregion

/// <summary>
@@ -247,6 +244,66 @@ namespace BeDesignerSCADA.Helper
scrollViewer.ScrollToHorizontalOffset(tarPos.X);
}

/// <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)]


Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save