delphi – 是否有可用的数据感知选项卡控件?

前端之家收集整理的这篇文章主要介绍了delphi – 是否有可用的数据感知选项卡控件?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
数据感知控件可以链接到数据集,以显示当前行中的字段中包含的数据,或者在某些情况下,显示来自多行中的一个或多个列的数据. TTabControl允许您以易于理解的方式将同一组控件应用于不同的数据值集.

在我看来他们会很好地在一起. TTabControl将提供良好的数据感知控制(将其链接到数据集中的标识列,它可能是比TDBNavigator更直观的导航器),但VCL中没有一个.

有没有人创建了数据感知选项卡控件?我发现的唯一一个是Jean-Luc Mattei的DBTABCONTROL98,它可以追溯到1998年(Delphi 3时代),甚至在修改它以使其在XE下编译之后,实际上并不起作用.有没有其他工作符合预期? (即,在数据集中添加/删除新记录时添加/删除选项卡,并在用户更改选项卡时切换数据集的活动行,反之亦然.)

是的,我知道如果数据集中有很多行,那可能会有点笨拙.我正在寻找一些东西来构建一个用例,其中行数是单个或非常低的两位数.

解决方法

我为你写了一个TDBTabControl.如果未设置DataField属性,则选项卡的标题将是记录索引.带星号的选项卡表示新记录,可以使用ShowInsertTab属性切换可见性.

