Hi,
What is the best way (if there is any) to show pound signs instead of a number if a cell is not wide enough to display the whole formatted number? This is one of features in MS Excel. In order to do this, we need to be able to do at least the following tasks:
1) get the formatted number
2) get the font
3) get Graphics instance to call MeasureString on the formatted number with the font
4) get the width of the cell and it margins
Thanks,
Shaolin
Hi Shaolin,
Drawing borders for individual cells or rows is very difficult because the rows and cells overlap. So if you want to draw a border for a cell and another cell next to it, you will need to decide what to do - what color would the line between the cells be? My advice would be to highlight the cell in some other way, like using BackColor or ForeColor or even drawing a border that is entirely inside the cell in order to avoid the problem of overlapping. Another option would be to set CellSpacing on the grid to a small number like 2 so that cells no longer overlap and there is a gap in between.
Shaolin said:I noticed that both class UltraGridRow and UltraGridColumn have CellAppearance property and UltraGridRow has Appearance property. How are they used?
I'm not sure what you mean by this question. The CellAppearance on the Row or column determined the appearance of cells within that row or column. The Appearance on the row determines the appearance of the row itself.
Hi Mike,
It is much better now with your new solution. The only issue is those two Color columns and both values and pound signs are displayed at the same time for some of the cells. It seems that using draw filter is quite tricky and complicated. I tried to use this feature to row and cell borders and I have to draw them at phase DrawPhase.AfterDrawElement instead of DrawPhase.BeforeDrawBorders, otherwise parts of borders are covered by CellAppearance.BackColor of UltraGridColumn. The following is my code:
public virtual bool DrawElement(DrawPhase drawPhase, ref UIElementDrawParams drawParams) { switch (drawPhase) { //case DrawPhase.BeforeDrawBorders: case DrawPhase.AfterDrawElement: // have to draw borders at last, or they may be covered by cell background color if (drawParams.Element is RowCellAreaUIElement) { if (_drawRowBorders) drawParams.Graphics.DrawRectangle(_rowBorderPen, drawParams.ElementDrawingRect); if (_drawCellBorders) { var row = (RowCellAreaUIElement)drawParams.Element; foreach (var cell in row.ChildElements) drawParams.Graphics.DrawRectangle(_cellBorderPen, cell.DrawingRect); } return _drawRowBorders || _drawCellBorders; } break;
Can you tell me what is the correct way to draw cell border?
I noticed that both class UltraGridRow and UltraGridColumn have CellAppearance property and UltraGridRow has Appearance property. How are they used?
Ah, okay, I see it now. I took a new approach and used a DrawFilter instead of a CreationFilter and it works correctly now.
If you are interested in why the first problem occurred, it's because the UIElements for the cell are verified when the column is initially visible. When you scroll, the position of the UIElements changes, but the contents don't, so the cell essentially doesn't get into the CreationFilter when scrolling back to the left and so it just keeps the # signs.
So the cell doesn't have to go through the CreationFilter, but it does have to re-paint, so a CreationFilter works okay.
There are two caveats to this approach, though.
First, you have to turn off ScrollWindow (via the UseScrollWindow property). This property optimizes the grid scrolling, but it prevents the cell from painting every time when scrolling. So there's a slight performance cost here.
Second, we have to wait for the TextUIElement to draw the text and then erase the text and draw the # signs. You might notice that in my sample, the Color cells don't work correct. This is because the TextUIElement in those cells has a transparent background. So if you are using colors in your grid, you would have to work around this by either hard-coding the color for the background drawing or else getting the resolved background color of the cell and using that.
I played with the test app a little more and it is quite easy to reproduce what I reported. You press and hold down your mouse on the scroll box of the horizontal scroll bar and drag the scroll box to the far right and then slowly back to the left, all the strings and numbers will be displayed as pound signs as shown in the attached image.
I tried this out with Column 7 - which is the "Double 1" column. But I am still not seeing any problem. I tried scrolling the grid, resizing the column and every combination of those that I can think of. I am attaching the updated sample here.
I'm sure you are probably right. This was just a quick sample, so there are likely to be edge cases that the sample does not account for. But I need to be able to see the problem in order to help you figure out why it's not working. Can you tell me exactly how to reproduce the issue?