我最终创建了以下自定义网格单元格渲染器,以完全控制边框的绘制方式:
class CellBorderRenderer : public wxGridCellNumberRenderer
{
public:
CellBorderRenderer(const wxPen& top=*wxBLACK_PEN, const wxPen& right=*wxBLACK_PEN,
const wxPen& bottom=*wxBLACK_PEN, const wxPen& left=*wxBLACK_PEN,
bool hideSelection=false)
: pen_({top, right, bottom, left}), hideSelection_(hideSelection)
{
}
void Draw(wxGrid &grid, wxGridCellAttr &attr, wxDC &dc, const wxRect &rect,
int row, int col, bool isSelected) override
{
attr.SetAlignment(wxALIGN_CENTER, wxALIGN_CENTER);
wxGridCellNumberRenderer::Draw(grid, attr, dc, rect, row, col, hideSelection_ ? false : isSelected);
std::array<wxPoint, 5> points{rect.GetTopLeft(), rect.GetTopRight(),
rect.GetBottomRight(), rect.GetBottomLeft(),
rect.GetTopLeft()};
for (unsigned i = 0; i < pen_.size(); ++i)
{
dc.SetPen(pen_[i]);
dc.DrawLine(points[i], points[i+1]);
}
}
private:
std::array<wxPen, 4> pen_{*wxBLACK_PEN, *wxBLACK_PEN, *wxBLACK_PEN, *wxBLACK_PEN};
bool hideSelection_{false};
};
然后我禁用了网格线并将此类的一个实例传递给每个单元格,如下所示:
const auto thickBlackPen = wxPen(*wxBLACK, this->FromDIP(2));
for (int r = 0; r < mygrid->GetNumberRows(); ++r)
{
for (int c = 0; c < mygrid->GetNumberCols(); ++c)
{
wxPen topPen{*wxLIGHT_GREY_PEN}, rightPen{*wxLIGHT_GREY_PEN}, bottomPen{*wxLIGHT_GREY_PEN}, leftPen{*wxLIGHT_GREY_PEN};
bool hideSelection = false;
if (c % 3 == 0) // 3x3 subgrid boxes have thick border
{
rightPen = thickBlackPen;
}
if (r % 3 == 0) // 3x3 subgrid boxes have thick border
{
bottomPen = thickBlackPen;
}
mygrid->SetCellRenderer(r, c, new CellBorderRenderer(topPen, rightPen, bottomPen, leftPen, hideSelection));
}
}
在这个(简化的)示例中,每三列和三行会有一条较粗的黑线。这当然可以适应任何其他类型的边框模式。