终端一体化运控平台
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 

299 lignes
12 KiB

  1. using BPASmartClient.Compiler;
  2. using Newtonsoft.Json;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Collections.ObjectModel;
  6. using System.ComponentModel;
  7. using System.Text;
  8. using System.Windows;
  9. using System.Windows.Controls;
  10. using System.Windows.Data;
  11. using System.Windows.Markup;
  12. using System.Windows.Threading;
  13. using System.Xml;
  14. namespace BPASmartClient.SCADAControl.CustomerControls
  15. {
  16. /// <summary>
  17. /// TheListBox.xaml 的交互逻辑
  18. /// </summary>
  19. public partial class TheListBox :ListBox, IExecutable, IDisposable
  20. {
  21. public event EventHandler PropertyChange; //声明一个事件
  22. public TheListBox()
  23. {
  24. InitializeComponent();
  25. ResourceDictionary languageResDic = new ResourceDictionary();
  26. languageResDic.Source = new Uri(@"/BPASmartClient.SCADAControl;component/Themes/Generic.xaml",UriKind.RelativeOrAbsolute);
  27. this.Resources.MergedDictionaries.Add(languageResDic);
  28. EditorHelper.Register<BindingExpression, BindingConvertor>();
  29. Width = 100;
  30. Height = 100;
  31. }
  32. #region 属性
  33. [Category("控件数据集合")]
  34. private ObservableCollection<object> ItemsString
  35. {
  36. get { return (ObservableCollection<object>)GetValue(ItemsStringProperty); }
  37. set { SetValue(ItemsStringProperty, value); }
  38. }
  39. private static readonly DependencyProperty ItemsStringProperty =
  40. DependencyProperty.Register("ItemsString", typeof(ObservableCollection<object>), typeof(TheListBox), new PropertyMetadata(new ObservableCollection<object>()));
  41. [Category("子控件模板XML格式")]
  42. public string ChildTemplateXml
  43. {
  44. get { return (string)GetValue(ChildTemplateXmlProperty); }
  45. set { SetValue(ChildTemplateXmlProperty, value); }
  46. }
  47. public static readonly DependencyProperty ChildTemplateXmlProperty =
  48. DependencyProperty.Register("ChildTemplateXml", typeof(string), typeof(TheListBox), new PropertyMetadata(string.Empty,new PropertyChangedCallback(onChildTemplateXmlChanged)));
  49. private static void onChildTemplateXmlChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) => (d as TheListBox)?.XmlRefresh();
  50. public void XmlRefresh()
  51. {
  52. ;
  53. }
  54. [Category("数据绑定-数据来源")]
  55. public DataTypeEnum DataSouceType
  56. {
  57. get { return (DataTypeEnum)GetValue(DataSouceTypeProperty); }
  58. set { SetValue(DataSouceTypeProperty, value); }
  59. }
  60. public static readonly DependencyProperty DataSouceTypeProperty =
  61. DependencyProperty.Register("DataSouceType", typeof(DataTypeEnum), typeof(TheListBox), new PropertyMetadata(DataTypeEnum.API接口));
  62. [Category("数据绑定-数据来源")]
  63. public int TimeCount
  64. {
  65. get { return (int)GetValue(TimeCountProperty); }
  66. set { SetValue(TimeCountProperty, value); }
  67. }
  68. public static readonly DependencyProperty TimeCountProperty =
  69. DependencyProperty.Register("TimeCount", typeof(int), typeof(TheListBox), new PropertyMetadata(500));
  70. [Category("数据绑定-数据来源")]
  71. public string DataSouceInformation
  72. {
  73. get { return (string)GetValue(DataSouceInformationProperty); }
  74. set { SetValue(DataSouceInformationProperty, value); }
  75. }
  76. public static readonly DependencyProperty DataSouceInformationProperty =
  77. DependencyProperty.Register("DataSouceInformation", typeof(string), typeof(TheListBox), new PropertyMetadata("api0"));
  78. [Category("数据绑定")]
  79. public string FDataSouce
  80. {
  81. get { return (string)GetValue(FDataSouceProperty); }
  82. set { SetValue(FDataSouceProperty, value); }
  83. }
  84. public static readonly DependencyProperty FDataSouceProperty =
  85. DependencyProperty.Register("FDataSouce", typeof(string), typeof(TheListBox), new PropertyMetadata(string.Empty, new PropertyChangedCallback(onFDataSouceChanged)));
  86. private static void onFDataSouceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) => (d as TheListBox)?.DataSouceRefresh();
  87. public void DataSouceRefresh()
  88. {
  89. try
  90. {
  91. GenerateData = (string)CSharpConfig.GetInstance().RunCSharp(Code, new object[] { FDataSouce });
  92. if (PropertyChange != null)
  93. {
  94. PropertyChange(this, null);
  95. }
  96. }
  97. catch (Exception ex)
  98. {
  99. }
  100. }
  101. public static string _code = "public string main(string message) \n{ \n //请在此填写你的代码\n\n return message; \n}\n";
  102. [Category("数据绑定")]
  103. public string Code
  104. {
  105. get { return (string)GetValue(CodeProperty); }
  106. set { SetValue(CodeProperty, value); }
  107. }
  108. public static readonly DependencyProperty CodeProperty =
  109. DependencyProperty.Register("Code", typeof(string), typeof(TheListBox), new PropertyMetadata(_code));
  110. [Category("数据绑定")]
  111. public string GenerateData
  112. {
  113. get { return (string)GetValue(GenerateDataProperty); }
  114. set { SetValue(GenerateDataProperty, value); }
  115. }
  116. public static readonly DependencyProperty GenerateDataProperty =
  117. DependencyProperty.Register("GenerateData", typeof(string), typeof(TheListBox), new PropertyMetadata(string.Empty, new PropertyChangedCallback(onGenerateDataChanged)));
  118. private static void onGenerateDataChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) => (d as TheListBox)?.GenerateDataRefresh();
  119. public void GenerateDataRefresh()
  120. {
  121. if (!string.IsNullOrEmpty(GenerateData) && GenerateData.Contains("data"))
  122. {
  123. try
  124. {
  125. Dictionary<string, object> keys = JsonConvert.DeserializeObject<Dictionary<string, object>>(GenerateData);
  126. ItemsString = JsonConvert.DeserializeObject<ObservableCollection<object>>(keys["data"].ToString());
  127. }
  128. catch (Exception ex)
  129. {
  130. }
  131. }
  132. else
  133. {
  134. //this.Items.Clear();
  135. }
  136. }
  137. #endregion
  138. public string ControlType => "控件";
  139. private bool isExecuteState;
  140. public bool IsExecuteState
  141. {
  142. get { return isExecuteState; }
  143. set
  144. {
  145. isExecuteState = value;
  146. if (IsExecuteState)
  147. {
  148. Register();
  149. }
  150. }
  151. }
  152. DispatcherTimer timer = new DispatcherTimer();
  153. /// <summary>
  154. /// 注册需要处理的事件
  155. /// </summary>
  156. public void Register()
  157. {
  158. XmlToFrameworkElement();
  159. if (DataSouceType == DataTypeEnum.API接口)
  160. {
  161. timer.Interval = TimeSpan.FromMilliseconds(TimeCount);
  162. timer.Tick += Timer_Tick; ;
  163. timer.Start();
  164. }
  165. }
  166. /// <summary>
  167. /// 流转Xml
  168. /// </summary>
  169. /// <param name="framework"></param>
  170. public void FrameworkElementToXml(FrameworkElement framework)
  171. {
  172. StringBuilder outstr = new StringBuilder();
  173. try
  174. {
  175. //this code need for right XML fomating
  176. XmlWriterSettings settings = new XmlWriterSettings
  177. {
  178. Indent = true,
  179. OmitXmlDeclaration = true
  180. };
  181. var dsm = new XamlDesignerSerializationManager(XmlWriter.Create(outstr, settings))
  182. {
  183. //this string need for turning on expression saving mode
  184. XamlWriterMode = XamlWriterMode.Expression
  185. };
  186. XamlWriter.Save(framework, dsm);
  187. }
  188. catch (Exception ex) { }
  189. ChildTemplateXml = outstr.ToString();
  190. }
  191. public void XmlToFrameworkElement()
  192. {
  193. var template = (DataTemplate)XamlReader.Parse(@"
  194. <DataTemplate xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
  195. xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"">
  196. " + ChildTemplateXml + @"
  197. </DataTemplate>");
  198. SetValue(ItemTemplateProperty, template);
  199. Binding binding = new Binding();
  200. binding.RelativeSource = new RelativeSource() { Mode = RelativeSourceMode.Self };
  201. binding.Path = new PropertyPath("ItemsString");
  202. SetBinding(ItemsSourceProperty, binding);
  203. }
  204. public void Dispose()
  205. {
  206. timer.Stop();
  207. FDataSouce = "";
  208. GenerateDataRefresh();
  209. }
  210. private void Timer_Tick(object? sender, EventArgs e)
  211. {
  212. if (!string.IsNullOrEmpty(DataSouceInformation))
  213. {
  214. if (DataSouceType == DataTypeEnum.API接口)
  215. {
  216. if (Class_DataBus.GetInstance().Dic_APIData.ContainsKey(DataSouceInformation))
  217. {
  218. FDataSouce = Class_DataBus.GetInstance().Dic_APIData[DataSouceInformation];
  219. }
  220. }
  221. else if (DataSouceType == DataTypeEnum.Redis)
  222. {
  223. if (DataSouceInformation.Contains(".") && DataSouceInformation.Contains("{Binding "))
  224. {
  225. string[] str = DataSouceInformation.Replace("{Binding ", "").Replace("}", "").Split(".");
  226. if (str.Length > 1)
  227. {
  228. if (Class_DataBus.GetInstance().Dic_RedisData.ContainsKey(str[0]))
  229. {
  230. Dictionary<string, object> b = Class_DataBus.GetInstance().Dic_RedisData[str[0]];
  231. if (b != null && b.ContainsKey(str[1]))
  232. FDataSouce = b[str[1]].ToString();
  233. }
  234. }
  235. }
  236. }
  237. else if (DataSouceType == DataTypeEnum.静态数据)
  238. {
  239. FDataSouce = "";
  240. }
  241. }
  242. }
  243. }
  244. internal class BindingConvertor : ExpressionConverter
  245. {
  246. public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
  247. {
  248. if (destinationType == typeof(MarkupExtension))
  249. return true;
  250. else return false;
  251. }
  252. public override object ConvertTo(ITypeDescriptorContext context,
  253. System.Globalization.CultureInfo culture, object value, Type destinationType)
  254. {
  255. if (destinationType == typeof(MarkupExtension))
  256. {
  257. BindingExpression bindingExpression = value as BindingExpression;
  258. if (bindingExpression == null)
  259. throw new Exception();
  260. return bindingExpression.ParentBinding;
  261. }
  262. return base.ConvertTo(context, culture, value, destinationType);
  263. }
  264. }
  265. internal static class EditorHelper
  266. {
  267. public static void Register<T, TC>()
  268. {
  269. Attribute[] attr = new Attribute[1];
  270. TypeConverterAttribute vConv = new TypeConverterAttribute(typeof(TC));
  271. attr[0] = vConv;
  272. TypeDescriptor.AddAttributes(typeof(T), attr);
  273. }
  274. }
  275. }