using HMI.Base; using HMI.Core.Setting; using HMI.Core.Util; using HMI.UI; using HMI.UI.Util; using log4net; using Panuon.WPF.UI; using Plugin.DOControl.Entity; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.IO; using System.Linq; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Media; namespace Plugin.DOControl { /// /// UserControl1.xaml 的交互逻辑 /// public partial class DOControl : PluginControl { /// /// 实例化服务器接口函数 /// private OpcInterface.OpcInterface lTSCADAApi = new OpcInterface.OpcInterface(); private ObservableCollection groups; public ObservableCollection Groups { get => groups; set { Set(ref groups, value); } } private string selectedGroup; public string SelectedGroup { get => selectedGroup; set { Set(ref selectedGroup, value); if (string.IsNullOrEmpty(value)) { selectedControls.Clear(); } else if (GroupMap.ContainsKey(value)) { selectedControls = GroupMap[value]; } RefreshControl(); } } private ObservableCollection datasource; public ObservableCollection Datasource { get => datasource; set { Set(ref datasource, value); } } private Dictionary> GroupMap = new Dictionary>(); private List visiableControls = new List(); private List selectedControls = new List(); private System.Timers.Timer motorMonitorTimer; public DOControl() { DataContext = this; motorMonitorTimer = new System.Timers.Timer(); motorMonitorTimer.Interval = 200; motorMonitorTimer.AutoReset = false; motorMonitorTimer.Elapsed += MotorMonitorTimer_Elapsed; InitializeComponent(); } public override void Active() { motorMonitorTimer.Enabled = true; base.Active(); } public override void DeActive() { motorMonitorTimer.Enabled = false; base.DeActive(); } public override void DoClose(object sender, EventArgs e) { motorMonitorTimer.Enabled = false; base.DoClose(sender, e); } public static string FilePath { get; private set; } public static ILog Logger { get; private set; } public override void SetBaseFolder(string folder) { FilePath = Path.Combine(folder, "DOControlData.data"); base.SetBaseFolder(folder); } public override void SetLogger(ILog logger) { Logger = logger; base.SetLogger(logger); } public override void InitFinish() { base.InitFinish(); } private void LoadData() { try { motorMonitorTimer.Enabled = false; ObservableCollection datas = new ObservableCollection(); if (File.Exists(FilePath)) { datas = XmlHelper.DeserializeFromXml>(FilePath); } Datasource = datas; GroupMap = datas.GroupBy(x => x.Group) .ToDictionary( group => group.Key, group => group.ToList() ); Groups = new ObservableCollection(GroupMap.Keys); if (string.IsNullOrEmpty(SelectedGroup) && Groups.Count > 0) { SelectedGroup = Groups[0]; } else { RefreshControl(); } } catch (Exception ex) { log.Error("Load Data Failed.", ex); ToastHelper.Error(this, ex.Message); } finally { motorMonitorTimer.Enabled = true; } } private void MotorMonitorTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { try { motorMonitorTimer.Enabled = false; for (int i = visiableControls.Count - 1; i >= 0; i--) { var ui = visiableControls[i]; ui.Dispatcher.Invoke(() => { DOControlData data = ui.Tag as DOControlData; if (data == null) return; string value = GetPlcValue(data.Address); switch (data.ControlType) { case ControlType.Button: var color = Application.Current.FindResource("VerBar") as Brush; if (value == data.PressDownValue) { color = Application.Current.FindResource("GreenVerBar") as Brush; } ((Button)ui).Background = color; ((Button)ui).Content = value; break; case ControlType.Int16: case ControlType.Int32: case ControlType.Real: case ControlType.LReal: case ControlType.String: case ControlType.WString: ((Button)ui).Content = value; break; default: break; } }); } } finally { motorMonitorTimer.Enabled = true; } } private void RefreshControl() { try { motorMonitorTimer.Enabled = false; panel0.Children.Clear(); panel1.Children.Clear(); visiableControls.Clear(); int index = 0; foreach (string group in GroupMap.Keys) { int num = index % 2; WrapPanel panel = new WrapPanel { Orientation = Orientation.Horizontal }; GroupBox gb = new GroupBox { Header = group, Content = panel, Margin = new Thickness(0, 0, 0, 10) }; var datas = GroupMap[group]; foreach (var data in datas) { FrameworkElement ui = null; switch (data.ControlType) { case ControlType.Button: case ControlType.ClickButton: ui = CreateButton(data); break; case ControlType.Int16: case ControlType.Int32: case ControlType.Real: case ControlType.LReal: case ControlType.String: case ControlType.WString: ui = CreateNumberInput(data); break; default: break; } if (ui != null) { FormGroup fg = new FormGroup { Header = data.Name, Content = ui, Orientation = Orientation.Vertical, Margin = new Thickness(10, 0, 0, 10) }; panel.Children.Add(fg); visiableControls.Add(ui); } } if (num == 0) { panel0.Children.Add(gb); } else { panel1.Children.Add(gb); } index++; } } catch { } finally { motorMonitorTimer.Enabled = true; } } private Button CreateButton(DOControlData data) { Style btnStyle = Application.Current.FindResource("PrimaryButton") as Style; var btn = new Button { Tag = data, Style = btnStyle, MinWidth = 180, MinHeight = 40 }; if (data.ControlType == ControlType.Button) { btn.Click += ControlButton_Click; } else if (data.ControlType == ControlType.ClickButton) { btn.Content = data.Address; btn.PreviewMouseLeftButtonDown += Btn_MouseLeftButtonDown; btn.PreviewMouseLeftButtonUp += Btn_MouseLeftButtonUp; } return btn; } private void Btn_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e) { Button btn = sender as Button; DOControlData data = btn.Tag as DOControlData; try { var color = Application.Current.FindResource("GreenVerBar") as Brush; btn.Background = color; SetPlcValue(data.Address, data.PressDownValue); } catch (Exception ex) { log.Error("PressDownClick", ex); ToastHelper.Error($"{data.Name}: {ex.Message}"); } } private void Btn_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e) { Button btn = sender as Button; DOControlData data = btn.Tag as DOControlData; try { var color = Application.Current.FindResource("VerBar") as Brush; btn.Background = color; SetPlcValue(data.Address, data.PressUpValue); } catch (Exception ex) { log.Error("PressUpClick", ex); ToastHelper.Error($"{data.Name}: {ex.Message}"); } } private Button CreateNumberInput(DOControlData data) { Style btnStyle = Application.Current.FindResource("PrimaryButton") as Style; var tb = new Button { Tag = data, Style = btnStyle, MinWidth = 180, MinHeight = 40, BorderBrush = Brushes.Black, BorderThickness = new Thickness(1), Background = Brushes.White, Foreground = Brushes.Black }; if (data.ReadOnly) { tb.Background = Brushes.LightGray; return tb; } if (data.ControlType == ControlType.String || data.ControlType == ControlType.WString) { tb.Click += StringInput_Click; } else { tb.Click += NumberInput_Click; } return tb; } /// /// 设置plc值 /// /// 地址 /// 类型 /// 值 private void SetPlcValue(string key, string value) { if (!lTSCADAApi.DoFctWriteSingle(key, value, out string errMsg)) { throw new Exception(errMsg); } } private string GetPlcValue(string key) { if (lTSCADAApi.DoFctReadSingle(key, out string Val, out string errMsg)) { return Val; } else { return null; } } private void ControlButton_Click(object sender, RoutedEventArgs args) { Button btn = sender as Button; DOControlData data = btn.Tag as DOControlData; try { string value = btn.Content?.ToString() == data.PressDownValue ? data.PressUpValue : data.PressDownValue; SetPlcValue(data.Address, value); } catch (Exception ex) { log.Error("ControlButton_Click", ex); ToastHelper.Error($"{data.Name}: {ex.Message}"); } } private void StringInput_Click(object sender, RoutedEventArgs args) { Button tb = sender as Button; DOControlData data = tb.Tag as DOControlData; KeyboardWindow kw = new KeyboardWindow { Title = data.Name, Owner = Window.GetWindow(this) }; if (kw.Open(tb.Content?.ToString()) == true) { SetPlcValue(data.Address, kw.Data?.ToString()); } } private void NumberInput_Click(object sender, RoutedEventArgs args) { Button tb = sender as Button; DOControlData data = tb.Tag as DOControlData; NumberPanel np = new NumberPanel { Title = data.Name, Owner = Window.GetWindow(this) }; if (np.Open(tb.Content?.ToString()) == true) { SetPlcValue(data.Address, np.Data?.ToString()); } } private void UserControl_Loaded(object sender, RoutedEventArgs e) { LoadData(); if (SystemSetting.Instance.PlcEnabled) { if (lTSCADAApi.Connect2("127.0.0.1", 6543, 18888, out string errMsg)) { motorMonitorTimer.Enabled = true; RefreshControl(); } else { MsgBoxHelper2.Error(errMsg); } } Loaded -= UserControl_Loaded; } private void Button_Click(object sender, RoutedEventArgs e) { Button btn = sender as Button; switch (btn.Name) { case "addBtn": OpenDataModal(null); break; case "settingBtn": OpenDataList(); break; case "resetBtn": LoadData(); break; case "exportBtn": break; default: break; } } private void OpenDataModal(DOControlData data) { DataModal modal = new DataModal { Title = data == null ? this.lang("App.Add") : this.lang("App.Edit"), Owner = Window.GetWindow(this) }; if (modal.Open(data ?? new DOControlData(), Datasource) == true) { LoadData(); } } private void OpenDataList() { ControlList list = new ControlList { Owner = Window.GetWindow(this) }; if (list.Open(Datasource) == true) { LoadData(); } } } }