• cxgrid技巧集


    ==========================================================================

    在主从TableView中根据主TableView得到对应的从TableView
    var
    ADetailDC: TcxGridDataController;
    AView: TcxCustomGridTableView;
    begin
    with cxGrid1DBTableView1.DataController do
    ADetailDC := TcxGridDataController(GetDetailDataController(FocusedRecordIndex, 0));
    AView := ADetailDC.GridView;
    end;

    ==============================================================================

    定位在第一行并显示内置编辑器

    cxDBVerticalGrid1.FocusedRow := cxDBVerticalGrid1.Rows[0];
    cxDBVerticalGrid1.ShowEdit;

    ==============================================================================

    隐藏 "<No data to display>" 字符串

    该文本存储在scxGridNoDataInfoText资源字符串,可以将该资源字符串的内容设为空
    来隐藏该文本。

    uses cxClasses, cxGridStrs;
    ...
    cxSetResourceString(@scxGridNoDataInfoText, '');

    //如果"<No data to display>" 字符串已经显示,需要调用:
    <View>.LayoutChanged;

    ============================================================

    删除应用过滤后的行

    var
    I: Integer;
    begin
    with <GridView> do
    for I := 0 to ViewData.RecordCount - 1 do
    begin
    ViewData.Records[0].Focused := True;
    DataController.DataSet.Delete;
    end;

    =============================================================

    根据单元的值设置样式

    procedure <aForm>.<aColumn>StylesGetContentStyle(
    Sender: TcxCustomGridTableView; ARecord: TcxCustomGridRecord;
    AItem: TcxCustomGridTableItem; out AStyle: TcxStyle);
    begin
    if ARecord.Values[AItem.Index] = aSomeValue then
    AStyle := <aSomeStyle>;
    end;

    procedure <aForm>.<aView>StylesGetContentStyle(
    Sender: TcxCustomGridTableView; ARecord: TcxCustomGridRecord;
    AItem: TcxCustomGridTableItem; out AStyle: TcxStyle);
    var
    AColumn: TcxCustomGridTableItem;
    begin
    AColumn := (Sender as TcxGridDBTableView).GetColumnByFieldName('Email');
    if VarToStr(ARecord.Values[AColumn.Index]) = '' then
    AStyle := cxStyleNullEmail;
    end;

    ==============================================================================

    TcxCustomGridTableView.FindItemByName, TcxGridDBTableView.GetColumnByFieldName or
    TcxGridDBDataController.GetItemByFieldName

    with cxGrid1DBBandedTableView1.DataController do
    AValue := Values[FocusedRecordIndex, GetItemByFieldName('SomeFieldName').Index];

    ===================================================================

    动态生成BandedView

    var
    AView: TcxCustomGridView;
    begin
    AView := <cxGrid>.CreateView(TcxGridDBBandedTableView);
    TcxGridDBBandedTableView(AView).DataController.DataSource := <DataSource>;
    TcxGridDBBandedTableView(AView).Bands.Add;
    with TcxGridDBBandedTableView(AView).Bands.Add do
    begin
    Visible := False;
    FixedKind := fkLeft;
    end;
    TcxGridDBBandedTableView(AView).DataController.CreateAllItems;
    <cxGridLevel>.GridView := AView;  

    ======================================================================

    当底层数据集为空时显示一条空记录

    procedure <Form>.<cxGrid>Enter(Sender: TObject);
    var
    View: TcxGridDBTableView;
    begin
    View := TcxGridDBTableView((Sender as TcxGrid).FocusedView);
    if View.DataController.DataSet.IsEmpty then
    begin
    View.DataController.DataSet.Append;
    View.Controller.EditingController.ShowEdit;
    end;
    end;

    =======================================================================

    在当前View插入记录

    使用FocusedView属性得到当前焦点View,用View.DataController得到对应的Data Controller,
    之后使用Data Controller的方法来操作数据:
    - Append
    - Insert
    - Post
    - Cancel
    - DeleteFocused
    - DeleteSelection

    示例:
    var
    ARecIndex: Integer;

    View.DataController.Append;
    ARecIndex := View.DataController.FocusedRecordIndex;
    View.DataController.Values[ARecIndex, SomeItemIndex] := SomeValue;
    View.DataController.Post;

    另外一种方法是使用View.DataController.DataSource.DataSet得到底层数据集后,再用数据集的
    方法来操作数据。

    ========================================================================

    激活内置编辑控件

    1) <aView>.Controller.EditingController.ShowEdit(<aColumn>);
    2) <aView>.Controller.EditingController.StartEditShowingTimer(<aColumn>);
    3) <aView>.Controller.EditingItem := <aColumn>;
    4) <aColumn>.Editing := True;

    隐藏内置编辑控件
    <aView>.Controller.EditingController.HideEdit(True);

    ===========================================================================

    移除一个分组列

    <aColumn>.GroupIndex := -1;
    <aColumn>.Visible := True;

    ===========================================================================

    保存修改到数据库

    procedure <aForm>.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
    if (<aGrid>.FocusedView <> nil) and (<aGrid>.FocusedView.DataController.EditState <> []) then
    <aGrid>.FocusedView.DataController.Post;
    end;

    ============================================================================

    设置内置右键菜单

    内置右键菜单包括二个菜单:cxGridStdHeaderMenu, TcxGridStdFooterMenu

    uses cxGridStdPopupMenu;

    procedure TForm1.cxGridPopupMenu1Popup(ASenderMenu: TComponent;
    AHitTest: TcxCustomGridHitTest; X, Y: Integer; var AllowPopup: Boolean);
    begin
    if ASenderMenu is TcxGridStdHeaderMenu then
    TcxGridStdHeaderMenu(ASenderMenu).OnPopup := StdHeaderMenuPopup;
    end;

    procedure TForm1.StdHeaderMenuPopup(Sender: TObject);
    var
    I: Integer;
    begin
    with TcxGridStdHeaderMenu(Sender).Items do
    for I := 0 to Count - 1 do
    if Items[I].Caption = 'Group By Box' then
    begin
    Items[I].Enabled := False;
    System.Break;
    end
    end;

    ===========================================================================

    得到选中记录的值

    1) View.DataController.DataModeController.GridMode = False时

    RecIdx := View.Controller.SelectedRecords[i].RecordIndex;
    ColIdx := View.DataController.GetItemByFieldName(AFieldName).Index;
    OutputVal := View.DataController.Values[RecIdx, ColIdx];

    //RecID := View.DataController.GetRecordId(RecIdx);
    //OutputVal := ADataSet.Lookup(View.DataController.KeyFieldNames, RecID, AFieldName);

    2) View.DataController.DataModeController.GridMode = True时
    Bkm := View.DataController.GetSelectedBookmark(ASelectedRecordIndex);
    if ADataSet.BookmarkValid(TBookmark(Bkm)) then
    begin
    ADataSet.Bookmark := TBookmark(Bkm);
    OutputVal := ADataSet.FieldByName(AFieldName).Value;
    end;

    View.BeginUpdate;
    View.DataController.BeginLocate;
    try
    // make changes here…
    finally
    View.DataController.EndLocate;
    View.EndUpdate;
    end;

    =============================================================

    在GridMode禁用内置的右键Footer菜单

    uses cxGridStdPopupMenu;

    procedure cxGridPopupMenuOnPopup(...)
    begin
    if (ASenderMenu is TcxGridStdFooterMenu) and
    <GridView>.DataController.DataModeController.GridMode then
    AllowPopup := False;
    end;

    ==============================================================

    主从表任何时候只能展开一个组

    procedure TForm1.ADetailDataControllerCollapsing(
    ADataController: TcxCustomDataController; ARecordIndex: Integer;
    var AAllow: Boolean);
    var
    I: Integer;
    C: Integer;
    begin
    AAllow := False;
    C := 0;
    for I := 0 to ADataController.RecordCount - 1 do
    begin
    if ADataController.GetDetailExpanding(I) then
    Inc(C);
    if C > 1 then
    AAllow := True;
    end;
    end;

    procedure TForm1.ADetailDataControllerExpanding(
    ADataController: TcxCustomDataController; ARecordIndex: Integer;
    var AAllow: Boolean);
    begin
    ADataController.CollapseDetails;
    end;

    procedure TForm1.FormCreate(Sender: TObject);
    begin
    cxGrid1DBTableView1.DataController.OnDetailExpanding := ADetailDataControllerExpanding;
    cxGrid1DBTableView1.DataController.OnDetailCollapsing := ADetailDataControllerCollapsing;
    end;

    =================================================================

    动态创建层次(Level)和视图(View)

    var
    Grid: TcxGrid;
    Level: TcxGridLevel;
    View: TcxGridDBTableView;
    begin
    // Creates a Grid instance
    Grid := TcxGrid.Create(SomeOwner);
    Grid.Parent := SomeParent;
    // Creates a Level
    Level := Grid.Levels.Add;
    Level.Name := 'SomeLevelName';
    // Creates a View
    View := Grid.CreateView(TcxGridDBTableView) as TcxGridDBTableView;
    View.Name := 'SomeViewName';
    // … and binds it to the Level
    Level.GridView := View;
    // Hooks up the View to the data
    View.DataController.DataSource := SomeDataSource;
    // … and creates all columns
    View.DataController.CreateAllItems;
    end;

    ======================================================================

    获得Group Footer合计行对应的记录

    procedure TForm1.cxGrid1DBTableView1CustomDrawFooterCell(
    Sender: TcxGridTableView; ACanvas: TcxCanvas;
    AViewInfo: TcxGridColumnHeaderViewInfo; var ADone: Boolean);
    var
    ALevel, ADataGroupIndex: Integer;
    AGridRecord, AGroupRecord: TcxCustomGridRecord;
    begin
    if AViewInfo is TcxGridRowFooterCellViewInfo and // Row footer
    (TcxGridDBColumn(AViewInfo.Column).DataBinding.FieldName = 'Area') then // Area column
    begin
    AGridRecord := TcxGridRowFooterCellViewInfo(AViewInfo).GridRecord;
    ALevel := TcxGridRowFooterCellViewInfo(AViewInfo).Container.GroupLevel;
    ADataGroupIndex := Sender.DataController.Groups.DataGroupIndexByRowIndex[AGridRecord.Index];
    if ADataGroupIndex <> -1 then
    begin
    AGroupRecord := AGridRecord;
    while AGroupRecord.Level <> ALevel do
    AGroupRecord := AGroupRecord.ParentRecord;
    AViewInfo.Text := AGroupRecord.DisplayTexts[0];
    end;
    end;
    end;

    ===========================================================================

    访问过滤之后的记录

    var
    I: Integer;
    begin
    Memo1.Lines.Clear;
    with cxGrid1DBTableView1.DataController do
    for I := 0 to FilteredRecordCount - 1 do
    Memo1.Lines.Add(DisplayTexts[FilteredRecordIndex[I], 0]);
    end;

    ============================================================================

    获得单元的Font

    cxGrid1DBTableView1.ViewInfo.RecordsViewInfo.Items[1].GetCellViewInfoByItem(
    cxGrid1DBTableView1Company).EditViewInfo.Font;

    ============================================================================

    根据Level名称找到Level对象

    function GetLevelByName(AGrid: TcxGrid; ALevelName: string): TcxGridLevel;

    function LoopThroughLevels(ALevel: TcxGridLevel; ALevelName: string): TcxGridLevel;
    var
    I: Integer;
    begin
    Result := nil;
    for I := 0 to ALevel.Count - 1 do
    begin
    if ALevel[I].Name = ALevelName then
    begin
    Result := ALevel[I];
    Exit;
    end;
    if ALevel[I].Count > 0 then
    begin
    Result := LoopThroughLevels(ALevel[I], ALevelName);
    if Result <> nil then
    Exit;
    end;
    end;
    end;

    var
    I: Integer;
    begin
    Result := nil;
    for I := 0 to AGrid.Levels.Count - 1 do
    begin
    if AGrid.Levels[I].Name = ALevelName then
    begin
    Result := AGrid.Levels[I];
    Exit;
    end;
    if AGrid.Levels[I].Count > 0 then
    begin
    Result := LoopThroughLevels(AGrid.Levels[I], ALevelName);
    if Result <> nil then
    Exit;
    end;
    end;
    end;

    ============================================================================

    指定Filter Builder打开/保存过滤文件的默认路径

    uses
    ..., cxFilterControlDialog;

    procedure TForm.GridView1FilterControlDialogShow(
    Sender: TObject);
    begin
    TfmFilterControlDialog(Sender).OpenDialog.InitialDir := 'D:/'
    end;

    ============================================================================

    保存/恢复带汇总行的布局

    <TableView>.StoreToIniFile('c:/Grid.ini', True, [gsoUseSummary]);
    <GridView>.RestoreFromIniFile(<inifilename>,True,False {or True, optional},[gsoUseSummary]);

    ============================================================================

    取消过滤时移到第一行

    uses
    cxCustomData;

    procedure TYour_Form.AViewDataControllerFilterChanged(Sender: TObject);
    var
    Filter: TcxDataFilterCriteria;
    begin
    with Sender as TcxDataFilterCriteria do
    if IsEmpty then
    DataController.FocusedRowIndex := 0;
    end;

    =============================================================================

    排序后移到第一行

    可以设置DataController.Options.FocusTopRowAfterSorting := True,也可以使用如下的代码:

    uses
    cxCustomData;

    procedure TYour_Form.Your_ViewDataControllerSortingChanged(Sender: TObject);
    begin
    TcxCustomDataController(Sender).FocusedRowIndex := 0;
    end;

    ==============================================================================

    判断当前行是否第一行或最后一行

    可以使用DataController的IsBOF, IsEOF方法,或者:
    <AView>.Controller.Controller.FocusedRow.IsFirst
    <AView>.Controller.Controller.FocusedRow.IsLast

    ==============================================================================

    根据指定值查找记录

    DataController提供了好几个方法来得到指定值对应的RecordIndex
    对于Bound View可以使用FindRecordIndexByKeyValue方法

    ===============================================================================

    编辑和显示Blob字段

    该字段的Properties设置为BlobEdit,并将BlobPaintStyle 属性设为 bpsText

    ===============================================================================

    得到可见行数

    <View>.ViewInfo.VisibleRecordCount

    ===============================================================================

    保存后的行设置为当前行

    const
    CM_SETFOCUSEDRECORD = WM_USER + 1002;

    type
    TForm1 = class(TForm)
    cxGrid1DBTableView1: TcxGridDBTableView;
    cxGrid1Level1: TcxGridLevel;
    cxGrid1: TcxGrid;
    dxMemData1: TdxMemData;
    dxMemData1Field1: TStringField;
    dxMemData1Field2: TIntegerField;
    DataSource1: TDataSource;
    cxGrid1DBTableView1RecId: TcxGridDBColumn;
    cxGrid1DBTableView1Field1: TcxGridDBColumn;
    cxGrid1DBTableView1Field2: TcxGridDBColumn;
    Timer1: TTimer;
    CheckBox1: TCheckBox;
    procedure Timer1Timer(Sender: TObject);
    procedure dxMemData1AfterPost(DataSet: TDataSet);
    procedure CheckBox1Click(Sender: TObject);
    private
    procedure CMSetFocusedRecord(var Msg: TMessage); message CM_SETFOCUSEDRECORD;
    public
    { Public declarations }
    end;

    var
    Form1: TForm1;
    FocusedIdx: Integer;


    implementation

    {$R *.dfm}

    procedure TForm1.Timer1Timer(Sender: TObject);
    begin
    dxMemData1.AppendRecord(['', IntToStr(Random(1000)), Random(1000)]);
    end;

    procedure TForm1.dxMemData1AfterPost(DataSet: TDataSet);
    begin
    PostMessage(Handle, CM_SETFOCUSEDRECORD, Integer(cxGrid1DBTableView1), MakeLParam(cxGrid1DBTableView1.Controller.FocusedRowIndex, cxGrid1DBTableView1.Controller.TopRowIndex));
    end;

    procedure TForm1.CMSetFocusedRecord(var Msg: TMessage);
    begin
    TcxGridDBTableView(msg.WParam).Controller.FocusedRowIndex := Msg.LParamLo;
    TcxGridDBTableView(msg.WParam).Controller.TopRowIndex := Msg.LParamHi;
    end;

    procedure TForm1.CheckBox1Click(Sender: TObject);
    begin
    Timer1.Enabled := TCheckBox(Sender).Checked;
    end;

    end.

    =================================================================================

    删除记录并获得焦点

    procedure TForm1.BtnDeleteClick(Sender: TObject);
    var
    FocusedRow, TopRow: Integer;
    View: TcxGridTableView;
    DataController: TcxGridDataController;
    begin
    View := cxGrid1.FocusedView as TcxGridTableView;
    DataController := View.DataController;

    // Remember the top row (the vertical scrollbar position)
    TopRow := View.Controller.TopRowIndex;
    // Remember the focused row(!) index
    FocusedRow := DataController.FocusedRowIndex;

    DataController.DeleteFocused;

    // After deletion the same row must be focused,
    // although it will correspond to a different data record
    DataController.FocusedRowIndex := FocusedRow;
    // Restore the top row
    View.Controller.TopRowIndex := TopRow;
    end;

  • 相关阅读:
    【微信小程序】 自定义组件
    vue3中的组件通讯
    vue3如何使用watch监听
    windows server 2008中iis7中的php5.3出现 Server 内部错误500的解决
    在计算里面计算为什么要采用补码
    计算机里二进制与十进制互相转到到底是怎么完成的
    矩的概念、意义以及在SLAM中的应用
    VC++6.0 使用jsoncpp静态库解析json数据(亲测绝对可用)
    python等待用户输入并超时退出
    使用WTV工具箱检测有效电视源
  • 原文地址:https://www.cnblogs.com/hnxxcxg/p/2940946.html
Copyright © 2020-2023  润新知