移植参数编辑变量编辑功能

This commit is contained in:
hsc 2025-11-06 15:30:32 +08:00
parent e87c097c4e
commit e25c2cd3d9
31 changed files with 1847 additions and 243 deletions

View File

@ -25,6 +25,66 @@
<!--自定义style-->
<ResourceDictionary Source="Resources\Styles\WindowStyle.xaml"></ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
<Style TargetType="TextBox"
BasedOn="{StaticResource MaterialDesignTextBox}">
<!-- 禁用自动化属性,避免 null 报错 -->
<Setter Property="AutomationProperties.Name"
Value="" />
<!-- 使用底线风格 -->
<Setter Property="materialDesign:TextFieldAssist.DecorationVisibility"
Value="Hidden" />
<Setter Property="materialDesign:TextFieldAssist.UnderlineBrush"
Value="{DynamicResource MaterialDesignDivider}" />
<Setter Property="BorderThickness"
Value="0,0,0,1" />
<Setter Property="BorderBrush"
Value="{DynamicResource MaterialDesignDivider}" />
<!-- 字体靠下 -->
<Setter Property="VerticalContentAlignment"
Value="Bottom" />
<Setter Property="Padding"
Value="0,0,0,2" />
<!-- 其他优化 -->
<Setter Property="Background"
Value="Transparent" />
<Setter Property="Foreground"
Value="{DynamicResource MaterialDesignBody}" />
<Setter Property="FontSize"
Value="14" />
</Style>
<Style TargetType="ComboBox"
BasedOn="{StaticResource MahApps.Styles.ComboBox}">
<!-- 禁用自动化属性,避免 null 报错 -->
<Setter Property="AutomationProperties.Name"
Value="" />
<!-- 使用底线风格 -->
<Setter Property="materialDesign:TextFieldAssist.DecorationVisibility"
Value="Hidden" />
<Setter Property="materialDesign:TextFieldAssist.UnderlineBrush"
Value="{DynamicResource MaterialDesignDivider}" />
<Setter Property="BorderThickness"
Value="0,0,0,1" />
<Setter Property="BorderBrush"
Value="{DynamicResource MaterialDesignDivider}" />
<!-- 字体靠下 -->
<Setter Property="VerticalContentAlignment"
Value="Bottom" />
<Setter Property="Padding"
Value="0,0,0,2" />
<!-- 其他优化 -->
<Setter Property="Background"
Value="Transparent" />
<Setter Property="Foreground"
Value="{DynamicResource MaterialDesignBody}" />
<Setter Property="FontSize"
Value="14" />
</Style>
</ResourceDictionary>
</Application.Resources>
</prism:PrismApplication>

View File

@ -34,12 +34,13 @@ namespace BOB
containerRegistry.RegisterForNavigation<MainView>("MainView");
//注册弹窗
containerRegistry.RegisterDialog<MessageBoxView, MessageBoxViewModel>("MessageBox");
containerRegistry.RegisterDialog<ParameterSetting, ParameterSettingViewModel>("ParameterSetting");
containerRegistry.RegisterDialog<DeviceSetting, DeviceSettingViewModel>("DeviceSetting");
//注册全局变量
containerRegistry.RegisterSingleton<GlobalVariables>();
}
}
}

View File

@ -7,30 +7,27 @@ using System.Threading.Tasks;
using System.Windows;
using System.Windows.Data;
namespace Common.Converters
namespace BOB.Converters
{
public class BooleanToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
bool input = value is bool b && b;
bool invert = parameter?.ToString()?.ToLower() == "invert";
if (invert)
input = !input;
return input ? Visibility.Visible : Visibility.Collapsed;
if (value is bool boolValue)
{
// 处理反转逻辑
if (parameter?.ToString() == "Inverse")
{
boolValue = !boolValue;
}
return boolValue ? Visibility.Visible : Visibility.Collapsed;
}
return Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
bool output = value is Visibility v && v == Visibility.Visible;
bool invert = parameter?.ToString()?.ToLower() == "invert";
if (invert)
output = !output;
return output;
throw new NotImplementedException();
}
}
}

View File

@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Data;
namespace BOB.Converters
{
public class DeviceNameConverter : IValueConverter
{
private readonly string[] specialName = { "奇偶" };
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is string name)
{
if (specialName.Contains(name))
{
if (parameter?.ToString() == "Inverse")
{
return Visibility.Visible;
}
else if (parameter?.ToString() == "Items")
{
switch (name)
{
case "奇偶":
return new List<string> { "无", "奇", "偶" };
}
}
return Visibility.Collapsed;
}
}
if (parameter?.ToString() == "Inverse")
{
return Visibility.Collapsed;
}
return Visibility.Visible;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

View File

@ -0,0 +1,82 @@
using System;
using System.Globalization;
using System.Linq;
using System.Windows.Data;
namespace BOB.Converters
{
public class EnumValueConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
// 验证输入参数
if (values.Length < 2 || values[0] == null || values[1] == null)
{
return null;
}
try
{
// 获取枚举类型
Type enumType = values[0] as Type;
if (enumType == null || !enumType.IsEnum)
{
return null;
}
// 获取数值
object value = values[1];
// 确保数值类型匹配枚举的底层类型
Type underlyingType = Enum.GetUnderlyingType(enumType);
object convertedValue;
try
{
convertedValue = System.Convert.ChangeType(value, underlyingType);
}
catch
{
// 如果转换失败,尝试直接使用原始值
convertedValue = value;
}
// 将数值转换为枚举值
return Enum.ToObject(enumType, convertedValue);
}
catch
{
// 发生任何异常时返回null
return null;
}
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
if (value == null)
{
return [null, null];
}
try
{
// 获取枚举值的底层数值
Type enumType = value.GetType();
if (!enumType.IsEnum)
{
return [null, null];
}
Type underlyingType = Enum.GetUnderlyingType(enumType);
object numericValue = System.Convert.ChangeType(value, underlyingType);
// 返回枚举类型和对应的数值
return [enumType, numericValue];
}
catch
{
return [null, null];
}
}
}
}

View File

@ -0,0 +1,23 @@
using System;
using System.Globalization;
using System.Windows.Data;
namespace BOB.Converters
{
public class EnumValuesConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is Type type && type.IsEnum)
{
return Enum.GetValues(type);
}
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

View File

@ -0,0 +1,74 @@

