I2CSetControl.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  1. using System;
  2. using System.Collections;
  3. using System.Linq;
  4. using System.Reflection;
  5. using System.Windows.Forms;
  6. using Uestc.Auto6.Dso.Core;
  7. using Uestc.Auto6.Dso.Core.Decode;
  8. using Uestc.Auto6.Dso.ComModel;
  9. using Uni_Trend.MSO7000X.Language;
  10. using Uni_Trend.MSO7000X.Common.Helper;
  11. using Uni_Trend.MSO7000X.UserControls;
  12. namespace Uestc.Auto6.Dso.Protocol.I2C
  13. {
  14. public partial class I2CSetControl : UserControl,IProtocolView
  15. {
  16. #region 属性定义
  17. protected new Boolean DesignMode
  18. {
  19. get
  20. {
  21. Boolean rtnflag = false;
  22. #if DEBUG
  23. rtnflag = DesignTimeHelper.InDesignMode(this);
  24. #endif
  25. return rtnflag;
  26. }
  27. }
  28. private I2CDecodePrsnt DestinDecodePrsnt
  29. {
  30. get => destinDecodePrsnt;
  31. set
  32. {
  33. if (destinDecodePrsnt!=value)
  34. {
  35. destinDecodePrsnt = value;
  36. ///当有新的同步目标时,应先将目标中参数同步到本地<see cref="_I2CDecodePrsnt"/>属性中
  37. if (_I2CDecodePrsnt != null && value != null)
  38. {
  39. typeof(I2CDecodePrsnt).GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(x=>x.CanWrite).ToList().ForEach(x =>
  40. {
  41. x.SetValue(_I2CDecodePrsnt, x.GetValue(value));
  42. });
  43. }
  44. }
  45. }
  46. }
  47. private I2CDecodePrsnt destinDecodePrsnt;
  48. private I2CDecodePrsnt _I2CDecodePrsnt => Presenter as I2CDecodePrsnt;
  49. public IProtocolPrsnt Presenter { get; set; }
  50. private FloatForm _FloatForm;
  51. private Int32 _RowHeight = 56;
  52. private Int32 _ColnumCount = 2;
  53. #endregion 属性定义
  54. public I2CSetControl()
  55. {
  56. InitializeComponent();
  57. InitView();
  58. }
  59. protected override void OnLoad(EventArgs e)
  60. {
  61. base.OnLoad(e);
  62. Init();
  63. }
  64. private void Init()
  65. {
  66. GetDestinPrsnt();
  67. InitSCLK();
  68. InitSCLKThreshold();
  69. InitSDA();
  70. InitSDAThreshold();
  71. }
  72. /// <summary>
  73. /// 获取需要同步的Prsnt
  74. /// 当<see cref="_I2CDecodePrsnt"/>为<see cref="null"/>时表示不需要与其他Prsnt进行同步
  75. /// </summary>
  76. private void GetDestinPrsnt()
  77. {
  78. if (_I2CDecodePrsnt == null)
  79. return;
  80. if (_I2CDecodePrsnt.IsTrigger)
  81. DestinDecodePrsnt = Presenter.GetChannlesDecodePrsnt().Where(x => x is I2CDecodePrsnt decodePrsnt && decodePrsnt.SDA == _I2CDecodePrsnt.SDA).Cast<I2CDecodePrsnt>().OrderBy(x=>x.SDA).FirstOrDefault();
  82. else
  83. {
  84. if (Presenter.GetTriggerDecodePrsnt() is I2CDecodePrsnt i2cdecodePrsnt && i2cdecodePrsnt.SDA == _I2CDecodePrsnt.SDA)
  85. DestinDecodePrsnt = i2cdecodePrsnt;
  86. else
  87. DestinDecodePrsnt = null;
  88. }
  89. }
  90. /// <summary>
  91. /// 同步两个Prsnt
  92. /// </summary>
  93. /// <param name="propertyName">属性名称</param>
  94. private void DecodeSynchronization(String propertyName)
  95. {
  96. if (DestinDecodePrsnt == null)
  97. return;
  98. ///由于使用了<see cref="II2CDecodePrsnt.SDA"/>进行判断具体同步的目标
  99. ///因此<see cref="II2CDecodePrsnt.SDA"/>参数不进行同步
  100. if (propertyName == nameof(_I2CDecodePrsnt.SDA))
  101. return;
  102. if (String.IsNullOrEmpty(propertyName))
  103. {
  104. typeof(I2CDecodePrsnt).GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(x=>x.CanWrite).ToList().ForEach(x =>
  105. {
  106. x.SetValue(DestinDecodePrsnt, x.GetValue(_I2CDecodePrsnt));
  107. });
  108. }
  109. else
  110. {
  111. PropertyInfo propertyInfo = typeof(I2CDecodePrsnt).GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
  112. if (propertyInfo != null)
  113. propertyInfo.SetValue(DestinDecodePrsnt, propertyInfo.GetValue(_I2CDecodePrsnt));
  114. }
  115. }
  116. private void InitSDA()
  117. {
  118. this.CbxSDA.DataSource = ChannelIdExt.GetAnalogs().Select(x => new ComboBoxData<ChannelId>(x.GetDescription(), x, true)).ToList();
  119. this.CbxSDA.DisplayMember = "Key";
  120. this.CbxSDA.ValueMember = "Value";
  121. this.CbxSDA.SelectedValueChanged += (_, _) =>
  122. {
  123. _I2CDecodePrsnt.SDA = (ChannelId)this.CbxSDA.SelectedValue;
  124. };
  125. this.CbxSDA.SelectedValue = _I2CDecodePrsnt.SDA;
  126. }
  127. private void InitSDAThreshold()
  128. {
  129. this.BtnSDAThreshold.Text = SIHelper.ValueChangeToSI(_I2CDecodePrsnt.SDAThreshold, 2, "V");
  130. this.BtnSDAThreshold.Click += (_, _) =>
  131. {
  132. Boolean lastflag = true;
  133. if (this.FindForm() is FloatForm form)
  134. {
  135. lastflag = form.CanClose;
  136. form.CanClose = false;
  137. }
  138. if (_FloatForm != null && !_FloatForm.IsDisposed)
  139. _FloatForm?.Close();
  140. _FloatForm = new FloatForm();
  141. _FloatForm.BackColor = BackColor;
  142. _FloatForm.ForeColor = ForeColor;
  143. _FloatForm.Title = "设置数据通道阈值";
  144. _FloatForm.Width = 380;
  145. _FloatForm.Height = 500 + _FloatForm.HeadHeight;
  146. NumberKeyboard numberKeyboard = new NumberKeyboard();
  147. numberKeyboard.Controls.Cast<Control>().ToList().ForEach(x => Uni_Trend.MSO7000X.UserControls.Style.StyleManager.Instance.RegisterControl(x));
  148. numberKeyboard.Top = _FloatForm.HeadHeight;
  149. numberKeyboard.Height = _FloatForm.Height - _FloatForm.HeadHeight;
  150. numberKeyboard.Width = _FloatForm.Width;
  151. numberKeyboard.ForeColor = ForeColor;
  152. numberKeyboard.BackColor = BackColor;
  153. numberKeyboard.MaxValue = 12;
  154. numberKeyboard.MinValue = -12;
  155. numberKeyboard.DecimalNumber = 2;
  156. numberKeyboard.DefaultValue = _I2CDecodePrsnt.SDAThreshold;
  157. numberKeyboard.OkClickEvent += (sender, args) =>
  158. {
  159. _I2CDecodePrsnt.SDAThreshold = (Double)args.Data;
  160. UpdateSDAThreshold();
  161. _FloatForm.Close();
  162. };
  163. numberKeyboard.CancelEvent += (_, _) => _FloatForm.Close();
  164. _FloatForm.Controls.Add(numberKeyboard);
  165. _FloatForm.FormClosing += (_, _) =>
  166. {
  167. if (this.FindForm() is FloatForm form)
  168. form.CanClose = lastflag;
  169. };
  170. EventBus.EventBroker.Instance.GetEvent<Uni_Trend.MSO7000X.Common.Structs.FormEventArgs>().Publish(this, new Uni_Trend.MSO7000X.Common.Structs.FormEventArgs()
  171. {
  172. Current = _FloatForm,
  173. Type = Uni_Trend.MSO7000X.Common.Structs.FormType.InfoForm,
  174. });
  175. };
  176. }
  177. private void InitSCLKThreshold()
  178. {
  179. this.BtnSCLKThreshold.Text = SIHelper.ValueChangeToSI(_I2CDecodePrsnt.SCLKThreshold, 2, "V");
  180. this.BtnSCLKThreshold.Click += (_, _) =>
  181. {
  182. Boolean lastflag = true;
  183. if (this.FindForm() is FloatForm form)
  184. {
  185. lastflag = form.CanClose;
  186. form.CanClose = false;
  187. }
  188. if (_FloatForm != null && !_FloatForm.IsDisposed)
  189. _FloatForm?.Close();
  190. _FloatForm = new FloatForm();
  191. _FloatForm.BackColor = BackColor;
  192. _FloatForm.ForeColor = ForeColor;
  193. _FloatForm.Title = "设置数据通道阈值";
  194. _FloatForm.Width = 380;
  195. _FloatForm.Height = 500 + _FloatForm.HeadHeight;
  196. NumberKeyboard numberKeyboard = new NumberKeyboard();
  197. numberKeyboard.Controls.Cast<Control>().ToList().ForEach(x => Uni_Trend.MSO7000X.UserControls.Style.StyleManager.Instance.RegisterControl(x));
  198. numberKeyboard.Top = _FloatForm.HeadHeight;
  199. numberKeyboard.Height = _FloatForm.Height - _FloatForm.HeadHeight;
  200. numberKeyboard.Width = _FloatForm.Width;
  201. numberKeyboard.ForeColor = ForeColor;
  202. numberKeyboard.BackColor = BackColor;
  203. numberKeyboard.MaxValue = 12;
  204. numberKeyboard.MinValue = -12;
  205. numberKeyboard.DecimalNumber = 2;
  206. numberKeyboard.DefaultValue = _I2CDecodePrsnt.SCLKThreshold;
  207. numberKeyboard.OkClickEvent += (sender, args) =>
  208. {
  209. _I2CDecodePrsnt.SCLKThreshold = (Double)args.Data;
  210. UpdateSCLKThreshold();
  211. _FloatForm.Close();
  212. };
  213. numberKeyboard.CancelEvent += (_, _) => _FloatForm.Close();
  214. _FloatForm.Controls.Add(numberKeyboard);
  215. _FloatForm.FormClosing += (_, _) =>
  216. {
  217. if (this.FindForm() is FloatForm form)
  218. form.CanClose = lastflag;
  219. };
  220. EventBus.EventBroker.Instance.GetEvent<Uni_Trend.MSO7000X.Common.Structs.FormEventArgs>().Publish(this, new Uni_Trend.MSO7000X.Common.Structs.FormEventArgs()
  221. {
  222. Current = _FloatForm,
  223. Type = Uni_Trend.MSO7000X.Common.Structs.FormType.InfoForm,
  224. });
  225. };
  226. }
  227. private void InitSCLK()
  228. {
  229. this.CbxSCLK.DataSource = ChannelIdExt.GetAnalogs().Select(x => new ComboBoxData<ChannelId>(x.GetDescription(), x, x!=_I2CDecodePrsnt.SDA)).ToList();
  230. this.CbxSCLK.DisplayMember = "Key";
  231. this.CbxSCLK.ValueMember = "Value";
  232. this.CbxSCLK.SelectedValueChanged += (_, _) =>
  233. {
  234. _I2CDecodePrsnt.SCLK = (ChannelId)this.CbxSCLK.SelectedValue;
  235. };
  236. this.CbxSCLK.SelectedValue = _I2CDecodePrsnt.SCLK;
  237. }
  238. private void InitView()
  239. {
  240. Int32 rowcount = 1;
  241. Controls.Cast<Control>().ToList().ForEach(x => Uni_Trend.MSO7000X.UserControls.Style.StyleManager.Instance.RegisterControl(x));
  242. this.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance).Where(x => x.GetCustomAttribute<RowColAttribute>() != null && x.GetValue(this) is Control).Select(x =>
  243. {
  244. RowColAttribute attribute = x.GetCustomAttribute<RowColAttribute>();
  245. Control control = x.GetValue(this) as Control;
  246. return (attribute, control);
  247. }).GroupBy(x => x.attribute, (x => x.control)).ToList().ForEach(x =>
  248. {
  249. Control lable = x.First(x => x is UestcLabel);
  250. Control control = x.First(x => !(x is UestcLabel));
  251. lable.Left = Width / _ColnumCount * x.Key.Colnum;
  252. lable.Width = control.Width;
  253. lable.Height = lable.Font.Height;
  254. lable.Top = 10 + _RowHeight * x.Key.Row;
  255. control.Left = lable.Left;
  256. control.Top = lable.Bottom + 2;
  257. lable.Width = 120;
  258. control.Width = 120;
  259. rowcount = Math.Max(rowcount, x.Key.Row + 1);
  260. });
  261. Height = rowcount * _RowHeight;
  262. }
  263. /// <summary>
  264. /// <see cref="II2CDecodePrsnt.SCLK"/>与<see cref="II2CDecodePrsnt.SDA"/>中值不能相同
  265. /// </summary>
  266. private void ChangeSDA()
  267. {
  268. if (_I2CDecodePrsnt.SCLK == _I2CDecodePrsnt.SDA)
  269. {
  270. if (_I2CDecodePrsnt.SDA == ChannelIdExt.GetAnalogs().Last())
  271. _I2CDecodePrsnt.SCLK = ChannelIdExt.GetAnalogs().Last() - 1;
  272. else if (_I2CDecodePrsnt.SDA == ChannelIdExt.GetAnalogs().First())
  273. _I2CDecodePrsnt.SCLK = ChannelIdExt.GetAnalogs().First() + 1;
  274. else
  275. _I2CDecodePrsnt.SCLK++;
  276. }
  277. if (this.CbxSCLK.DataSource is IList list)
  278. {
  279. foreach (dynamic val in list)
  280. {
  281. val.Visible = val.Value != _I2CDecodePrsnt.SDA;
  282. }
  283. }
  284. }
  285. private class ComboBoxData<T>
  286. {
  287. public String Key { get; set; }
  288. public T Value { get; set; }
  289. public Boolean Visible { get; set; }
  290. public ComboBoxData(String key, T value, Boolean visible = true)
  291. {
  292. Key = key;
  293. Value = value;
  294. Visible = visible;
  295. }
  296. }
  297. #region UpdateFunction
  298. [UpdateProperty(nameof(I2CDecodePrsnt.SDAThreshold))]
  299. void UpdateSDAThreshold()
  300. {
  301. this.BtnSDAThreshold.Text = SIHelper.ValueChangeToSI(_I2CDecodePrsnt.SDAThreshold, 2, "V");
  302. }
  303. [UpdateProperty(nameof(I2CDecodePrsnt.SCLKThreshold))]
  304. void UpdateSCLKThreshold()
  305. {
  306. this.BtnSCLKThreshold.Text = SIHelper.ValueChangeToSI(_I2CDecodePrsnt.SCLKThreshold, 2, "V");
  307. }
  308. [UpdateProperty(nameof(I2CDecodePrsnt.SCLK))]
  309. void UpdateSCLK()
  310. {
  311. this.CbxSCLK.SelectedValue = _I2CDecodePrsnt.SCLK;
  312. }
  313. [UpdateProperty(nameof(I2CDecodePrsnt.SDA))]
  314. void UpdateSDA()
  315. {
  316. this.CbxSDA.SelectedValue = _I2CDecodePrsnt.SDA;
  317. GetDestinPrsnt();
  318. ChangeSDA();
  319. }
  320. #endregion UpdateFunction
  321. public void UpdateView(String propertyName)
  322. {
  323. DecodeSynchronization(propertyName);
  324. if (String.IsNullOrEmpty(propertyName))
  325. {
  326. UpdateView();
  327. return;
  328. }
  329. this.GetType().GetMethods(BindingFlags.NonPublic | BindingFlags.Instance).Where(x =>
  330. {
  331. UpdatePropertyAttribute attribute = x.GetCustomAttribute<UpdatePropertyAttribute>();
  332. return attribute != null && attribute.PropertyName == propertyName;
  333. }).FirstOrDefault()?.Invoke(this, null);
  334. }
  335. private void UpdateView()
  336. {
  337. this.GetType().GetMethods().Where(x => x.GetCustomAttribute<UpdatePropertyAttribute>() != null).ToList().ForEach(x => x?.Invoke(this, null));
  338. this.Refresh();
  339. }
  340. }
  341. [AttributeUsage(AttributeTargets.Field)]
  342. internal class RowColAttribute : Attribute
  343. {
  344. public RowColAttribute(Int32 row = 0, Int32 col = 0)
  345. {
  346. Row = row;
  347. Colnum = col;
  348. }
  349. public Int32 Row { get; set; }
  350. public Int32 Colnum { get; set; }
  351. public override Boolean Equals(Object obj)
  352. {
  353. if (obj == null)
  354. return false;
  355. if (!(obj is RowColAttribute attribute))
  356. return false;
  357. return attribute.Colnum == Colnum && attribute.Row == Row;
  358. }
  359. public override Int32 GetHashCode()
  360. {
  361. Int32 hashCode = Row.GetHashCode();
  362. if (Row.GetHashCode() != Colnum.GetHashCode())
  363. hashCode ^= Colnum.GetHashCode();
  364. return hashCode;
  365. }
  366. }
  367. [AttributeUsage(AttributeTargets.Method)]
  368. internal class UpdatePropertyAttribute : Attribute
  369. {
  370. public UpdatePropertyAttribute(string propertyName) => this.PropertyName = propertyName;
  371. public String PropertyName { get; set; }
  372. }
  373. }