RelationEditorForm.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. using FastReport.Data;
  2. using FastReport.Utils;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.ComponentModel;
  6. using System.Drawing;
  7. using System.Linq;
  8. using System.Windows.Forms;
  9. namespace FastReport.Forms
  10. {
  11. internal partial class RelationEditorForm : BaseDialogForm
  12. {
  13. private Relation relation;
  14. private void cbxParent_DrawItem(object sender, DrawItemEventArgs e)
  15. {
  16. e.DrawBackground();
  17. if (e.Index >= 0)
  18. {
  19. DataSourceBase dataSource = (sender as ComboBox).Items[e.Index] as DataSourceBase;
  20. this.DrawImageAndText(e, this.GetImage(222), dataSource.Alias);
  21. }
  22. }
  23. private void cbxParent_SelectedIndexChanged(object sender, EventArgs e)
  24. {
  25. columnsPanel.ParentDataSource = cbxParent.SelectedItem as DataSourceBase;
  26. }
  27. private void cbxChild_SelectedIndexChanged(object sender, EventArgs e)
  28. {
  29. columnsPanel.ChildDataSource = cbxChild.SelectedItem as DataSourceBase;
  30. }
  31. private void columnsPanel_Resize(object sender, EventArgs e)
  32. {
  33. ClientSize = new Size(ClientSize.Width, columnsPanel.Bottom + this.LogicalToDevice(50));
  34. }
  35. private void RelationEditorForm_FormClosing(object sender, FormClosingEventArgs e)
  36. {
  37. if (DialogResult == DialogResult.OK)
  38. {
  39. string[] parentColumns = columnsPanel.ParentColumns;
  40. string[] childColumns = columnsPanel.ChildColumns;
  41. e.Cancel = !(parentColumns.Length > 0 && parentColumns.Length == childColumns.Length);
  42. if (e.Cancel)
  43. FRMessageBox.Error(Res.Get("Forms,RelationEditor,Error"));
  44. }
  45. }
  46. private void RelationEditorForm_FormClosed(object sender, FormClosedEventArgs e)
  47. {
  48. Done();
  49. }
  50. private void Init()
  51. {
  52. Dictionary dictionary = relation.Report.Dictionary;
  53. ObjectCollection allObjects = dictionary.AllObjects;
  54. SortedList<string, DataSourceBase> tables = new SortedList<string, DataSourceBase>();
  55. foreach (Base c in allObjects)
  56. {
  57. if (c is DataSourceBase)
  58. {
  59. DataSourceBase table = c as DataSourceBase;
  60. if (!tables.ContainsKey(table.Alias))
  61. tables.Add(table.Alias, table);
  62. }
  63. }
  64. foreach (KeyValuePair<string, DataSourceBase> keyValue in tables)
  65. {
  66. DataSourceBase table = keyValue.Value;
  67. cbxParent.Items.Add(table);
  68. cbxChild.Items.Add(table);
  69. }
  70. cbxParent.SelectedItem = relation.ParentDataSource;
  71. cbxChild.SelectedItem = relation.ChildDataSource;
  72. if (relation.ParentColumns != null && relation.ChildColumns != null && relation.ParentColumns.Length == relation.ChildColumns.Length)
  73. {
  74. for (int i = 0; i < relation.ParentColumns.Length; i++)
  75. {
  76. columnsPanel.AddPanel(relation.ParentColumns[i], relation.ChildColumns[i]);
  77. }
  78. }
  79. columnsPanel.EnsureSinglePanel();
  80. }
  81. private void Done()
  82. {
  83. if (DialogResult == DialogResult.OK)
  84. {
  85. relation.ParentDataSource = columnsPanel.ParentDataSource;
  86. relation.ChildDataSource = columnsPanel.ChildDataSource;
  87. relation.ParentColumns = columnsPanel.ParentColumns;
  88. relation.ChildColumns = columnsPanel.ChildColumns;
  89. }
  90. }
  91. public override void Localize()
  92. {
  93. base.Localize();
  94. MyRes res = new MyRes("Forms,RelationEditor");
  95. Text = res.Get("");
  96. lblParentTable.Text = res.Get("ParentTable");
  97. lblChildTable.Text = res.Get("ChildTable");
  98. lblColumns.Text = res.Get("Columns");
  99. }
  100. public override void UpdateDpiDependencies()
  101. {
  102. base.UpdateDpiDependencies();
  103. cbxParent.ItemHeight = cbxChild.ItemHeight = this.LogicalToDevice(16);
  104. columnsPanel.UpdateDpiDependencies();
  105. }
  106. public RelationEditorForm(Relation relation)
  107. {
  108. this.relation = relation;
  109. InitializeComponent();
  110. Localize();
  111. UIUtils.CheckRTL(this);
  112. UpdateDpiDependencies();
  113. Init();
  114. }
  115. }
  116. internal class ColumnsPanel : Panel
  117. {
  118. private List<ColumnPanel> panels;
  119. private DataSourceBase parentDataSource;
  120. private DataSourceBase childDataSource;
  121. [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  122. public DataSourceBase ParentDataSource
  123. {
  124. get => parentDataSource;
  125. set
  126. {
  127. parentDataSource = value;
  128. panels.ForEach(p => p.ParentDataSource = value);
  129. }
  130. }
  131. [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  132. public DataSourceBase ChildDataSource
  133. {
  134. get => childDataSource;
  135. set
  136. {
  137. childDataSource = value;
  138. panels.ForEach(p => p.ChildDataSource = value);
  139. }
  140. }
  141. public string[] ParentColumns => panels.Select(p => p.ParentColumn).Where(x => !string.IsNullOrEmpty(x)).ToArray();
  142. public string[] ChildColumns => panels.Select(p => p.ChildColumn).Where(x => !string.IsNullOrEmpty(x)).ToArray();
  143. private void UpdateSize()
  144. {
  145. Height = panels.Sum(p => p.Height);
  146. }
  147. private ColumnPanel AddEmptyPanel(ColumnPanel sender)
  148. {
  149. var panel = new ColumnPanel() { ParentDataSource = ParentDataSource, ChildDataSource = ChildDataSource };
  150. if (sender == null)
  151. panels.Add(panel);
  152. else
  153. panels.Insert(panels.IndexOf(sender) + 1, panel);
  154. Controls.Add(panel);
  155. Controls.SetChildIndex(panel, sender == null ? 0 : Controls.IndexOf(sender));
  156. panel.Scale(new SizeF(this.DpiMultiplier(), this.DpiMultiplier()));
  157. UIUtils.CheckRTL(panel);
  158. panel.UpdateDpiDependencies();
  159. panel.Focus();
  160. UpdateSize();
  161. return panel;
  162. }
  163. private void RemovePanel(ColumnPanel panel)
  164. {
  165. if (panels.Count > 1)
  166. {
  167. panels.Remove(panel);
  168. panel.Dispose();
  169. UpdateSize();
  170. }
  171. else
  172. {
  173. panel.ParentColumn = null;
  174. panel.ChildColumn = null;
  175. }
  176. }
  177. public void AddPanel(string parentColumn, string childColumn)
  178. {
  179. var panel = AddEmptyPanel(null);
  180. panel.ParentColumn = parentColumn;
  181. panel.ChildColumn = childColumn;
  182. }
  183. public void EnsureSinglePanel()
  184. {
  185. if (panels.Count == 0)
  186. AddPanel("", "");
  187. }
  188. public void UpdateDpiDependencies() => panels.ForEach(p => p.UpdateDpiDependencies());
  189. public ColumnsPanel()
  190. {
  191. panels = new List<ColumnPanel>();
  192. Size = new Size(445, 150);
  193. }
  194. private class ColumnPanel : Panel
  195. {
  196. private ComboBox cbxParentColumn;
  197. private ComboBox cbxChildColumn;
  198. private Button btnAdd;
  199. private Button btnRemove;
  200. private ColumnsPanel ParentPanel => Parent as ColumnsPanel;
  201. private DataSourceBase parentDataSource;
  202. public DataSourceBase ParentDataSource
  203. {
  204. get => parentDataSource;
  205. set
  206. {
  207. parentDataSource = value;
  208. FillColumns(value, cbxParentColumn);
  209. }
  210. }
  211. private DataSourceBase childDataSource;
  212. public DataSourceBase ChildDataSource
  213. {
  214. get => childDataSource;
  215. set
  216. {
  217. childDataSource = value;
  218. FillColumns(value, cbxChildColumn);
  219. }
  220. }
  221. public string ParentColumn
  222. {
  223. get => cbxParentColumn.Text;
  224. set => cbxParentColumn.Text = value;
  225. }
  226. public string ChildColumn
  227. {
  228. get => cbxChildColumn.Text;
  229. set => cbxChildColumn.Text = value;
  230. }
  231. private void FillColumns(DataSourceBase dataSource, ComboBox comboBox)
  232. {
  233. comboBox.Items.Clear();
  234. if (dataSource == null)
  235. return;
  236. foreach (Column column in dataSource.Columns)
  237. {
  238. comboBox.Items.Add(column.Alias);
  239. }
  240. }
  241. private void btnAdd_Click(object sender, EventArgs e)
  242. {
  243. ParentPanel.AddEmptyPanel(this);
  244. }
  245. private void btnRemove_Click(object sender, EventArgs e)
  246. {
  247. ParentPanel.RemovePanel(this);
  248. }
  249. private void cbxParentColumn_DrawItem(object sender, DrawItemEventArgs e)
  250. {
  251. e.DrawBackground();
  252. if (e.Index >= 0)
  253. {
  254. var column = ParentDataSource.Columns[e.Index];
  255. this.DrawImageAndText(e, this.GetImage(column.GetImageIndex()), column.Alias);
  256. }
  257. }
  258. private void cbxChildColumn_DrawItem(object sender, DrawItemEventArgs e)
  259. {
  260. e.DrawBackground();
  261. if (e.Index >= 0)
  262. {
  263. var column = ChildDataSource.Columns[e.Index];
  264. this.DrawImageAndText(e, this.GetImage(column.GetImageIndex()), column.Alias);
  265. }
  266. }
  267. public void UpdateDpiDependencies()
  268. {
  269. btnAdd.Image = this.GetImage(213);
  270. btnRemove.Image = this.GetImage(51);
  271. cbxParentColumn.ItemHeight = cbxChildColumn.ItemHeight = this.LogicalToDevice(16);
  272. }
  273. public ColumnPanel()
  274. {
  275. Dock = DockStyle.Top;
  276. Height = 27;
  277. cbxParentColumn = new ComboBox();
  278. cbxParentColumn.DrawMode = DrawMode.OwnerDrawFixed;
  279. cbxParentColumn.DropDownStyle = ComboBoxStyle.DropDownList;
  280. cbxParentColumn.Location = new Point(3, 3);
  281. cbxParentColumn.Size = new Size(175, 21);
  282. cbxParentColumn.DrawItem += cbxParentColumn_DrawItem;
  283. cbxChildColumn = new ComboBox();
  284. cbxChildColumn.DrawMode = DrawMode.OwnerDrawFixed;
  285. cbxChildColumn.DropDownStyle = ComboBoxStyle.DropDownList;
  286. cbxChildColumn.Location = new Point(190, 3);
  287. cbxChildColumn.Size = new Size(175, 21);
  288. cbxChildColumn.DrawItem += cbxChildColumn_DrawItem;
  289. btnAdd = new Button();
  290. btnAdd.FlatStyle = FlatStyle.Flat;
  291. btnAdd.FlatAppearance.BorderSize = 0;
  292. btnAdd.Location = new Point(372, 2);
  293. btnAdd.Size = new Size(23, 23);
  294. btnAdd.Click += btnAdd_Click;
  295. btnRemove = new Button();
  296. btnRemove.FlatStyle = FlatStyle.Flat;
  297. btnRemove.FlatAppearance.BorderSize = 0;
  298. btnRemove.Location = new Point(394, 2);
  299. btnRemove.Size = new Size(23, 23);
  300. btnRemove.Click += btnRemove_Click;
  301. Controls.Add(btnRemove);
  302. Controls.Add(btnAdd);
  303. Controls.Add(cbxChildColumn);
  304. Controls.Add(cbxParentColumn);
  305. }
  306. }
  307. }
  308. }