我继承自TCustomTabControl,因为可能不会为此组件发布属性Tabs,TabIndex和MultiSelect.

  1. unit DBTabControl;
  2.  
  3. interface
  4.  
  5. uses
  6. Classes,Windows,SysUtils,Messages,Controls,ComCtrls,DB,DBCtrls;
  7.  
  8. type
  9. TCustomDBTabControl = class(TCustomTabControl)
  10. private
  11. FDataLink: TFieldDataLink;
  12. FPrevTabIndex: Integer;
  13. FShowInsertTab: Boolean;
  14. procedure ActiveChanged(Sender: TObject);
  15. procedure DataChanged(Sender: TObject);
  16. function GetDataField: String;
  17. function GetDataSource: TDataSource;
  18. function GetField: TField;
  19. procedure RebuildTabs;
  20. procedure SetDataField(const Value: String);
  21. procedure SetDataSource(Value: TDataSource);
  22. procedure SetShowInsertTab(Value: Boolean);
  23. procedure CMExit(var Message: TCMExit); message CM_EXIT;
  24. procedure CMGetDataLink(var Message: TMessage); message CM_GETDATALINK;
  25. protected
  26. function CanChange: Boolean; override;
  27. procedure Change; override;
  28. procedure KeyDown(var Key: Word; Shift: TShiftState); override;
  29. procedure Notification(AComponent: TComponent; Operation: TOperation);
  30. override;
  31. procedure Loaded; override;
  32. property DataField: String read GetDataField write SetDataField;
  33. property DataSource: TDataSource read GetDataSource write SetDataSource;
  34. property Field: TField read GetField;
  35. property ShowInsertTab: Boolean read FShowInsertTab write SetShowInsertTab
  36. default False;
  37. public
  38. constructor Create(AOwner: TComponent); override;
  39. destructor Destroy; override;
  40. function ExecuteAction(Action: TBasicAction): Boolean; override;
  41. function UpdateAction(Action: TBasicAction): Boolean; override;
  42. end;
  43.  
  44. TDBTabControl = class(TCustomDBTabControl)
  45. public
  46. property DisplayRect;
  47. property Field;
  48. published
  49. property Align;
  50. property Anchors;
  51. property BiDiMode;
  52. property Constraints;
  53. property DockSite;
  54. property DataField;
  55. property DataSource;
  56. property DragCursor;
  57. property DragKind;
  58. property DragMode;
  59. property Enabled;
  60. property Font;
  61. property HotTrack;
  62. property Images;
  63. property MultiLine;
  64. property OwnerDraw;
  65. property ParentBiDiMode;
  66. property ParentFont;
  67. property ParentShowHint;
  68. property PopupMenu;
  69. property RaggedRight;
  70. property ScrollOpposite;
  71. property ShowHint;
  72. property ShowInsertTab;
  73. property Style;
  74. property TabHeight;
  75. property TabOrder;
  76. property TabPosition;
  77. property TabStop;
  78. property TabWidth;
  79. property Visible;
  80. property OnChange;
  81. property OnChanging;
  82. property OnContextPopup;
  83. property OnDockDrop;
  84. property OnDockOver;
  85. property OnDragDrop;
  86. property OnDragOver;
  87. property OnDrawTab;
  88. property OnEndDock;
  89. property OnEndDrag;
  90. property OnEnter;
  91. property OnExit;
  92. property OnGetImageIndex;
  93. property OnGetSiteInfo;
  94. property OnMouseDown;
  95. property OnMouseMove;
  96. property OnMouseUp;
  97. property OnResize;
  98. property OnStartDock;
  99. property OnStartDrag;
  100. property OnUnDock;
  101. end;
  102.  
  103. implementation
  104.  
  105. { TCustomDBTabControl }
  106.  
  107. procedure TCustomDBTabControl.ActiveChanged(Sender: TObject);
  108. begin
  109. RebuildTabs;
  110. end;
  111.  
  112. function TCustomDBTabControl.CanChange: Boolean;
  113. begin
  114. FPrevTabIndex := TabIndex;
  115. Result := (inherited CanChange) and (DataSource <> nil) and
  116. (DataSource.State in [dsBrowse,dsEdit,dsInsert]);
  117. end;
  118.  
  119. procedure TCustomDBTabControl.Change;
  120. var
  121. NewTabIndex: Integer;
  122. begin
  123. try
  124. if FDataLink.Active and (DataSource <> nil) then
  125. begin
  126. if FShowInsertTab and (TabIndex = Tabs.Count - 1) then
  127. DataSource.DataSet.Append
  128. else if DataSource.State = dsInsert then
  129. begin
  130. NewTabIndex := TabIndex;
  131. DataSource.DataSet.CheckBrowseMode;
  132. DataSource.DataSet.MoveBy(NewTabIndex - TabIndex);
  133. end
  134. else
  135. DataSource.DataSet.MoveBy(TabIndex - FPrevTabIndex);
  136. end;
  137. inherited Change;
  138. except
  139. TabIndex := FPrevTabIndex;
  140. raise;
  141. end;
  142. end;
  143.  
  144. procedure TCustomDBTabControl.CMExit(var Message: TCMExit);
  145. begin
  146. try
  147. FDataLink.UpdateRecord;
  148. except
  149. SetFocus;
  150. raise;
  151. end;
  152. inherited;
  153. end;
  154.  
  155. procedure TCustomDBTabControl.CMGetDataLink(var Message: TMessage);
  156. begin
  157. Message.Result := Integer(FDataLink);
  158. end;
  159.  
  160. constructor TCustomDBTabControl.Create(AOwner: TComponent);
  161. begin
  162. inherited Create(AOwner);
  163. FDataLink := TFieldDataLink.Create;
  164. FDataLink.Control := Self;
  165. FDataLink.OnActiveChange := ActiveChanged;
  166. FDataLink.OnDataChange := DataChanged;
  167. end;
  168.  
  169. procedure TCustomDBTabControl.DataChanged(Sender: TObject);
  170. const
  171. StarCount: array[Boolean] of Integer = (0,1);
  172. var
  173. NewTabIndex: Integer;
  174. begin
  175. if FDataLink.Active and (DataSource <> nil) then
  176. with DataSource do
  177. begin
  178. if DataSet.RecordCount <> Tabs.Count - StarCount[FShowInsertTab] then
  179. RebuildTabs
  180. else if (State = dsInsert) and FShowInsertTab then
  181. TabIndex := Tabs.Count - 1
  182. else if Tabs.Count > 0 then
  183. begin
  184. NewTabIndex := Tabs.IndexOfObject(TObject(DataSet.RecNo));
  185. if (TabIndex = NewTabIndex) and (State <> dsInsert) and
  186. (Field <> nil) and (Field.AsString <> Tabs[TabIndex]) then
  187. Tabs[TabIndex] := Field.AsString;
  188. TabIndex := NewTabIndex;
  189. end;
  190. end;
  191. end;
  192.  
  193. destructor TCustomDBTabControl.Destroy;
  194. begin
  195. FDataLink.Free;
  196. FDataLink := nil;
  197. inherited Destroy;
  198. end;
  199.  
  200. function TCustomDBTabControl.ExecuteAction(Action: TBasicAction): Boolean;
  201. begin
  202. Result := inherited ExecuteAction(Action) or FDataLink.ExecuteAction(Action);
  203. end;
  204.  
  205. function TCustomDBTabControl.GetDataField: String;
  206. begin
  207. Result := FDataLink.FieldName;
  208. end;
  209.  
  210. function TCustomDBTabControl.GetDataSource: TDataSource;
  211. begin
  212. Result := FDataLink.DataSource;
  213. end;
  214.  
  215. function TCustomDBTabControl.GetField: TField;
  216. begin
  217. Result := FDataLink.Field;
  218. end;
  219.  
  220. procedure TCustomDBTabControl.KeyDown(var Key: Word; Shift: TShiftState);
  221. begin
  222. if (DataSource <> nil) and (DataSource.State = dsInsert) and
  223. (Key = VK_ESCAPE) then
  224. begin
  225. DataSource.DataSet.Cancel;
  226. Change;
  227. end;
  228. inherited keyDown(Key,Shift);
  229. end;
  230.  
  231. procedure TCustomDBTabControl.Loaded;
  232. begin
  233. inherited Loaded;
  234. if (csDesigning in ComponentState) then
  235. RebuildTabs;
  236. end;
  237.  
  238. procedure TCustomDBTabControl.Notification(AComponent: TComponent;
  239. Operation: TOperation);
  240. begin
  241. inherited Notification(AComponent,Operation);
  242. if (Operation = opRemove) and (FDataLink <> nil) and
  243. (AComponent = DataSource) then
  244. DataSource := nil;
  245. end;
  246.  
  247. procedure TCustomDBTabControl.RebuildTabs;
  248. var
  249. Bookmark: TBookmark;
  250. begin
  251. if (DataSource <> nil) and (DataSource.State = dsBrowse) then
  252. with DataSource do
  253. begin
  254. if HandleAllocated then
  255. LockWindowUpdate(Handle);
  256. Tabs.BeginUpdate;
  257. DataSet.DisableControls;
  258. BookMark := DataSet.GetBookmark;
  259. try
  260. Tabs.Clear;
  261. DataSet.First;
  262. while not DataSet.Eof do
  263. begin
  264. if Field = nil then
  265. Tabs.AddObject(IntToStr(Tabs.Count + 1),TObject(DataSet.RecNo))
  266. else
  267. Tabs.AddObject(Field.AsString,TObject(DataSet.RecNo));
  268. DataSet.Next;
  269. end;
  270. if FShowInsertTab then
  271. Tabs.AddObject('*',TObject(-1));
  272. finally
  273. DataSet.GotoBookmark(Bookmark);
  274. DataSet.FreeBookmark(Bookmark);
  275. DataSet.EnableControls;
  276. Tabs.EndUpdate;
  277. if HandleAllocated then
  278. LockWindowUpdate(0);
  279. end;
  280. end
  281. else
  282. Tabs.Clear;
  283. end;
  284.  
  285. procedure TCustomDBTabControl.SetDataField(const Value: String);
  286. begin
  287. FDataLink.FieldName := Value;
  288. RebuildTabs;
  289. end;
  290.  
  291. procedure TCustomDBTabControl.SetDataSource(Value: TDataSource);
  292. begin
  293. FDataLink.DataSource := Value;
  294. if DataSource <> nil then
  295. DataSource.FreeNotification(Self);
  296. if not (csLoading in ComponentState) then
  297. RebuildTabs;
  298. end;
  299.  
  300. procedure TCustomDBTabControl.SetShowInsertTab(Value: Boolean);
  301. begin
  302. if FShowInsertTab <> Value then
  303. begin
  304. FShowInsertTab := Value;
  305. RebuildTabs;
  306. end;
  307. end;
  308.  
  309. function TCustomDBTabControl.UpdateAction(Action: TBasicAction): Boolean;
  310. begin
  311. Result := inherited UpdateAction(Action) or FDataLink.UpdateAction(Action);
  312. end;
  313.  
  314. end.
  1. unit DBTabControlReg;
  2.  
  3. interface
  4.  
  5. uses
  6. Classes,DBTabControl;
  7.  
  8. procedure Register;
  9.  
  10. implementation
  11.  
  12. procedure Register;
  13. begin
  14. RegisterComponents('Samples',[TDBTabControl]);
  15. end;
  16.  
  17. end.
  1. package DBTabControl70;
  2.  
  3. {$R *.res}
  4. {$ALIGN 8}
  5. {$ASSERTIONS ON}
  6. {$BOOLEVAL OFF}
  7. {$DEBUGINFO ON}
  8. {$EXTENDEDSyntax ON}
  9. {$IMPORTEDDATA ON}
  10. {$IOCHECKS ON}
  11. {$LOCALSYMBOLS ON}
  12. {$LONGSTRINGS ON}
  13. {$OPENSTRINGS ON}
  14. {$OPTIMIZATION OFF}
  15. {$OVERFLOWCHECKS ON}
  16. {$RANGECHECKS ON}
  17. {$REFERENCEINFO ON}
  18. {$SAFEDIVIDE OFF}
  19. {$STACKFRAMES ON}
  20. {$TYPEDADDRESS OFF}
  21. {$VARSTRINGCHECKS ON}
  22. {$WRITEABLECONST OFF}
  23. {$MINENUMSIZE 1}
  24. {$IMAGEBASE $400000}
  25. {$DESCRIPTION '#DBTabControl'}
  26. {$IMPLICITBUILD OFF}
  27.  
  28. requires
  29. rtl,vcl,dbrtl,vcldb;
  30.  
  31. contains
  32. DBTabControl in 'DBTabControl.pas',DBTabControlReg in 'DBTabControlReg.pas';
  33.  
  34. end.

猜你在找的Delphi相关文章