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,
Measuring the test yourself will be extremely difficult. But there might be an easier way. The grid and it's editors already keep track of whether or not the text fits inside the cell. They do this so the grid knows whether or not it's appropriate to show a tooltip.
So you could probably make use of that and then use a CreationFilter in order to change the Text of the cell to whatever you want without affecting the cell's value.
I decided to try to whip up a quick sample and it turned out to be surprisingly easy. My sample is attached here.
Hi Mike,
Thanks for your quick response and solution!
I tested your solution. Method IsTextFullyVisible is not always accurate.
Regards,
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?
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.
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.
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?
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.
The way it works is that the more specific appearance takes precedence over the more general appearance. So the appearance on the Cell (cell.Appearance) would apply the BackColor Yellow in your example.
There are appearances at many different levels in the grid, and many of the other Infragistics Winforms controls do the same thing.
The cell appearances can be affected by many different appearances: the cell, the Column, the Row, the Override (which is on the band and the layout). So this allows you to set appearances at a very broad level and also override those appearances for more specific objects within the larger set.
What is the background color for a cell if the background color of its row's Appearance is Red, Yellow of row's CellAppearance and Green of column's Appearance? What UltraGridCell's Appearance and how I can change it?
I am in a process to choose a Grid control for our projects. I might have asked improper questions. Thanks for your patience!