using BOB.Models;
using System;
using System.Globalization;
using System.Linq;
using System.Windows.Data;
namespace BOB.Converters
{
public class FilteredParametersConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values.Length < 2 || values[0] == null || values[1] == null)
return null;
Type currentParamType = values[0] as Type;
var allParameters = values[1] as System.Collections.IEnumerable;
if (currentParamType == null || allParameters == null)
return allParameters;
// 过滤出类型匹配的参数
return allParameters.Cast<ParameterModel>()
.Where(p => IsTypeMatch(currentParamType, p.Type))
.ToList();
}
private bool IsTypeMatch(Type currentType, Type candidateType)
{
if (candidateType == null) return false;
// 如果候选参数类型是 object则匹配所有类型
if (candidateType == typeof(object)) return true;
// 如果类型完全相同,则匹配
if (candidateType == currentType) return true;
// 处理数值类型的兼容性
if (IsNumericType(currentType) && IsNumericType(candidateType))
return true;
return false;
}
private bool IsNumericType(Type type)
{
if (type == null) return false;
switch (Type.GetTypeCode(type))
{
case TypeCode.Byte:
case TypeCode.SByte:
case TypeCode.UInt16:
case TypeCode.UInt32:
case TypeCode.UInt64:
case TypeCode.Int16:
case TypeCode.Int32:
case TypeCode.Int64:
case TypeCode.Decimal:
case TypeCode.Double:
case TypeCode.Single:
return true;
default:
return false;
}
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

View File

@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Data;
namespace BOB.Converters
{
public class IsEnumTypeConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is Type type)
{
// 检查是否为枚举类型
bool isEnum = type.IsEnum;
// 根据参数决定返回值类型
if (parameter is string strParam && strParam == "Collapse")
{
return isEnum ? Visibility.Collapsed : Visibility.Visible;
}
return isEnum ? Visibility.Visible : Visibility.Collapsed;
}
return Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

View File

@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;
using static BOB.Models.ParameterModel;
namespace BOB.Converters
{
public class ParameterCategoryToStringConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is ParameterCategory category)
{
switch (category)
{
case ParameterCategory.Input:
return "输入";
case ParameterCategory.Output:
return "输出";
case ParameterCategory.Temp:
return "缓存";
default:
return "未知";
}
}
return "未知";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

View File

@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Data;
using static BOB.Models.ParameterModel;
namespace BOB.Converters
{
public class ParameterCategoryToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is ParameterCategory category)
{
if (parameter?.ToString() == "Item")
{
if (category == ParameterCategory.Temp) { return Visibility.Collapsed; }
else { return Visibility.Visible; }
}
bool boolValue = category == ParameterCategory.Input;
if (parameter?.ToString() == "Inverse")
{
boolValue = !boolValue;
}
return boolValue ? Visibility.Visible : Visibility.Collapsed;
}
return Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

View File

@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Data;
namespace BOB.Converters
{
public class ParameterTypeToBoolConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if(value is Type type)
{
if(type == typeof(CancellationToken))
{
return false;
}
}
return true;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

View File

@ -0,0 +1,38 @@
using ControlzEx.Standard;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;
namespace BOB.Converters
{
public class ParameterValueToStringConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is IEnumerable enumerable && !(value is string))
{
var elements = enumerable.Cast<object>().Select(item => item?.ToString() ?? "null");
return $"[{string.Join(", ", elements)}]";
}
else if(value != null)
{
return value.ToString()!;
}
return "";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value != null)
{
return value.ToString()!;
}
return "";
}
}
}

View File

