1

在桌面应用程序上工作,遇到一个可能很愚蠢的问题,仍然让我发疯。

我有一个从动态源获取其行的列表框。

如果该单元格的基础数据更改为特定条件,我正在尝试更改控件中特定单元格的前景色。

在开始检查条件之前,控件也会被绘制一次,这意味着每个单元格都开始使用相同的(白色)前景色绘制。

此外,此列表框位于 Canvas 内,而 Canvas 又位于 Window 控件内。

此代码检查条件与列表框中的所有行:

for each dict as Dictionary in WidgetsDictionary
  Dim site as String = dict.Value("Site").StringValue
  Dim device as String = dict.Value("Device").StringValue
  Dim sensor as String = dict.Value("Sensor").StringValue
  for intC as integer = 0 to actualLstBox.ListCount
    Dim siteComp as String = actualLstBox.Cell(intC,4) 
    Dim deviceComp as String = actualLstBox.Cell(intC,0) 
    Dim sensorComp as String = actualLstBox.Cell(intC,1) 
    if  actualLstBox.Cell(intC,4) = site    AND
        actualLstBox.Cell(intC,1) = sensor  AND
        actualLstBox.Cell(intC,0) = device then
      actualLstBox.CellTag(intC,2) = RGB(255, 192, 203) 
      exit For
    end
  next
next

其中 WidgetsDictionary 包含我需要检查的条件。

这很有效,如果我在运行后检查 CellTags,我会发现它们正确设置在它们应该在的位置。

现在,如果在那个代码之后我打电话

actualLstBox.Refresh()

注意:我知道 Refresh 不是最佳选择,但我需要它尽快触发

我看到代码跳转到 ListBox 的 CellBackgroundPaint 事件

我有这个

If (row<me.ListCount ) then
  If Me.CellTag(row, column ) <>nil Then
    g.ForeColor = me.CellTag(row,column)
    g.FillRect(0, 0, g.Width, g.Height)
  End If
end

再一次,我看到这段代码正确执行。

所以,我希望用新颜色的正确单元格重新绘制列表。

但是没有任何改变,我看到每次刷新后都会触发 CellBackgroundPaint 事件,但显示的最终结果始终是默认(白色)彩色单元格。

我试过打电话,按顺序

  • 特定单元格上的 InvalidateCell
  • 使整个列表框无效而不是刷新(因为你永远不知道)
  • 在包含的 Canvas 上刷新

在第一块代码之后,无济于事。

所以现在我不知道下一步该尝试什么。

编辑

如果我将事件处理程序替换为

If (row mod 2) = 0 Then
  g.ForeColor = RGB(232,235,255) 
  g.FillRect 0, 0, g.Width, g.Height
End If

if column = 2 then
  g.ForeColor = RGB(255,253,208) 
  g.FillRect 0, 0, g.Width, g.Height
end

我得到不同颜色的行和整个第三列的交替颜色。

所以我想我在第一次显示后尝试重新粉刷它的事实就是问题所在。

4

1 回答 1

2

You need to return true from the handler in order to tell Xojo that you already have do e the painting. Otherwise Xojo will do its own FillRect after yours.

Keep in mind that this will also override the selection coloring. Meaning that if the row is selected, your cell won't show that unless you either return false in that case or draw your own special bg color for that case.

Also, what you are talking about is the background color, not foreground color, it seems to me. You could perhaps update your question title accordingly.

于 2019-06-11T11:58:46.853 回答