2

我的程序处于发布后状态,所以请多多包涵。

设想

我的程序基于办公数据管理系统(面向车辆维护)的不同功能的不同页面的多种布局。这些功能的一个主要类别显然是数据输入。我使用不同的风格来适应不同的受众。

言归正传,其中一个界面具有 excel 样式的网格和 3 个用于打印/保存/重置功能的按钮。我使用 FastReports 打印表单。

我正在为网格列开发一个自定义类,以使它们适应预定义的控件列表而不是动态的单元格,但现在我只是在代码中创建了所需的单元格子控件。

该页面有 3 个部分(布局);

  • 顶部是一种特定于所有页面的目的(添加/修改/添加部分)选择器,在不需要的地方可能不可见。

  • 中间一个是一个控件,用于接收要修改的表单的收据编号,它们的信息嵌入到其他表单中等。它主要在每一页上,但不是全部。

  • 最后一个具有页面内容,即前面提到的网格和 3 个按钮。

代码

这是用于显示其中一个有问题的页面的代码片段。它在所有数据处理完成并且服务器 OK 转换时执行。

传奇

  • AState : 状态机状态变量;表示显示页面的当前状态。

  • AMode : 状态机状态枚举器;表示整个应用程序的模式,例如预订(数据输入)等。我跳过了涉及此的代码,因为它在 AState 转换期间被跳过以发生此问题。

  • fMode:与上面相同,但它是表单的主要字段。

  • UI_CA_Controls1:包含预订模式的目的选择器(组合列表框)的布局。

  • EV_Mode:为方便起见的变量;它存储目的选择器的项目索引。

  • UI_CA_Grid:包含在 UI_CA_Content 中的布局本身包含 UI_CA_FieldGrid (TGrid)。

  • fEditColumn:具有 TEdits 的网格的第二列。

  • fGridDataset:网格关联的 TStringList。

//

procedure TUI.SetFormState ( AState : Byte; AMode : TMode = UIM_Unselected );
var
  EV_Mode, I : Byte;

begin

  
  // ---------------------------------------------------------------------------

  fFormState          := AState;

  // The children of the grid cells
  
  fCalEdit1.Parent    := nil; // Calender Edits
  fCalEdit2.Parent    := nil;
  fVehicleClass.Parent := nil; // Combo List Boxes
  fEmployee1.Parent   := nil;
  fEmployee2.Parent   := nil;
  fEmployee3.Parent   := nil;
  fEmployee4.Parent   := nil;

  // ---------------------------------------------------------------------------

  if AState = 0 then
  begin
  
    for I := 0 to 20 do
      DPCM.fGridDataset.Strings [I] := ''; // The Grid Associated TStringList

    UI_CA_ReceiptNo.ReadOnly  := False;
    UI_CA_ReceiptNo.Text      := '';

  end;

  // ---------------------------------------------------------------------------

  UI_CA_Content.BeginUpdate;

  case fMode of

    // Skipped unrelated modes

    UIM_Booking :
    begin

      UI_CA_Controls1.Visible := True;
      EV_Mode := UI_CA_EV_ModeSelect.ItemIndex;

      // -----------------------------------------------------------------------

      if fFormState = 0 then
      begin

        // Skipped handling of other EV_Mode values

        if EV_Mode < 7 then
        begin

          UI_CA_ReceiptControl.Visible  := True;
          UI_CA_Content.Visible         := False;

        end;

      end

      // -----------------------------------------------------------------------

      else if fFormState = 1 then // The problematic area
      begin

        if ( EV_Mode = 3 ) or ( EV_Mode = 4 ) then
        begin

          UI_CA_FieldGrid.RowCount := 6;
          UI_CA_Grid.Height        := 160;

          fCalEdit1.Parent        := fEditColumn.CellControlByRow ( 0 );
          fCalEdit1.Date          := Date;
          fCalEdit2.Parent        := nil;
          fVehicleClass.Parent    := fEditColumn.CellControlByRow ( 2 );
          fVehicleClass.ItemIndex := 0;

        end;
    
        UI_CA_Content.Visible := True;

      end;

    end;

    // -------------------------------------------------------------------------

  end;

  // ---------------------------------------------------------------------------
  // Workaround 1
  
  if UI_CA_Content.Visible then
  begin

    UI_CA_FieldGrid.UpdateColumns;
    UI_CA_Content.EndUpdate;
    UI_CA_FieldGrid.SetFocus;
    UI_CA_C2_Reset.SetFocus;
    UI_CA_C2_Print.SetFocus;
    UI_CA_C2_Save.SetFocus; 
    UI_CA_FieldGrid.SetFocus;

  end
  else UI_CA_Content.EndUpdate; 

end;

问题

问题是,无论何时显示收据部分,内容部分都不会在现场显示。行为是这样的,当我将鼠标悬停在应该显示这些子控件和 3 个按钮的位置时,当我单击它时才显示网格。

这个问题本身就出现了,UI 代码没有变化,这让我困惑了 3 天。我只对网络端的协议和数据处理(独立数据模块)进行了优化。

序列

  • 用户想要修改已经预订的车辆数据。

  • 用户输入预订收据编号。(AState = 0,AMode = UIM_Booking)

  • 客户端查询的服务器和服务器回复完整的数据集(如果存在)。

  • 客户端获取数据并将其复制到 Grid 关联的 TStringlist 和子字段的字符串中。

  • 客户端不显示带有数据和 3 个按钮的网格。(AState = 1,AMode = UIM_Booking)

到目前为止我尝试了什么

  • 使用了 BeginUpdate/EndUpdate,这使得对齐工件变得更糟。

  • 在网格和按钮上使用 SetFocus 会导致其中一些随机显示,有时会完整显示,但并非每次都显示。

  • 使用 Application.ProcessMessages 没有任何变化,而不是 UI 线程有时只是卡在其中永远不会返回。在单独的线程中使用它,每秒调用一次,没有任何变化。

  • 为该方法使用了单独的线程,但问题更多。

  • 回溯和恢复旧的工作代码,没有任何变化(让我很生气)。

  • 更新 1:我试图使网格不可见,然后在代码末尾可见。现在网格的一些单元格随机显示。

解决方法 1

  • 当为它们中的每一个调用 SetFocus 方法时,可以显示网格和按钮。
  • 按钮的调用顺序是不稳定的。就像我必须先调用重置然后打印并保存 SetFocus 方法,否则只有其中一个被显示。
  • 有一个瞬间的重新对齐故障,显示控件正在调整大小,但我认为这是可以忽略的。

解决方法 2

因此,如果你们有任何建议,我将不胜感激。

4

0 回答 0