@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Data;
namespace BOB.Converters
{
public class StringToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if(value is string str)
{
if (string.IsNullOrEmpty(str))
{
return Visibility.Collapsed;
}
else
{
return Visibility.Visible;
}
}
return Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

View File

@ -12,7 +12,10 @@ namespace BOB
public ProgramModel Program = new();
public bool IsAdmin=true;
public String UserName="hsc";
public String Title = "主程序";
public string CurrentFilePath;
public StepModel SelectedStep;
public ParameterModel SelectedParameter;
public DeviceModel SelectedDevice;
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BOB.Models
{
public class DeviceConnectSettingModel
{
public string Name { get; set; } = "";
public string Value { get; set; } = "";
}
}

View File

@ -0,0 +1,192 @@
using BOB.Models;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using static BOB.Models.ParameterModel;
namespace BOB.ViewModels.Dialogs
{
public class DeviceSettingViewModel : BindableBase, IDialogAware
{
#region
private string _title = "设备设置界面";
public string Title
{
get => _title;
set => SetProperty(ref _title, value);
}
private ObservableCollection<string> _types = ["串口", "Tcp", "ModbusRtu", "ModbusTcp", "CAN", "Udp"];
public ObservableCollection<string> Types
{
get => _types;
set => SetProperty(ref _types, value);
}
private string _Mode;
public string Mode
{
get => _Mode;
set => SetProperty(ref _Mode, value);
}
private bool _IsAdd;
public bool IsAdd
{
get => _IsAdd;
set => SetProperty(ref _IsAdd, value);
}
private ProgramModel _program;
public ProgramModel Program
{
get => _program;
set => SetProperty(ref _program, value);
}
private DeviceModel _Device;
public DeviceModel Device
{
get => _Device;
set => SetProperty(ref _Device, value);
}
private ObservableCollection<DeviceConnectSettingModel> _DeviceConnectSettings=new();
public ObservableCollection<DeviceConnectSettingModel> DeviceConnectSettings
{
get => _DeviceConnectSettings;
set => SetProperty(ref _DeviceConnectSettings, value);
}
#endregion
public DialogCloseListener RequestClose { get; set; }
private GlobalVariables _globalVariables;
public ICommand CancelCommand { get; set; }
public ICommand SaveCommand { get; set; }
public ICommand SelectionChangedCommand { get; set; }
public DeviceSettingViewModel(GlobalVariables globalVariables)
{
_globalVariables = globalVariables;
CancelCommand = new DelegateCommand(Cancel);
SaveCommand = new DelegateCommand(Save);
SelectionChangedCommand = new DelegateCommand(SelectionChanged);
}
private void SelectionChanged()
{
if (Device == null) return;
DeviceConnectSettings.Clear();
switch (Device!.Type)
{
case "Tcp":
case "ModbusTcp":
DeviceConnectSettings.Add(new()
{
Name = "IP地址",
Value = "127.0.0.1"
});
DeviceConnectSettings.Add(new()
{
Name = "端口号",
Value = "502"
});
break;
case "串口":
case "ModbusRtu":
DeviceConnectSettings.Add(new()
{
Name = "COM口",
Value = "COM1"
});
DeviceConnectSettings.Add(new()
{
Name = "波特率",
Value = "9600"
});
DeviceConnectSettings.Add(new()
{
Name = "数据位",
Value = "8"
});
DeviceConnectSettings.Add(new()
{
Name = "停止位",
Value = "1"
});
DeviceConnectSettings.Add(new()
{
Name = "奇偶",
Value = "无"
});
break;
case "Udp":
DeviceConnectSettings.Add(new()
{
Name = "远程IP地址",
Value = "127.0.0.1"
});
DeviceConnectSettings.Add(new()
{
Name = "远程端口号",
Value = "8080"
});
DeviceConnectSettings.Add(new()
{
Name = "本地端口号",
Value = "0"
});
break;
}
DeviceConnectSettings.Add(new()
{
Name = "读超时",
Value = "3000"
});
DeviceConnectSettings.Add(new()
{
Name = "写超时",
Value = "3000"
});
}
private void Save()
{
}
private void Cancel()
{
RequestClose.Invoke();
}
#region Prism Dialog
public bool CanCloseDialog()
{
return true;
}
public void OnDialogClosed()
{
}
public void OnDialogOpened(IDialogParameters parameters)
{
Program = _globalVariables.Program;
Mode = parameters.GetValue<string>("Mode");
if(Mode == "ADD")
{
Device = new();
IsAdd = true;
Device.Type = "TCP";
SelectionChanged();
}
else
{
Device = _globalVariables.SelectedDevice;
IsAdd = false;
}
}
#endregion
}
}

View File

@ -0,0 +1,108 @@
using BOB.Models;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using static BOB.Models.ParameterModel;
namespace BOB.ViewModels.Dialogs
{
public class ParameterSettingViewModel : BindableBase, IDialogAware
{
#region
private string _title = "参数设置界面";
public string Title
{
get => _title;
set => SetProperty(ref _title, value);
}
private Array _EnumValues;
public Array EnumValues
{
get => _EnumValues;
set => SetProperty(ref _EnumValues, value);
}
private ObservableCollection<Type> _types =
[
typeof(string), typeof(bool),
typeof(short), typeof(int), typeof(long), typeof(float), typeof(double),
typeof(byte[]), typeof(short[]), typeof(ushort[]), typeof(int[]), typeof(long[]), typeof(float[]), typeof(double[]),
typeof(object)
];
public ObservableCollection<Type> Types
{
get => _types;
set => SetProperty(ref _types, value);
}
private ObservableCollection<string> _categories = new ObservableCollection<string>(
Enum.GetNames(typeof(ParameterCategory))
);
public ObservableCollection<string> Categories
{
get => _categories;
set => SetProperty(ref _categories, value);
}
private string _Mode;
public string Mode
{
get => _Mode;
set => SetProperty(ref _Mode, value);
}
private ProgramModel _program;
public ProgramModel Program
{
get => _program;
set => SetProperty(ref _program, value);
}
private ParameterModel _Parameter;
public ParameterModel Parameter
{
get => _Parameter;
set => SetProperty(ref _Parameter, value);
}
#endregion
public DialogCloseListener RequestClose{get;set;}
private GlobalVariables _globalVariables;
public ICommand CancelCommand { get; set; }
public ICommand SaveCommand { get; set; }
public ParameterSettingViewModel(GlobalVariables globalVariables)
{
_globalVariables = globalVariables;
CancelCommand = new DelegateCommand(Cancel);
SaveCommand = new DelegateCommand(Save);
}
private void Save()
{
}
private void Cancel()
{
RequestClose.Invoke();
}
#region Prism Dialog
public bool CanCloseDialog()
{
return true;
}
public void OnDialogClosed()
{
}
public void OnDialogOpened(IDialogParameters parameters)
{
Program=_globalVariables.Program;
Parameter = _globalVariables.SelectedParameter;
Mode = parameters.GetValue<string>("Mode");
}
#endregion
}
}

View File

@ -1,16 +1,129 @@
using System;
using BOB.Models;
using MaterialDesignThemes.Wpf;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using System.Xml;
namespace BOB.ViewModels
{
public class ParametersManagerViewModel
public class ParametersManagerViewModel:BindableBase,IDialogAware
{
public ParametersManagerViewModel()
#region
private ProgramModel _program;
public ProgramModel Program
{
get => _program;
set => SetProperty(ref _program, value);
}
private ParameterModel _SelectedParameter;
public ParameterModel SelectedParameter
{
get => _SelectedParameter;
set => SetProperty(ref _SelectedParameter, value);
}
private DeviceModel _SelectedDevice;
public DeviceModel SelectedDevice
{
get => _SelectedDevice;
set => SetProperty(ref _SelectedDevice, value);
}
#endregion
public DialogCloseListener RequestClose { get; set; }
GlobalVariables _GlobalVariables { get; set; }
IDialogService _dialogService { get; set; }
public ICommand ParameterAddCommand { get; set; }
public ICommand ParameterEditCommand { get; set; }
public ICommand ParameterDeleteCommand { get; set; }
public ICommand DeviceAddCommand { get; set; }
public ICommand DeviceEditCommand { get; set; }
public ICommand DeviceDeleteCommand { get; set; }
public ParametersManagerViewModel(GlobalVariables GlobalVariables,IDialogService dialogService)
{
_GlobalVariables = GlobalVariables;
_dialogService= dialogService;
Program = _GlobalVariables.Program;
ParameterAddCommand = new DelegateCommand(ParameterAdd);
ParameterEditCommand = new DelegateCommand(ParameterEdit);
ParameterDeleteCommand = new DelegateCommand(ParameterDelete);
DeviceAddCommand = new DelegateCommand(DeviceAdd);
DeviceEditCommand = new DelegateCommand(DeviceEdit);
DeviceDeleteCommand = new DelegateCommand(DeviceDelete);
}
#region
private void DeviceDelete()
{
}
private void DeviceEdit()
{
var param = new DialogParameters
{
{ "Mode", _GlobalVariables.SelectedDevice==null?"ADD":"Edit" }
};
_dialogService.ShowDialog("DeviceSetting", param);
}
private void DeviceAdd()
{
var param = new DialogParameters
{
{ "Mode", "ADD" }
};
_dialogService.ShowDialog("DeviceSetting", param);
}
private void ParameterDelete()
{
}
private void ParameterEdit()
{
var param = new DialogParameters
{
{ "Mode", _GlobalVariables.SelectedParameter==null?"ADD":"Edit" }
};
_dialogService.ShowDialog("ParameterSetting", param);
}
private void ParameterAdd()
{
var param = new DialogParameters
{
{ "Mode", "ADD" }
};
_dialogService.ShowDialog("ParameterSetting", param);
}
#endregion
#region Prism Dialog
public bool CanCloseDialog()
{
return true;
}
public void OnDialogClosed()
{
}
public void OnDialogOpened(IDialogParameters parameters)
{
}
#endregion
}
}

View File

@ -1,5 +1,6 @@
using BOB.Views;
using Common.PubEvents;
using Logger;
using MaterialDesignThemes.Wpf;
using System;
using System.Collections.Generic;
@ -7,6 +8,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Input;
namespace BOB.ViewModels
@ -28,16 +30,46 @@ namespace BOB.ViewModels
public ICommand MinimizeCommand { get; set; }
public ICommand MaximizeCommand { get; set; }
public ICommand CloseCommand { get; set; }
public ICommand RunningCommand { get; set; }
public ICommand RunSingleCommand { get; set; }
public ICommand ResotrationCommand { get; set; }
public ICommand StopCommand { get; set; }
#endregion
private IEventAggregator _eventAggregator;
public ShellViewModel(IEventAggregator eventAggregator, IContainerProvider containerProvider)
private GlobalVariables _globalVariables;
public ShellViewModel(IEventAggregator eventAggregator, IContainerProvider containerProvider,GlobalVariables globalVariables)
{
_eventAggregator= eventAggregator;
_globalVariables= globalVariables;
LeftDrawerOpenCommand = new DelegateCommand(LeftDrawerOpen);
MinimizeCommand = new DelegateCommand<Window>(MinimizeWindow);
MaximizeCommand = new DelegateCommand<Window>(MaximizeWindow);
CloseCommand = new DelegateCommand<Window>(CloseWindow);
RunningCommand = new DelegateCommand<Window>(Running);
RunSingleCommand = new DelegateCommand<Window>(RunSingle);
ResotrationCommand = new DelegateCommand<Window>(Resotration);
StopCommand = new DelegateCommand<Window>(Stop);
}
private void Stop(Window window)
{
LoggerHelper.InfoWithNotify(_globalVariables.UserName+"执行停止命令");
}
private void Resotration(Window window)
{
LoggerHelper.InfoWithNotify(_globalVariables.UserName + "执行复位命令");
}
private void RunSingle(Window window)
{
LoggerHelper.InfoWithNotify(_globalVariables.UserName + "执行单步执行命令");
}
private void Running(Window window)
{
LoggerHelper.InfoWithNotify(_globalVariables.UserName + "执行运行命令");
}
private void LeftDrawerOpen()

View File

@ -1,16 +1,58 @@
using System;
using BOB.Models;
using Common.PubEvent;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
namespace BOB.ViewModels
{
public class SingleStepEditViewModel
public class SingleStepEditViewModel:BindableBase
{
public SingleStepEditViewModel()
#region
private StepModel _SelectedStep;
public StepModel SelectedStep
{
get => _SelectedStep;
set => SetProperty(ref _SelectedStep, value);
}
#endregion
private GlobalVariables _globalVariables;
private IEventAggregator _eventAggregator;
public ICommand CancelEditCommand { get; set; }
public ICommand SaveStepCommand { get; set; }
public SingleStepEditViewModel(GlobalVariables globalVariables,IEventAggregator eventAggregator)
{
_globalVariables= globalVariables;
_eventAggregator= eventAggregator;
_eventAggregator.GetEvent<EditSetpEvent>().Subscribe(EditSingleSetp);
CancelEditCommand = new DelegateCommand(CancelEdit);
SaveStepCommand = new DelegateCommand(SaveStep);
_eventAggregator.GetEvent<DeletedStepEvent>().Subscribe(DisposeSelectedStep);
}
private void DisposeSelectedStep(Guid id)
{
if(id== SelectedStep.ID)
SelectedStep = null;
}
private void CancelEdit()
{
}
private void SaveStep()
{
}
private void EditSingleSetp()
{
SelectedStep = new StepModel(_globalVariables.SelectedStep);
}
}
}

View File

@ -16,43 +16,29 @@ namespace BOB.ViewModels
public class StepsManagerViewModel:BindableBase
{
#region
private string _Title;
public string Title
{
get => _Title;
private set
{
SetProperty(ref _Title, value);
get => _globalVariables.Title;
set => SetProperty(ref _globalVariables.Title, value);
}
}
private StepModel _SelectedStep;
public StepModel SelectedStep
{
get => _SelectedStep;
set
{
if (SetProperty(ref _SelectedStep, value))
{
GlobalVariables.SelectedStep = value;
get => _globalVariables.SelectedStep;
set => SetProperty(ref _globalVariables.SelectedStep, value);
}
}
}
private ProgramModel _program = new();
public ProgramModel Program
{
get => _program;
set => SetProperty(ref _program, value);
get => _globalVariables.Program;
set => SetProperty(ref _globalVariables.Program, value);
}
private bool _IsAdmin = new();
public bool IsAdmin
{
get => _IsAdmin;
set => SetProperty(ref _IsAdmin, value);
get => _globalVariables.IsAdmin;
set => SetProperty(ref _globalVariables.IsAdmin, value);
}
GlobalVariables GlobalVariables { get; set; }
GlobalVariables _globalVariables { get; set; }
private List<StepModel> tmpCopyList = new List<StepModel>();
private IEventAggregator eventAggregator;
private IEventAggregator _eventAggregator;
#endregion
public ICommand EditStepCommand { get;set; }
@ -61,22 +47,21 @@ namespace BOB.ViewModels
public ICommand DeleteStepCommand { get;set; }
public StepsManagerViewModel(GlobalVariables _GlobalVariables,IEventAggregator eventAggregator)
{
eventAggregator = eventAggregator;
GlobalVariables = _GlobalVariables;
Program = GlobalVariables.Program;
IsAdmin = GlobalVariables.IsAdmin;
_eventAggregator = eventAggregator;
_globalVariables = _GlobalVariables;
EditStepCommand = new DelegateCommand(EditStep);
CopyStepCommand = new DelegateCommand(CopyStep);
PasteStepCommand = new DelegateCommand(PasteStep);
DeleteStepCommand = new DelegateCommand(DeleteStep);
Program.StepCollection.CollectionChanged += StepCollection_CollectionChanged;
}
#region
private void EditStep()
{
if (IsAdmin && SelectedStep != null)
if (IsAdmin && SelectedStep != null&& _globalVariables.SelectedStep!=null)
{
var stepToEdit = SelectedStep;
_eventAggregator.GetEvent<EditSetpEvent>().Publish() ;
}
}
private void CopyStep()
@ -104,10 +89,13 @@ namespace BOB.ViewModels
if (IsAdmin && SelectedStep != null)
{
var tmpList = new List<StepModel> { SelectedStep };
_eventAggregator.GetEvent<DeletedStepEvent>().Publish(SelectedStep.ID);
foreach (var item in tmpList)
{
Program.StepCollection.Remove(item);
}
_globalVariables.SelectedStep = null;
}
}
#endregion

View File

@ -0,0 +1,124 @@
<UserControl x:Class="BOB.Views.Dialogs.DeviceSetting"
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:converters="clr-namespace:BOB.Converters"
xmlns:prism="http://prismlibrary.com/"
xmlns:behavior="clr-namespace:Common.Behaviors;assembly=Common"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
prism:ViewModelLocator.AutoWireViewModel="True"
mc:Ignorable="d"
Height="290"
Width="450">
<prism:Dialog.WindowStyle>
<Style BasedOn="{StaticResource DialogUserManageStyle}"
TargetType="Window" />
</prism:Dialog.WindowStyle>
<UserControl.Resources>
<converters:DeviceNameConverter x:Key="DeviceNameConverter" />
<converters:StringToVisibilityConverter x:Key="StringToVisibilityConverter" />
</UserControl.Resources>
<Grid>
<GroupBox Header="{Binding Title}"
Padding="10,15,10,0"
behavior:WindowDragBehavior.EnableWindowDrag="True">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<ScrollViewer>
<StackPanel>
<StackPanel Height="30"
Visibility="{Binding Device.ErrorMessage, Converter={StaticResource StringToVisibilityConverter}}"
Orientation="Horizontal"
Margin="7,7,0,7">
<TextBlock Text="{Binding Device.ErrorMessage}"
Padding="0,11"
Height="30"
Foreground="Red" />
</StackPanel>
<StackPanel Height="30"
Orientation="Horizontal"
Margin="7">
<Label Content="设备名称"
VerticalAlignment="Bottom"
Width="85" />
<TextBox Text="{Binding Device.Name}"
VerticalAlignment="Bottom"
Width="120" />
</StackPanel>
<StackPanel Height="30"
Orientation="Horizontal"
Margin="7">
<Label Content="通讯协议类型"
VerticalAlignment="Bottom"
Width="85" />
<ComboBox ItemsSource="{Binding Types}"
SelectedItem="{Binding Device.Type,UpdateSourceTrigger=PropertyChanged}"
VerticalAlignment="Bottom"
Width="120"
IsEnabled="{Binding IsAdd}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<prism:InvokeCommandAction Command="{Binding SelectionChangedCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</ComboBox>
</StackPanel>
<StackPanel Height="30"
Orientation="Horizontal"
Margin="7">
<Label Content="设备描述"
Width="85"
VerticalAlignment="Bottom" />
<TextBox Text="{Binding Device.Description}"
VerticalAlignment="Bottom"
Width="120" />
</StackPanel>
<Label Content="连接参数"
Height="30"
Margin="7"
VerticalContentAlignment="Bottom" />
<ItemsControl ItemsSource="{Binding DeviceConnectSettings}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal"
Height="30"
Margin="0,7">
<Label Content="{Binding Name}"
Width="75"
Margin="40,0,4,0"
VerticalContentAlignment="Bottom" />
<TextBox VerticalAlignment="Bottom"
Visibility="{Binding Name, Converter={StaticResource DeviceNameConverter}}"
Text="{Binding Value}"
Width="120" />
<ComboBox VerticalAlignment="Bottom"
Visibility="{Binding Name, Converter={StaticResource DeviceNameConverter}, ConverterParameter=Inverse}"
ItemsSource="{Binding Name, Converter={StaticResource DeviceNameConverter}, ConverterParameter=Items}"
SelectedItem="{Binding Value}"
Width="120" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</ScrollViewer>
<StackPanel Grid.Row="1"
Orientation="Horizontal"
FlowDirection="RightToLeft"
Margin="5,10,5,15">
<Button Content="取消"
Width="70"
Command="{Binding CancelCommand}" />
<Button Content="保存"
Width="70"
Margin="20,0"
Command="{Binding SaveCommand}" />
</StackPanel>
</Grid>
</GroupBox>
</Grid>
</UserControl>

View File

@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace BOB.Views.Dialogs
{
/// <summary>
/// DeviceSetting.xaml 的交互逻辑
/// </summary>
public partial class DeviceSetting : UserControl
{
public DeviceSetting()
{
InitializeComponent();
}
}
}

View File

@ -0,0 +1,129 @@
<UserControl x:Class="BOB.Views.Dialogs.ParameterSetting"
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:converters="clr-namespace:BOB.Converters"
xmlns:local="clr-namespace:BOB.Views.Dialogs"
xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:prism="http://prismlibrary.com/"
xmlns:behavior="clr-namespace:Common.Behaviors;assembly=Common"
prism:ViewModelLocator.AutoWireViewModel="True"
Width="420"
Height="284"
mc:Ignorable="d">
<prism:Dialog.WindowStyle>
<Style BasedOn="{StaticResource DialogUserManageStyle}"
TargetType="Window" />
</prism:Dialog.WindowStyle>
<UserControl.Resources>
<converters:IsEnumTypeConverter x:Key="IsEnumTypeConverter" />
<converters:ParameterValueToStringConverter x:Key="ParameterValueToStringConverter" />
</UserControl.Resources>
<Grid>
<GroupBox Padding="10,15,10,0"
Header="{Binding Title}"
behavior:WindowDragBehavior.EnableWindowDrag="True">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<ScrollViewer>
<StackPanel>
<StackPanel Height="30"
Margin="7"
Orientation="Horizontal">
<Label Width="60"
VerticalAlignment="Bottom"
Content="参数名称*" />
<TextBox Width="120"
VerticalAlignment="Bottom"
Text="{Binding Parameter.Name}" />
</StackPanel>
<StackPanel Height="30"
Margin="7"
Orientation="Horizontal">
<Label Width="60"
VerticalAlignment="Bottom"
Content="参数类型*" />
<ComboBox Width="120"
VerticalAlignment="Bottom"
ItemsSource="{Binding Types}"
SelectedItem="{Binding Parameter.Type}"
/>
</StackPanel>
<StackPanel Height="30"
Margin="7"
Orientation="Horizontal">
<Label Width="60"
VerticalAlignment="Bottom"
Content="参数类别*" />
<ComboBox Width="120"
VerticalAlignment="Bottom"
ItemsSource="{Binding Categories}"
Text="{Binding Parameter.Category}" />
</StackPanel>
<StackPanel Height="30"
Margin="7"
Orientation="Horizontal">
<Label Width="60"
VerticalAlignment="Bottom"
Content="参数下限" />
<TextBox Width="120"
VerticalAlignment="Bottom"
Text="{Binding Parameter.LowerLimit}" />
</StackPanel>
<StackPanel Height="30"
Margin="7"
Orientation="Horizontal">
<Label Width="60"
VerticalAlignment="Bottom"
Content="参数上限" />
<TextBox Width="120"
VerticalAlignment="Bottom"
Text="{Binding Parameter.UpperLimit}" />
</StackPanel>
<StackPanel Height="30"
Margin="7"
Orientation="Horizontal">
<Label Width="60"
VerticalAlignment="Bottom"
Content="参数值" />
<!-- 非枚举类型时显示文本框 -->
<TextBox MinWidth="120"
VerticalAlignment="Bottom"
Text="{Binding Parameter.Value, Converter={StaticResource ParameterValueToStringConverter}}"
Visibility="{Binding Parameter.Type, Converter={StaticResource IsEnumTypeConverter}, ConverterParameter=Collapse}" />
<!-- 枚举类型时显示下拉框 -->
<!--<ComboBox MinWidth="120"
VerticalAlignment="Bottom"
ItemsSource="{Binding EnumValues}"
SelectedItem="{Binding Parameter.Value}"
Visibility="{Binding Parameter.Type, Converter={StaticResource IsEnumTypeConverter}}" />-->
<CheckBox Margin="10,0"
VerticalAlignment="Bottom"
Content="保存数据"
IsChecked="{Binding Parameter.IsSave}" />
</StackPanel>
</StackPanel>
</ScrollViewer>
<StackPanel Grid.Row="1"
Margin="5,10,5,15"
FlowDirection="RightToLeft"
Orientation="Horizontal">
<Button Content="取消"
Width="70"
Command="{Binding CancelCommand}" />
<Button Content="保存"
Width="70"
Margin="20,0"
Command="{Binding SaveCommand}" />
</StackPanel>
</Grid>
</GroupBox>
</Grid>
</UserControl>

View File

@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace BOB.Views.Dialogs
{
/// <summary>
/// ParameterSetting.xaml 的交互逻辑
/// </summary>
public partial class ParameterSetting : UserControl
{
public ParameterSetting()
{
InitializeComponent();
}
private void ComboBox_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (sender is ComboBox comboBox && !comboBox.IsDropDownOpen)
{
comboBox.IsDropDownOpen = true;
e.Handled = true;
}
}
}
}

View File

@ -53,12 +53,11 @@
<MenuItem Header="新增"
Command="{Binding ParameterAddCommand}" />
<MenuItem Header="编辑"
Command="{Binding ParameterEditCommand}"
IsEnabled="{Binding SelectedParameter}" />
Command="{Binding ParameterEditCommand}" />
<MenuItem Header="删除"
Foreground="Red"
Command="{Binding ParameterDeleteCommand}"
IsEnabled="{Binding SelectedParameter}" />
Command="{Binding ParameterDeleteCommand}"/>
</ContextMenu>
</DataGrid.ContextMenu>
@ -119,11 +118,11 @@
Command="{Binding DeviceAddCommand}" />
<MenuItem Header="编辑"
Command="{Binding DeviceEditCommand}"
IsEnabled="{Binding SelectedDevice}" />
/>
<MenuItem Header="删除"
Foreground="Red"
Command="{Binding DeviceDeleteCommand}"
IsEnabled="{Binding SelectedDevice}" />
/>
</ContextMenu>
</DataGrid.ContextMenu>

View File

@ -67,7 +67,7 @@
Foreground="White"
VerticalAlignment="Center">
<!-- 文件菜单 -->
<MenuItem FontSize="13"
<MenuItem FontSize="14"
Height="50"
Header="菜单"
Foreground="White"
@ -78,7 +78,7 @@
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="文件"
FontSize="13"
FontSize="14"
Height="50"
Foreground="White">
<MenuItem.Icon>
@ -99,7 +99,7 @@
<!-- 工具菜单 -->
<MenuItem Header="工具"
FontSize="13"
FontSize="14"
Height="50"
Foreground="White">
<MenuItem.Icon>
@ -132,36 +132,40 @@
</MenuItem>
<!-- 程序运行控制 -->
<MenuItem FontSize="13"
<MenuItem FontSize="14"
Height="50"
Header="运行"
Command="{Binding RunningCommand}"
Foreground="White">
<MenuItem.Icon>
<materialDesign:PackIcon Kind="Play"
Foreground="White" />
</MenuItem.Icon>
</MenuItem>
<MenuItem FontSize="13"
<MenuItem FontSize="14"
Height="50"
Header="单步执行"
Command="{Binding RunSingleCommand}"
Foreground="White">
<MenuItem.Icon>
<materialDesign:PackIcon Kind="ArrowRight"
Foreground="White" />
</MenuItem.Icon>
</MenuItem>
<MenuItem FontSize="13"
<MenuItem FontSize="14"
Height="50"
Header="停止"
Command="{Binding StopCommand}"
Foreground="White">
<MenuItem.Icon>
<materialDesign:PackIcon Kind="Stop"
Foreground="White" />
</MenuItem.Icon>
</MenuItem>
<MenuItem FontSize="13"
<MenuItem FontSize="14"
Height="50"
Header="复位"
Command="{Binding ResotrationCommand}"
Foreground="White">
<MenuItem.Icon>
<materialDesign:PackIcon Kind="Restart"
@ -172,7 +176,7 @@
<Menu Grid.Column="2"
Margin="0 0 20 0">
<MenuItem FontSize="13"
<MenuItem FontSize="14"
Height="50"
Header="最小化"
Foreground="White"
@ -184,7 +188,7 @@
</MenuItem.Icon>
</MenuItem>
<MenuItem FontSize="13"
<MenuItem FontSize="14"
Height="50"
Header="最大化"
Foreground="White"
@ -196,7 +200,7 @@
</MenuItem.Icon>
</MenuItem>
<MenuItem FontSize="13"
<MenuItem FontSize="14"
Height="50"
Header="关闭"
Foreground="White"
@ -216,13 +220,20 @@
</materialDesign:ColorZone>
<materialDesign:DialogHost Grid.Row="1" x:Name="DialogHost"
<materialDesign:DialogHost Grid.Row="1"
x:Name="DialogHost"
DialogBackground="Transparent"
Background="Transparent"
Identifier="Root">
<!-- 主内容区 -->
<Grid >
<ContentControl prism:RegionManager.RegionName="ShellViewManager" />
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="454*" />
<ColumnDefinition Width="91*" />
<ColumnDefinition Width="1375*" />
</Grid.ColumnDefinitions>
<ContentControl prism:RegionManager.RegionName="ShellViewManager"
Grid.ColumnSpan="3" />
</Grid>
</materialDesign:DialogHost>
</Grid>

View File

@ -5,12 +5,23 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:local="clr-namespace:BOB.Views"
xmlns:converters="clr-namespace:BOB.Converters"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
d:DesignHeight="450"
d:DesignWidth="800"
mc:Ignorable="d">
<UserControl.Resources>
<converters:ParameterCategoryToVisibilityConverter x:Key="ParameterCategoryToVisibilityConverter" />
<converters:ParameterTypeToBoolConverter x:Key="ParameterTypeToBoolConverter" />
<converters:ParameterCategoryToStringConverter x:Key="ParameterCategoryToStringConverter" />
<converters:IsEnumTypeConverter x:Key="IsEnumTypeConverter" />
<converters:EnumValuesConverter x:Key="EnumValuesConverter" />
<converters:EnumValueConverter x:Key="EnumValueConverter" />
<converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
<converters:FilteredParametersConverter x:Key="FilteredParametersConverter" />
</UserControl.Resources>
<Grid>
<GroupBox Header="单步编辑">
<Grid>
@ -69,50 +80,262 @@
<!-- 参数编辑区 -->
<Grid Grid.Row="4">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="auto" />
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal"
Margin="7,0">
<Label Content="参数" />
<StackPanel Height="30"
Orientation="Horizontal">
<Label Margin="7,0"
VerticalAlignment="Bottom"
Content="参数" />
</StackPanel>
<ScrollViewer Grid.Row="1"
Margin="40,0,0,0"
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto">
<StackPanel>
<!-- 主参数 -->
<ItemsControl ItemsSource="{Binding SelectedStep.Method.Parameters}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="50" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0"
Margin="7,7,0,7"
Orientation="Horizontal">
<TextBlock VerticalAlignment="Bottom"
Text="{Binding Name}" />
<TextBlock VerticalAlignment="Bottom"
Text="(" />
<TextBlock VerticalAlignment="Bottom"
Text="{Binding Type.Name}" />
<TextBlock VerticalAlignment="Bottom"
Text=")" />
</StackPanel>
<StackPanel Grid.Column="1"
Margin="7"
Orientation="Horizontal">
<TextBlock Margin="5,0"
VerticalAlignment="Bottom"
Text="{Binding Category, Converter={StaticResource ParameterCategoryToStringConverter}}" />
</StackPanel>
<StackPanel Grid.Column="2"
Margin="7"
Orientation="Horizontal">
<!-- 输入参数编辑 -->
<StackPanel Height="30"
IsEnabled="{Binding Type, Converter={StaticResource ParameterTypeToBoolConverter}}"
Orientation="Horizontal"
Visibility="{Binding Category, Converter={StaticResource ParameterCategoryToVisibilityConverter}}">
<CheckBox VerticalAlignment="Bottom" Margin="0 15 0 0"
IsChecked="{Binding IsUseVar}" />
<Grid>
<!-- 常量输入区域 -->
<Grid Visibility="{Binding IsUseVar, Converter={StaticResource BooleanToVisibilityConverter}, ConverterParameter=Inverse}">
<!-- 非枚举类型 -->
<TextBox Height="22"
MinWidth="120"
VerticalAlignment="Bottom"
Text="{Binding Value, UpdateSourceTrigger=PropertyChanged}"
Visibility="{Binding Type, Converter={StaticResource IsEnumTypeConverter}, ConverterParameter=Collapse}" />
<!-- 枚举类型 -->
<ComboBox Height="22"
MinWidth="120"
VerticalAlignment="Bottom"
ItemsSource="{Binding Type, Converter={StaticResource EnumValuesConverter}}"
Visibility="{Binding Type, Converter={StaticResource IsEnumTypeConverter}}">
<ComboBox.SelectedItem>
<MultiBinding Converter="{StaticResource EnumValueConverter}">
<Binding Path="Type" />
<Binding Path="Value" />
</MultiBinding>
</ComboBox.SelectedItem>
</ComboBox>
</Grid>
<!-- 变量选择框 -->
<ComboBox Height="22"
MinWidth="120"
VerticalAlignment="Bottom"
SelectedValue="{Binding VariableName}"
SelectedValuePath="Name"
Visibility="{Binding IsUseVar, Converter={StaticResource BooleanToVisibilityConverter}}">
<ComboBox.ItemsSource>
<MultiBinding Converter="{StaticResource FilteredParametersConverter}">
<Binding Path="Type" />
<Binding Path="DataContext.Program.Parameters"
RelativeSource="{RelativeSource AncestorType=Window}" />
</MultiBinding>
</ComboBox.ItemsSource>
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" />
<TextBlock Text="(" />
<TextBlock Text="{Binding Type.Name, TargetNullValue=Unknown}" />
<TextBlock Text=")" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</Grid>
</StackPanel>
<!-- 输出参数编辑 -->
<StackPanel Height="30"
Orientation="Horizontal"
Visibility="{Binding Category, Converter={StaticResource ParameterCategoryToVisibilityConverter}, ConverterParameter=Inverse}">
<CheckBox VerticalAlignment="Bottom"
IsChecked="{Binding IsUseVar}"
Margin="0 15 0 0"
/>
<ComboBox Width="120"
Margin="0,0,0,0"
VerticalAlignment="Bottom"
SelectedValue="{Binding VariableName}"
SelectedValuePath="Name"
Visibility="{Binding Category, Converter={StaticResource ParameterCategoryToVisibilityConverter}, ConverterParameter=Inverse}">
<ComboBox.ItemsSource>
<MultiBinding Converter="{StaticResource FilteredParametersConverter}">
<Binding Path="Type" />
<Binding Path="DataContext.Program.Parameters"
RelativeSource="{RelativeSource AncestorType=Window}" />
</MultiBinding>
</ComboBox.ItemsSource>
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" />
<TextBlock Text="(" />
<TextBlock Text="{Binding Type.Name, TargetNullValue=Unknown}" />
<TextBlock Text=")" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</StackPanel>
</StackPanel>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<!-- 子程序参数 -->
<ItemsControl ItemsSource="{Binding SelectedStep.SubProgram.Parameters}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Visibility="{Binding Category, Converter={StaticResource ParameterCategoryToVisibilityConverter}, ConverterParameter=Item}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="50" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0"
Margin="7,7,0,7"
Orientation="Horizontal">
<TextBlock VerticalAlignment="Bottom"
Text="{Binding Name}" />
<TextBlock VerticalAlignment="Bottom"
Text="(" />
<TextBlock VerticalAlignment="Bottom"
Text="{Binding Type.Name}" />
<TextBlock VerticalAlignment="Bottom"
Text=")" />
</StackPanel>
<StackPanel Grid.Column="1"
Margin="7"
Orientation="Horizontal">
<TextBlock Margin="5,0"
VerticalAlignment="Bottom"
Text="{Binding Category, Converter={StaticResource ParameterCategoryToStringConverter}}" />
</StackPanel>
<StackPanel Grid.Column="2"
Margin="7"
Orientation="Horizontal">
<!-- 输入参数编辑 -->
<StackPanel Height="30"
Orientation="Horizontal"
Visibility="{Binding Category, Converter={StaticResource ParameterCategoryToVisibilityConverter}}">
<CheckBox VerticalAlignment="Bottom"
IsChecked="{Binding IsUseVar}" />
<Grid>
<!-- 常量输入区域 -->
<Grid Visibility="{Binding IsUseVar, Converter={StaticResource BooleanToVisibilityConverter}, ConverterParameter=Inverse}">
<!-- 非枚举类型 -->
<TextBox Height="22"
MinWidth="120"
VerticalAlignment="Bottom"
Text="{Binding Value, UpdateSourceTrigger=PropertyChanged}"
Visibility="{Binding Type, Converter={StaticResource IsEnumTypeConverter}, ConverterParameter=Collapse}" />
<!-- 枚举类型 -->
<ComboBox Height="22"
MinWidth="120"
VerticalAlignment="Bottom"
ItemsSource="{Binding Type, Converter={StaticResource EnumValuesConverter}}"
SelectedItem="{Binding Value}"
Visibility="{Binding Type, Converter={StaticResource IsEnumTypeConverter}}" />
</Grid>
<!-- 变量选择框 -->
<ComboBox Height="22"
MinWidth="120"
VerticalAlignment="Bottom"
ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=DataContext.Program.Parameters}"
SelectedValue="{Binding VariableName}"
SelectedValuePath="Name"
Visibility="{Binding IsUseVar, Converter={StaticResource BooleanToVisibilityConverter}}">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" />
<TextBlock Text="(" />
<TextBlock Text="{Binding Type.Name, TargetNullValue=Unknown}" />
<TextBlock Text=")" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</Grid>
</StackPanel>
<!-- 输出参数编辑 -->
<CheckBox VerticalAlignment="Bottom"
IsChecked="{Binding IsUseVar}"
Visibility="{Binding Category, Converter={StaticResource ParameterCategoryToVisibilityConverter}, ConverterParameter=Inverse}" />
<ComboBox Width="120"
Margin="0,0,0,0"
VerticalAlignment="Bottom"
ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=DataContext.Program.Parameters}"
SelectedValue="{Binding VariableName}"
SelectedValuePath="Name"
Visibility="{Binding Category, Converter={StaticResource ParameterCategoryToVisibilityConverter}, ConverterParameter=Inverse}">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" />
<TextBlock Text="(" />
<TextBlock Text="{Binding Type.Name, TargetNullValue=Unknown}" />
<TextBlock Text=")" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</StackPanel>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</ScrollViewer>
</Grid>
<!-- 按钮 -->
<StackPanel Grid.Row="5"
Orientation="Horizontal"

