@@ -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> | |||
@@ -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> | |||
@@ -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}" | |||
@@ -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, "提示", $"配方下发成功!"); | |||
} | |||
} | |||
} | |||
@@ -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> |
@@ -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 | |||
{ | |||
@@ -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> | |||
@@ -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; | |||
} | |||
} | |||
} | |||
} |
@@ -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 } | |||
}; | |||
} | |||
} |
@@ -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); | |||
} |
@@ -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(); | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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; | |||
}; | |||
} | |||
} |
@@ -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; } | |||
} |
@@ -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) | |||
}; | |||
} | |||
} |
@@ -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> { }; | |||
} | |||
} | |||
} | |||
} | |||
} |
@@ -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() | |||
{ | |||
@@ -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>(); | |||
} | |||
} |
@@ -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>(); | |||
} | |||
} |
@@ -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> |
@@ -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(); | |||
} | |||
} | |||
} |
@@ -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> | |||
@@ -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; | |||
} | |||
} | |||
} | |||
@@ -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" | |||
@@ -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> |
@@ -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; | |||
} | |||
} | |||
} |
@@ -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)); | |||
} | |||
} | |||
} |
@@ -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 }; | |||
@@ -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"); | |||
} | |||
} | |||
} |
@@ -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)); | |||
} | |||
} | |||
} |
@@ -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(); | |||
} | |||
} | |||
} |
@@ -21,4 +21,8 @@ | |||
<PackageReference Include="Microsoft.Toolkit.Mvvm" Version="7.1.2" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<Folder Include="奶咖一体机\" /> | |||
</ItemGroup> | |||
</Project> |
@@ -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, | |||
}); | |||
} | |||
//} | |||
@@ -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" }, | |||
}; | |||
} | |||
} | |||
@@ -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"> | |||
@@ -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 | |||
} | |||
} | |||
} |
@@ -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> | |||
@@ -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() | |||
@@ -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>(); | |||
} | |||
} |
@@ -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; } | |||
} | |||
@@ -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); | |||
@@ -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 | |||
@@ -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(); } } | |||
@@ -0,0 +1,37 @@ | |||
<UserControl x:Class="BPASmartClient.SCADAControl.CustomerControls.FYFTheListBox" | |||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | |||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | |||
xmlns:local="clr-namespace:BPASmartClient.SCADAControl.CustomerControls" | |||
mc:Ignorable="d" | |||
d:DesignHeight="450" d:DesignWidth="800"> | |||
<ListView | |||
ItemsSource="{Binding ViewItems,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" | |||
Background="{x:Null}" Foreground="White" | |||
PreviewMouseMove="ListView_PreviewMouseMove" | |||
PreviewMouseLeftButtonUp="lisbox_PreviewMouseLeftButtonUp"> | |||
<ListBox.ItemTemplate> | |||
<ItemContainerTemplate> | |||
<Border x:Name="border" Tag="border" BorderBrush="Aquamarine" MouseLeftButtonDown="Border_MouseLeftButtonDown" BorderThickness="1" Padding="5" Background="#FF18888A"> | |||
<Grid> | |||
<Grid.ColumnDefinitions> | |||
<ColumnDefinition Width="60"/> | |||
<ColumnDefinition/> | |||
<ColumnDefinition Width="100"/> | |||
<ColumnDefinition Width="60"/> | |||
</Grid.ColumnDefinitions> | |||
<TextBlock Margin="10,0,10,0" Grid.Column="0" Text="{Binding Name,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"></TextBlock> | |||
<TextBlock Grid.Column="1" Text="{Binding Ph,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"></TextBlock> | |||
<TextBox Width="100" Grid.Column="1"></TextBox> | |||
<ComboBox Grid.Column="2" Width="60"> | |||
<ComboBoxItem>sdsds</ComboBoxItem> | |||
<ComboBoxItem>sdsds</ComboBoxItem> | |||
<ComboBoxItem>sdsds</ComboBoxItem> | |||
</ComboBox> | |||
</Grid> | |||
</Border> | |||
</ItemContainerTemplate> | |||
</ListBox.ItemTemplate> | |||
</ListView> | |||
</UserControl> |
@@ -0,0 +1,391 @@ | |||
using BPASmartClient.Compiler; | |||
using Microsoft.Toolkit.Mvvm.ComponentModel; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Collections.ObjectModel; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
using System.Windows; | |||
using System.Windows.Controls; | |||
using System.Windows.Controls.Primitives; | |||
using System.Windows.Data; | |||
using System.Windows.Documents; | |||
using System.Windows.Input; | |||
using System.Windows.Media; | |||
using System.Windows.Media.Effects; | |||
using System.Windows.Media.Imaging; | |||
using System.Windows.Navigation; | |||
using System.Windows.Shapes; | |||
namespace BPASmartClient.SCADAControl.CustomerControls | |||
{ | |||
/// <summary> | |||
/// FYFTheListBox.xaml 的交互逻辑 | |||
/// </summary> | |||
public partial class FYFTheListBox : UserControl | |||
{ | |||
/// <summary> | |||
/// 数据model | |||
/// </summary> | |||
public ListBoxDataModel TheListBoxModel = new ListBoxDataModel(); | |||
public event EventHandler PropertyChange; //声明一个事件 | |||
ListView listView = null; | |||
public FYFTheListBox() | |||
{ | |||
InitializeComponent(); | |||
this.DataContext = TheListBoxModel; | |||
TheListBoxModel.ViewItems.Add(new ItemModel { Name = "张三", Ph = "125486545" }); | |||
TheListBoxModel.ViewItems.Add(new ItemModel { Name = "李四", Ph = "125486545" }); | |||
TheListBoxModel.ViewItems.Add(new ItemModel { Name = "王麻子", Ph = "125486545" }); | |||
TheListBoxModel.ViewItems.Add(new ItemModel { Name = "二货", Ph = "125486545" }); | |||
TheListBoxModel.ViewItems.Add(new ItemModel { Name = "张三1", Ph = "125486545" }); | |||
TheListBoxModel.ViewItems.Add(new ItemModel { Name = "李四2", Ph = "125486545" }); | |||
TheListBoxModel.ViewItems.Add(new ItemModel { Name = "王麻子3", Ph = "125486545" }); | |||
this.SizeChanged += Silos_SizeChanged; ; | |||
} | |||
private void Silos_SizeChanged(object sender, SizeChangedEventArgs e) | |||
{ | |||
if (listView == null) | |||
{ | |||
foreach (ListView tb in Utils.FindVisualChildren<ListView>(this)) | |||
{ | |||
// do something with tb here | |||
listView = tb; | |||
} | |||
} | |||
} | |||
public string ControlType => "控件"; | |||
private bool isExecuteState; | |||
public bool IsExecuteState | |||
{ | |||
get { return isExecuteState; } | |||
set | |||
{ | |||
isExecuteState = value; | |||
if (IsExecuteState) | |||
{ | |||
Register(); | |||
} | |||
} | |||
} | |||
public void Register() | |||
{ | |||
} | |||
#region 移动事件 | |||
/// <summary> | |||
/// 当前拖动子控件流 | |||
/// </summary> | |||
private UIElement ChildElement; | |||
/// <summary> | |||
/// 当前拖拽子控件Item | |||
/// </summary> | |||
private ListBoxItem ChildListBoxItem; | |||
/// <summary> | |||
/// 是否已经按下 | |||
/// </summary> | |||
private bool isDown = false; | |||
/// <summary> | |||
/// 当前拖动的Pop窗体 | |||
/// </summary> | |||
private Popup DropPopup = null; | |||
/// <summary> | |||
/// 鼠标按下事件 | |||
/// </summary> | |||
/// <param name="sender"></param> | |||
/// <param name="e"></param> | |||
private void Border_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) | |||
{ | |||
try | |||
{ | |||
//isDown变量是防止多次操作。 | |||
if (isDown) | |||
{ | |||
isDown = false; | |||
return; | |||
} | |||
ChildElement = (UIElement)sender; | |||
ChildElement.CaptureMouse();//设置了鼠标捕获,这样它可以不受到其它控件的影响。 | |||
ChildListBoxItem = Utils.FindVisualParent<ListBoxItem>(VisualTreeHelper.HitTest(ChildElement, e.GetPosition(ChildElement)).VisualHit); | |||
//创建一个Pop,表明拖拽开始 | |||
CreatePopup(ChildElement, e); | |||
isDown = true; | |||
} | |||
catch (Exception ex) | |||
{ | |||
} | |||
} | |||
/// <summary> | |||
/// 鼠标抬起事件 | |||
/// </summary> | |||
/// <param name="sender"></param> | |||
/// <param name="e"></param> | |||
private void lisbox_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e) | |||
{ | |||
try | |||
{ | |||
//鼠标未按下返回 | |||
if (!isDown) return; | |||
isDown = false; | |||
//关闭Pop窗体 | |||
if (this.DropPopup != null) | |||
{ | |||
this.DropPopup.IsOpen = false; | |||
this.DropPopup.Child = null; | |||
this.DropPopup = null; | |||
} | |||
//蒙层关闭,表明结束拖拽 | |||
MoveListBoxStyle(null, false); | |||
//当控件具有鼠标捕获的话,则释放该捕获。 | |||
ChildElement.ReleaseMouseCapture(); | |||
} | |||
catch (Exception ex) | |||
{ | |||
} | |||
} | |||
/// <summary> | |||
/// 鼠标移动事件 | |||
/// </summary> | |||
/// <param name="sender"></param> | |||
/// <param name="e"></param> | |||
private void ListView_PreviewMouseMove(object sender, MouseEventArgs e) | |||
{ | |||
try | |||
{ | |||
if (isDown == false) return; | |||
if (e.LeftButton != MouseButtonState.Pressed) | |||
lisbox_PreviewMouseLeftButtonUp(null, null); | |||
Point ptLeftUp = new Point(0, 0); | |||
Point ptRightDown = new Point(this.ActualWidth, this.ActualHeight); | |||
ptLeftUp = this.PointToScreen(ptLeftUp); | |||
ptRightDown = this.PointToScreen(ptRightDown); | |||
double y = e.GetPosition(this).Y; | |||
double x = e.GetPosition(this).X; | |||
if (DropPopup != null)//下面两句是设置Popup控件的位置除以2是想让鼠标在它的中心 | |||
{ | |||
DropPopup.HorizontalOffset = ptLeftUp.X + x - ((FrameworkElement)ChildElement).ActualWidth / 2; | |||
DropPopup.VerticalOffset = ptLeftUp.Y + y - ((FrameworkElement)ChildElement).ActualHeight / 2; | |||
} | |||
//蒙层打开,表明拖拽开始,设置透明度和显示状态 | |||
MoveListBoxStyle(e, true); | |||
} | |||
catch (Exception ex) | |||
{ | |||
} | |||
} | |||
/// <summary> | |||
/// 移动效果 | |||
/// </summary> | |||
/// <param name="boxItem"></param> | |||
private void MoveListBoxStyle(MouseEventArgs e, bool isBool) | |||
{ | |||
try | |||
{ | |||
if (isBool)//为真,根据鼠标位置设置行透明度和显示状态 | |||
{ | |||
//移动到某行减轻某行 暗黑 | |||
foreach (ListBoxItem item in Utils.FindVisualChildren<ListBoxItem>(listView)) | |||
{ | |||
if (item != ChildListBoxItem)//这就是其他控件 | |||
{ | |||
double item_width = item.ActualWidth; //当前行宽 | |||
double item_height = item.ActualHeight; //当前行高 | |||
double item_x = e.GetPosition(item).X; //鼠标相对当前行X位移 | |||
double item_y = e.GetPosition(item).Y; //鼠标相对当前行Y位移 | |||
if (item_y <= item_height && item_y > 0 && item_x > 0 && item_x <= item_width)//鼠标进入哪一行,则将那一行变灰 | |||
{ | |||
item.Opacity = 0.5; | |||
int lao_index = TheListBoxModel.ViewItems.IndexOf(item.Content as ItemModel); | |||
int new_index = TheListBoxModel.ViewItems.IndexOf(ChildListBoxItem.Content as ItemModel); | |||
TheListBoxModel.ViewItems.Move(lao_index, new_index); | |||
} | |||
else //鼠标没在哪一行,则保持原状 | |||
{ | |||
item.Opacity = 1; | |||
} | |||
} | |||
else | |||
{ | |||
item.Visibility = Visibility.Hidden; | |||
} | |||
} | |||
} | |||
else//为假 恢复所有行透明度和显示状态 | |||
{ | |||
//移动到某行减轻某行 暗黑 | |||
foreach (ListBoxItem item in Utils.FindVisualChildren<ListBoxItem>(listView)) | |||
{ | |||
item.Opacity = 1; | |||
item.Visibility = Visibility.Visible; | |||
} | |||
} | |||
} | |||
catch (Exception ex) | |||
{ | |||
} | |||
} | |||
/// <summary> | |||
/// 创建浮动窗口 | |||
/// </summary> | |||
/// <param name="dragElement"></param> | |||
/// <param name="e"></param> | |||
private void CreatePopup(Visual dragElement, MouseButtonEventArgs e) | |||
{ | |||
//使用PointToScreen函数可以将点转换为屏幕坐标 | |||
//首先获取当前窗体的左上角和右下角两点的坐标 | |||
Point ptLeftUp = new Point(0, 0); | |||
//转换获取到这个窗口相对于屏幕两个坐标 | |||
ptLeftUp = this.PointToScreen(ptLeftUp); | |||
//获取myGrid的实际宽高,主 | |||
double y = e.GetPosition(this).Y; | |||
double x = e.GetPosition(this).X; | |||
//拖拽Popup框 | |||
this.DropPopup = new Popup(); | |||
Border border = new Border(); | |||
border.Margin = new Thickness(0, 0, 8, 8); | |||
DropShadowEffect effect = new DropShadowEffect(); | |||
effect.Opacity = 1; | |||
effect.ShadowDepth = -14; | |||
effect.BlurRadius = 9; | |||
effect.Color = Color.FromArgb(100, 0, 0, 0); | |||
border.Effect = effect; | |||
//矩阵框 | |||
Rectangle r = new Rectangle(); | |||
r.Width = ((FrameworkElement)dragElement).ActualWidth; | |||
r.Height = ((FrameworkElement)dragElement).ActualHeight; | |||
r.Fill = new VisualBrush(dragElement); | |||
border.Child = r; | |||
this.DropPopup.Child = border; | |||
DropPopup.AllowsTransparency = true; | |||
DropPopup.HorizontalOffset = ptLeftUp.X + x - ((FrameworkElement)dragElement).ActualWidth / 2; | |||
DropPopup.VerticalOffset = ptLeftUp.Y + y - ((FrameworkElement)dragElement).ActualHeight / 2; | |||
this.DropPopup.IsOpen = true; | |||
} | |||
#endregion | |||
} | |||
/// <summary> | |||
/// 当前项数据Model | |||
/// </summary> | |||
public class ListBoxDataModel : ObservableObject | |||
{ | |||
private ObservableCollection<ItemModel> _ViewItems; | |||
public ObservableCollection<ItemModel> ViewItems | |||
{ | |||
get | |||
{ | |||
return _ViewItems; | |||
} | |||
set | |||
{ | |||
_ViewItems = value; | |||
OnPropertyChanged("ViewItems"); | |||
} | |||
} | |||
public ListBoxDataModel() | |||
{ | |||
ViewItems = new ObservableCollection<ItemModel>(); | |||
} | |||
} | |||
/// <summary> | |||
/// 行数据Model | |||
/// </summary> | |||
public class ItemModel : ObservableObject | |||
{ | |||
private string _Name; | |||
public string Name | |||
{ | |||
get | |||
{ | |||
return _Name; | |||
} | |||
set | |||
{ | |||
_Name = value; | |||
OnPropertyChanged("Name"); | |||
} | |||
} | |||
private string _Ph; | |||
public string Ph | |||
{ | |||
get | |||
{ | |||
return _Ph; | |||
} | |||
set | |||
{ | |||
_Ph = value; | |||
OnPropertyChanged("Ph"); | |||
} | |||
} | |||
} | |||
/// <summary> | |||
/// 帮助类 | |||
/// </summary> | |||
internal static class Utils | |||
{ | |||
/// <summary> | |||
/// 根据子元素查找父元素 | |||
/// </summary> | |||
/// <typeparam name="T"></typeparam> | |||
/// <param name="obj"></param> | |||
/// <returns></returns> | |||
public static T FindVisualParent<T>(DependencyObject obj) where T : class | |||
{ | |||
while (obj != null) | |||
{ | |||
if (obj is T) | |||
return obj as T; | |||
obj = VisualTreeHelper.GetParent(obj); | |||
} | |||
return null; | |||
} | |||
/// <summary> | |||
/// 查询子控件 | |||
/// </summary> | |||
/// <typeparam name="T"></typeparam> | |||
/// <param name="obj"></param> | |||
/// <returns></returns> | |||
public static IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject | |||
{ | |||
if (depObj != null) | |||
{ | |||
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++) | |||
{ | |||
DependencyObject child = VisualTreeHelper.GetChild(depObj, i); | |||
if (child != null && child is T) | |||
{ | |||
yield return (T)child; | |||
} | |||
foreach (T childOfChild in FindVisualChildren<T>(child)) | |||
{ | |||
yield return childOfChild; | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} |
@@ -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> | |||
@@ -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"> | |||
@@ -45,9 +45,19 @@ namespace BeDesignerSCADA.Controls | |||
viewModel.LayoutsPath = _Path; | |||
this.DataContext = viewModel; | |||
viewModel.Loaded(cav, runCanvas); | |||
//控件加载 | |||
Assembly assembly = Assembly.LoadFile($"{System.AppDomain.CurrentDomain.BaseDirectory}\\BPASmartClient.SCADAControl.dll"); //Assembly.GetExecutingAssembly(); | |||
CtlList.ItemsSource = assembly.GetTypes().Where(t => t.GetInterface("IExecutable") != null).OrderBy(o => o.Name)?.ToList(); | |||
List<Type> types = assembly.GetTypes().Where(t => t.GetInterface("IExecutable") != null)?.ToList(); | |||
List<Type> typesView = new List<Type>(); | |||
viewModel.ControlsNameValues.ToList().OrderBy(o => o.Value)?.ToList().ForEach(par => | |||
{ | |||
Type type= types?.Find(p => p.Name == par.Key); | |||
if (type != null) | |||
typesView.Add(type); | |||
}); | |||
CtlList.ItemsSource = typesView; | |||
//读取文件 | |||
FileRead(_Path); | |||
} | |||
@@ -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)] | |||
@@ -0,0 +1,37 @@ | |||
<UserControl x:Class="WPFDemo.TheListBox" | |||
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:WPFDemo" | |||
mc:Ignorable="d" | |||
d:DesignHeight="450" d:DesignWidth="800"> | |||
<ListView x:Name="listView" | |||
ItemsSource="{Binding ViewItems,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" | |||
Background="{x:Null}" Foreground="White" | |||
PreviewMouseMove="ListView_PreviewMouseMove" | |||
PreviewMouseLeftButtonUp="lisbox_PreviewMouseLeftButtonUp"> | |||
<ListBox.ItemTemplate> | |||
<ItemContainerTemplate> | |||
<Border x:Name="border" Tag="border" BorderBrush="Aquamarine" MouseLeftButtonDown="Border_MouseLeftButtonDown" BorderThickness="1" Padding="5" Background="#FF18888A"> | |||
<Grid> | |||
<Grid.ColumnDefinitions> | |||
<ColumnDefinition Width="60"/> | |||
<ColumnDefinition/> | |||
<ColumnDefinition Width="100"/> | |||
<ColumnDefinition Width="60"/> | |||
</Grid.ColumnDefinitions> | |||
<TextBlock Margin="10,0,10,0" Grid.Column="0" Text="{Binding Name,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"></TextBlock> | |||
<TextBlock Grid.Column="1" Text="{Binding Ph,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"></TextBlock> | |||
<TextBox Width="100" Grid.Column="1"></TextBox> | |||
<ComboBox Grid.Column="2" Width="60"> | |||
<ComboBoxItem>sdsds</ComboBoxItem> | |||
<ComboBoxItem>sdsds</ComboBoxItem> | |||
<ComboBoxItem>sdsds</ComboBoxItem> | |||
</ComboBox> | |||
</Grid> | |||
</Border> | |||
</ItemContainerTemplate> | |||
</ListBox.ItemTemplate> | |||
</ListView> | |||
</UserControl> |
@@ -0,0 +1,357 @@ | |||
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 WPFDemo | |||
{ | |||
/// <summary> | |||
/// fyf 创建测试案例 | |||
/// TheListBox.xaml 的交互逻辑 | |||
/// </summary> | |||
public partial class TheListBox : UserControl | |||
{ | |||
/// <summary> | |||
/// 数据model | |||
/// </summary> | |||
public ListBoxDataModel TheListBoxModel = new ListBoxDataModel(); | |||
public TheListBox() | |||
{ | |||
InitializeComponent(); | |||
this.DataContext = TheListBoxModel; | |||
TheListBoxModel.ViewItems.Add(new ItemModel { Name = "张三", Ph = "125486545" }); | |||
TheListBoxModel.ViewItems.Add(new ItemModel { Name = "李四", Ph = "125486545" }); | |||
TheListBoxModel.ViewItems.Add(new ItemModel { Name = "王麻子", Ph = "125486545" }); | |||
TheListBoxModel.ViewItems.Add(new ItemModel { Name = "二货", Ph = "125486545" }); | |||
TheListBoxModel.ViewItems.Add(new ItemModel { Name = "张三1", Ph = "125486545" }); | |||
TheListBoxModel.ViewItems.Add(new ItemModel { Name = "李四2", Ph = "125486545" }); | |||
TheListBoxModel.ViewItems.Add(new ItemModel { Name = "王麻子3", Ph = "125486545" }); | |||
} | |||
#region 移动事件 | |||
/// <summary> | |||
/// 当前拖动子控件流 | |||
/// </summary> | |||
private UIElement ChildElement; | |||
/// <summary> | |||
/// 当前拖拽子控件Item | |||
/// </summary> | |||
private ListBoxItem ChildListBoxItem; | |||
/// <summary> | |||
/// 是否已经按下 | |||
/// </summary> | |||
private bool isDown = false; | |||
/// <summary> | |||
/// 当前拖动的Pop窗体 | |||
/// </summary> | |||
private Popup DropPopup = null; | |||
/// <summary> | |||
/// 鼠标按下事件 | |||
/// </summary> | |||
/// <param name="sender"></param> | |||
/// <param name="e"></param> | |||
private void Border_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) | |||
{ | |||
try | |||
{ | |||
//isDown变量是防止多次操作。 | |||
if (isDown) | |||
{ | |||
isDown = false; | |||
return; | |||
} | |||
ChildElement = (UIElement)sender; | |||
ChildElement.CaptureMouse();//设置了鼠标捕获,这样它可以不受到其它控件的影响。 | |||
ChildListBoxItem = Utils.FindVisualParent<ListBoxItem>(VisualTreeHelper.HitTest(ChildElement, e.GetPosition(ChildElement)).VisualHit); | |||
//创建一个Pop,表明拖拽开始 | |||
CreatePopup(ChildElement, e); | |||
isDown = true; | |||
} | |||
catch (Exception ex) | |||
{ | |||
} | |||
} | |||
/// <summary> | |||
/// 鼠标抬起事件 | |||
/// </summary> | |||
/// <param name="sender"></param> | |||
/// <param name="e"></param> | |||
private void lisbox_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e) | |||
{ | |||
try | |||
{ | |||
//鼠标未按下返回 | |||
if (!isDown) return; | |||
isDown = false; | |||
//关闭Pop窗体 | |||
if (this.DropPopup != null) | |||
{ | |||
this.DropPopup.IsOpen = false; | |||
this.DropPopup.Child = null; | |||
this.DropPopup = null; | |||
} | |||
//蒙层关闭,表明结束拖拽 | |||
MoveListBoxStyle(null, false); | |||
//当控件具有鼠标捕获的话,则释放该捕获。 | |||
ChildElement.ReleaseMouseCapture(); | |||
} | |||
catch (Exception ex) | |||
{ | |||
} | |||
} | |||
/// <summary> | |||
/// 鼠标移动事件 | |||
/// </summary> | |||
/// <param name="sender"></param> | |||
/// <param name="e"></param> | |||
private void ListView_PreviewMouseMove(object sender, MouseEventArgs e) | |||
{ | |||
try | |||
{ | |||
if (isDown == false) return; | |||
if (e.LeftButton != MouseButtonState.Pressed) | |||
lisbox_PreviewMouseLeftButtonUp(null, null); | |||
Point ptLeftUp = new Point(0, 0); | |||
Point ptRightDown = new Point(this.ActualWidth, this.ActualHeight); | |||
ptLeftUp = this.PointToScreen(ptLeftUp); | |||
ptRightDown = this.PointToScreen(ptRightDown); | |||
double y = e.GetPosition(this).Y; | |||
double x = e.GetPosition(this).X; | |||
if (DropPopup != null)//下面两句是设置Popup控件的位置除以2是想让鼠标在它的中心 | |||
{ | |||
DropPopup.HorizontalOffset = ptLeftUp.X + x - ((FrameworkElement)ChildElement).ActualWidth / 2; | |||
DropPopup.VerticalOffset = ptLeftUp.Y + y - ((FrameworkElement)ChildElement).ActualHeight / 2; | |||
} | |||
//蒙层打开,表明拖拽开始,设置透明度和显示状态 | |||
MoveListBoxStyle(e, true); | |||
} | |||
catch (Exception ex) | |||
{ | |||
} | |||
} | |||
/// <summary> | |||
/// 移动效果 | |||
/// </summary> | |||
/// <param name="boxItem"></param> | |||
private void MoveListBoxStyle(MouseEventArgs e, bool isBool) | |||
{ | |||
try | |||
{ | |||
if (isBool)//为真,根据鼠标位置设置行透明度和显示状态 | |||
{ | |||
//移动到某行减轻某行 暗黑 | |||
foreach (ListBoxItem item in Utils.FindVisualChildren<ListBoxItem>(listView)) | |||
{ | |||
if (item != ChildListBoxItem)//这就是其他控件 | |||
{ | |||
double item_width = item.ActualWidth; //当前行宽 | |||
double item_height = item.ActualHeight; //当前行高 | |||
double item_x = e.GetPosition(item).X; //鼠标相对当前行X位移 | |||
double item_y = e.GetPosition(item).Y; //鼠标相对当前行Y位移 | |||
if (item_y <= item_height && item_y > 0 && item_x > 0 && item_x <= item_width)//鼠标进入哪一行,则将那一行变灰 | |||
{ | |||
item.Opacity = 0.5; | |||
int lao_index = TheListBoxModel.ViewItems.IndexOf(item.Content as ItemModel); | |||
int new_index = TheListBoxModel.ViewItems.IndexOf(ChildListBoxItem.Content as ItemModel); | |||
TheListBoxModel.ViewItems.Move(lao_index, new_index); | |||
} | |||
else //鼠标没在哪一行,则保持原状 | |||
{ | |||
item.Opacity = 1; | |||
} | |||
} | |||
else | |||
{ | |||
item.Visibility = Visibility.Hidden; | |||
} | |||
} | |||
} | |||
else//为假 恢复所有行透明度和显示状态 | |||
{ | |||
//移动到某行减轻某行 暗黑 | |||
foreach (ListBoxItem item in Utils.FindVisualChildren<ListBoxItem>(listView)) | |||
{ | |||
item.Opacity = 1; | |||
item.Visibility = Visibility.Visible; | |||
} | |||
} | |||
} | |||
catch (Exception ex) | |||
{ | |||
} | |||
} | |||
/// <summary> | |||
/// 创建浮动窗口 | |||
/// </summary> | |||
/// <param name="dragElement"></param> | |||
/// <param name="e"></param> | |||
private void CreatePopup(Visual dragElement, MouseButtonEventArgs e) | |||
{ | |||
//使用PointToScreen函数可以将点转换为屏幕坐标 | |||
//首先获取当前窗体的左上角和右下角两点的坐标 | |||
Point ptLeftUp = new Point(0, 0); | |||
//转换获取到这个窗口相对于屏幕两个坐标 | |||
ptLeftUp = this.PointToScreen(ptLeftUp); | |||
//获取myGrid的实际宽高,主 | |||
double y = e.GetPosition(this).Y; | |||
double x = e.GetPosition(this).X; | |||
//拖拽Popup框 | |||
this.DropPopup = new Popup(); | |||
Border border = new Border(); | |||
border.Margin = new Thickness(0, 0, 8, 8); | |||
DropShadowEffect effect = new DropShadowEffect(); | |||
effect.Opacity = 1; | |||
effect.ShadowDepth = -14; | |||
effect.BlurRadius = 9; | |||
effect.Color = Color.FromArgb(100, 0, 0, 0); | |||
border.Effect = effect; | |||
//矩阵框 | |||
Rectangle r = new Rectangle(); | |||
r.Width = ((FrameworkElement)dragElement).ActualWidth; | |||
r.Height = ((FrameworkElement)dragElement).ActualHeight; | |||
r.Fill = new VisualBrush(dragElement); | |||
border.Child = r; | |||
this.DropPopup.Child = border; | |||
DropPopup.AllowsTransparency = true; | |||
DropPopup.HorizontalOffset = ptLeftUp.X + x - ((FrameworkElement)dragElement).ActualWidth / 2; | |||
DropPopup.VerticalOffset = ptLeftUp.Y + y - ((FrameworkElement)dragElement).ActualHeight / 2; | |||
this.DropPopup.IsOpen = true; | |||
} | |||
#endregion | |||
} | |||
/// <summary> | |||
/// 当前项数据Model | |||
/// </summary> | |||
public class ListBoxDataModel : ObservableObject | |||
{ | |||
private ObservableCollection<ItemModel> _ViewItems; | |||
public ObservableCollection<ItemModel> ViewItems | |||
{ | |||
get | |||
{ | |||
return _ViewItems; | |||
} | |||
set | |||
{ | |||
_ViewItems = value; | |||
OnPropertyChanged("ViewItems"); | |||
} | |||
} | |||
public ListBoxDataModel() | |||
{ | |||
ViewItems = new ObservableCollection<ItemModel>(); | |||
} | |||
} | |||
/// <summary> | |||
/// 行数据Model | |||
/// </summary> | |||
public class ItemModel : ObservableObject | |||
{ | |||
private string _Name; | |||
public string Name | |||
{ | |||
get | |||
{ | |||
return _Name; | |||
} | |||
set | |||
{ | |||
_Name = value; | |||
OnPropertyChanged("Name"); | |||
} | |||
} | |||
private string _Ph; | |||
public string Ph | |||
{ | |||
get | |||
{ | |||
return _Ph; | |||
} | |||
set | |||
{ | |||
_Ph = value; | |||
OnPropertyChanged("Ph"); | |||
} | |||
} | |||
} | |||
/// <summary> | |||
/// 帮助类 | |||
/// </summary> | |||
internal static class Utils | |||
{ | |||
/// <summary> | |||
/// 根据子元素查找父元素 | |||
/// </summary> | |||
/// <typeparam name="T"></typeparam> | |||
/// <param name="obj"></param> | |||
/// <returns></returns> | |||
public static T FindVisualParent<T>(DependencyObject obj) where T : class | |||
{ | |||
while (obj != null) | |||
{ | |||
if (obj is T) | |||
return obj as T; | |||
obj = VisualTreeHelper.GetParent(obj); | |||
} | |||
return null; | |||
} | |||
/// <summary> | |||
/// 查询子控件 | |||
/// </summary> | |||
/// <typeparam name="T"></typeparam> | |||
/// <param name="obj"></param> | |||
/// <returns></returns> | |||
public static IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject | |||
{ | |||
if (depObj != null) | |||
{ | |||
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++) | |||
{ | |||
DependencyObject child = VisualTreeHelper.GetChild(depObj, i); | |||
if (child != null && child is T) | |||
{ | |||
yield return (T)child; | |||
} | |||
foreach (T childOfChild in FindVisualChildren<T>(child)) | |||
{ | |||
yield return childOfChild; | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} |
@@ -10,29 +10,10 @@ | |||
<Grid.Background> | |||
<ImageBrush ImageSource="/bj.png"/> | |||
</Grid.Background> | |||
<ListView x:Name="lisbox" ItemsSource="{Binding ViewItems,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" | |||
Background="{x:Null}" Foreground="White" | |||
PreviewMouseMove="ListView_PreviewMouseMove" | |||
PreviewMouseLeftButtonUp="lisbox_PreviewMouseLeftButtonUp"> | |||
<ListBox.ItemTemplate> | |||
<ItemContainerTemplate> | |||
<Grid MouseLeftButtonDown="Grid_MouseLeftButtonDown" > | |||
<Border BorderBrush="Aquamarine" BorderThickness="1" Padding="5"> | |||
<Grid> | |||
<Grid.ColumnDefinitions> | |||
<ColumnDefinition/> | |||
<ColumnDefinition/> | |||
<ColumnDefinition/> | |||
<ColumnDefinition/> | |||
</Grid.ColumnDefinitions> | |||
<TextBlock Grid.Column="0" Text="{Binding Name,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"></TextBlock> | |||
<TextBlock Grid.Column="1" Text="{Binding Ph,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"></TextBlock> | |||
</Grid> | |||
</Border> | |||
</Grid> | |||
</ItemContainerTemplate> | |||
</ListBox.ItemTemplate> | |||
</ListView> | |||
<Grid.RowDefinitions> | |||
<RowDefinition Height="50"/> | |||
<RowDefinition Height="*"/> | |||
</Grid.RowDefinitions> | |||
<local:TheListBox HorizontalAlignment="Right" Grid.Row="1"></local:TheListBox> | |||
</Grid> | |||
</Window> |
@@ -23,307 +23,9 @@ namespace WPFDemo | |||
/// </summary> | |||
public partial class Window2 : Window | |||
{ | |||
TestModel testModel=new TestModel(); | |||
public Window2() | |||
{ | |||
InitializeComponent(); | |||
this.DataContext = testModel; | |||
testModel.ViewItems.Add(new PageModel {Name="张三", Ph="125486545" }); | |||
testModel.ViewItems.Add(new PageModel { Name = "李四", Ph = "125486545" }); | |||
testModel.ViewItems.Add(new PageModel { Name = "王麻子", Ph = "125486545" }); | |||
testModel.ViewItems.Add(new PageModel { Name = "二货", Ph = "125486545" }); | |||
} | |||
#region 移动事件 | |||
/// <summary> | |||
/// 当前拖动子控件流 | |||
/// </summary> | |||
private UIElement ChildElement; | |||
/// <summary> | |||
/// 是否已经按下 | |||
/// </summary> | |||
private bool isDown = false; | |||
/// <summary> | |||
/// 按下记录初始鼠标点位 | |||
/// 鼠标相对与拖动子控件的位置(偏移量) | |||
/// </summary> | |||
private Point InitPoint; | |||
/// <summary> | |||
/// 当前拖动的Pop窗体 | |||
/// </summary> | |||
private Popup DropPopup = null; | |||
/// <summary> | |||
/// 鼠标按下事件 | |||
/// </summary> | |||
/// <param name="sender"></param> | |||
/// <param name="e"></param> | |||
private void Grid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) | |||
{ | |||
try | |||
{ | |||
//isDown变量是防止多次操作。 | |||
if (isDown) | |||
{ | |||
isDown = false; | |||
return; | |||
} | |||
ChildElement = (UIElement)sender; | |||
ChildElement.CaptureMouse();//设置了鼠标捕获,这样它可以不受到其它控件的影响。 | |||
InitPoint= new Point(e.GetPosition(ChildElement).X, e.GetPosition(ChildElement).Y); | |||
//加蒙层,表明已经开始拖动 | |||
//暂时未加 | |||
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; | |||
} | |||
//蒙层关闭 | |||
ChildElement.ReleaseMouseCapture();//当控件具有鼠标捕获的话,则释放该捕获。 | |||
//double y = e.GetPosition(this).Y;//获取鼠标抬起时的控件的位置 Y值 | |||
//double start = 0.0; | |||
//int row = 0; | |||
//foreach (RowDefinition rd in myGrid.RowDefinitions) | |||
//{ | |||
// start += rd.ActualHeight; | |||
// if (y < start) | |||
// { | |||
// break; | |||
// } | |||
// row++; | |||
//} | |||
//double x = e.GetPosition(myGrid).X;//获取鼠标抬起时的控件的位置 X值 | |||
//double cstart = 0.0; | |||
//int column = 0; | |||
//foreach (ColumnDefinition cd in myGrid.ColumnDefinitions) | |||
//{ | |||
// cstart += cd.ActualWidth; | |||
// if (x < cstart) | |||
// { | |||
// break; | |||
// } | |||
// column++; | |||
//} | |||
//var initRow = Grid.GetRow(ultUE);//找到控件所在的行 | |||
//var initCol = Grid.GetColumn(ultUE);//找到控件所在的列 | |||
//UIElement uIElement = null; | |||
//if (row != initRow || column != initCol) | |||
//{ | |||
// uIElement = GetChildren(myGrid, row, column); | |||
//} | |||
//if (uIElement != null) | |||
//{ | |||
// //下面是交换两个控件的位置 (需要先移除再加载) | |||
// myGrid.Children.Remove(uIElement); | |||
// Grid.SetColumn(ultUE, column);//指定控件在grid中哪行哪例 | |||
// Grid.SetRow(ultUE, row); | |||
// myGrid.Children.Add(uIElement); | |||
// Grid.SetColumn(uIElement, initCol); | |||
// Grid.SetRow(uIElement, initRow); | |||
//} | |||
} | |||
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; | |||
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(lisbox).Y; | |||
double x = e.GetPosition(lisbox).X; | |||
if (DropPopup != null) | |||
{ | |||
//下面两句是设置Popup控件的位置除以2是想让鼠标在它的中心 | |||
DropPopup.HorizontalOffset = ptLeftUp.X + x - ((FrameworkElement)ChildElement).ActualWidth / 2; | |||
DropPopup.VerticalOffset = ptLeftUp.Y + y - ((FrameworkElement)ChildElement).ActualHeight / 2; | |||
} | |||
//double start = 0.0; | |||
//int row = 0; | |||
//foreach (RowDefinition rd in myGrid.RowDefinitions) | |||
//{ | |||
// start += rd.ActualHeight; | |||
// if (y < start) | |||
// { | |||
// break; | |||
// } | |||
// row++; | |||
//} | |||
//double cstart = 0.0; | |||
//int column = 0; | |||
//foreach (ColumnDefinition cd in myGrid.ColumnDefinitions) | |||
//{ | |||
// cstart += cd.ActualWidth; | |||
// if (x < cstart) | |||
// { | |||
// break; | |||
// } | |||
// column++; | |||
//} | |||
////下面的代码是当鼠标移动到哪个格子哪个格子就会亮起来。 | |||
//UIElement uIElement = GetChildren(myGrid, row, column); | |||
//foreach (UIElement element in myGrid.Children) | |||
//{ | |||
// if (element != ultUE && element != uIElement) | |||
// { | |||
// element.Opacity = moveOpacity; | |||
// } | |||
// else | |||
// { | |||
// element.Opacity = 1; | |||
// } | |||
//} | |||
} | |||
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; | |||
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 | |||
} | |||
public class TestModel : ObservableObject | |||
{ | |||
private ObservableCollection<PageModel> _pageModels; | |||
public ObservableCollection<PageModel> ViewItems | |||
{ | |||
get | |||
{ | |||
return _pageModels; | |||
} | |||
set | |||
{ | |||
_pageModels = value; | |||
OnPropertyChanged("ViewItems"); | |||
} | |||
} | |||
public TestModel() | |||
{ | |||
ViewItems=new ObservableCollection<PageModel>(); | |||
} | |||
} | |||
public class PageModel : 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"); | |||
} | |||
} | |||
} | |||
} |