终端一体化运控平台
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

310 lines
12 KiB

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