View File

@ -0,0 +1,41 @@
using System.Windows;
using System.Windows.Input;
namespace Common.Behaviors
{
public static class WindowDragBehavior
{
public static readonly DependencyProperty EnableWindowDragProperty =
DependencyProperty.RegisterAttached(
"EnableWindowDrag",
typeof(bool),
typeof(WindowDragBehavior),
new PropertyMetadata(false, OnEnableWindowDragChanged));
public static bool GetEnableWindowDrag(DependencyObject obj) =>
(bool)obj.GetValue(EnableWindowDragProperty);
public static void SetEnableWindowDrag(DependencyObject obj, bool value) =>
obj.SetValue(EnableWindowDragProperty, value);
private static void OnEnableWindowDragChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is FrameworkElement element)
{
if ((bool)e.NewValue)
element.MouseLeftButtonDown += Element_MouseLeftButtonDown;
else
element.MouseLeftButtonDown -= Element_MouseLeftButtonDown;
}
}
private static void Element_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (sender is FrameworkElement element)
{
var window = Window.GetWindow(element);
window?.DragMove();
}
}
}
}

View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Common.PubEvent
{
public class DeletedStepEvent : PubSubEvent<Guid>
{
}
}

View File

@ -6,7 +6,7 @@ using System.Threading.Tasks;
namespace Common.PubEvent
{
public class AfterDragEvent:PubSubEvent
public class EditSetpEvent : PubSubEvent
{
}
}