Hi,
I have two rows in the root collection of my grid. Due to some layout requirements I have to adjust the row height to the same row height as another grid has.
If I set the row height of grid.Rows[0] = 32, the row height of the second row also changes. The AfterRowResize-Event will only be called for the row I change the height, but the height of both rows has changed.
It looks like a bug, or do I something wrong here? The grid is bound to a UltraDataSource. I'm using version 11.1.2011.2030.
Regards
Markus
I have figured out something:
If I set RowSizing = Free on a band overrides, I can not change individual row height. If I set it to the whole grid it works:
e.Layout.Override.RowSizingArea = RowSizingArea.EntireRow;
e.Layout.Override.RowSizing = RowSizing.Free;
e.Layout.Override.CellMultiLine = DefaultableBoolean.True;
Setting at the global override, setting individual row height in band[0] or band[2] works, otherwise not.
This looks strange. Do I missunderstood something?
The setting on the Band Override should take precedence over the Layout Override. So if you are saying that setting RowSizing to Free on the Band Override does not allow you to set the height of a single row, then something is wrong.
I tried this out and it works fine for me either way. Both of these work.
private void ultraGrid1_InitializeLayout(object sender, Infragistics.Win.UltraWinGrid.InitializeLayoutEventArgs e) { UltraGridLayout layout = e.Layout; UltraGridBand band = layout.Bands[0]; band.Override.RowSizing = RowSizing.Free; }
private void ultraGrid1_InitializeLayout(object sender, Infragistics.Win.UltraWinGrid.InitializeLayoutEventArgs e) { UltraGridLayout layout = e.Layout; UltraGridOverride ov = layout.Override; ov.RowSizing = RowSizing.Free; }
Yes, I see how this might be very difficult to track down.
So just to make sure I understand, you want the rows in both grids to have their heights synchronized. Are you also synchronizing the scrolling the grids? If so, then another approach you might take is to use the UIElements of the grid. This would essentially size the rows every time the grid paints, but it would be limited to the rows that are in view, so it would be pretty fast. This approach will probably be very tricky if you are synchronizing in both directions, though. You would need some kind of anti-recursion flag.
The basic idea would be to create a CreationFilter for your grid and trap AfterCreateChildElements. You would watch for when the 'parent' parameter is a RowUIlement. From there, you could get the row and use the height of the RowUIElement to adjust the corresponding row in the other grid.
I whipped up a very quick, simple example of using the CreationFilter approach. As I mentioned, this approach will not work unless the scrolling and the height of both grid is also synchronized.
I just have to sync in one direction, but sync two grids if users switch on all application features.
At the moment I not sure which approach is best for me. The case of showing a additional column, I can handle like discussed so far, because this event happens once if users click a feature. Dealing with UIElements sounds tricky and would be my last choice. Thanks for your sample, I will check.
The AfterCellActivate-case is bad because users can select block of cells and this event is fired every time the active cell is changing (even for the same row). I have lots of requirements in that grid, one is that back- and forecolor reflecting some status of the data. Therefore I have to change the color, because the state should be visible for the active as well. That seems to be somewhat against the grids appearance philosophy.
Ihave not tried so far changeing the color of a particular band instead of the Override. Maybe rows get not resized?
Do I have any chance to enable the RowAfterResize-event in the EventManager to be fired not only if the user resized a row?
Hello Mike,
If the active cell backcolor is set referencing the band, rows are not resized!
this.GridStandard.DisplayLayout.Bands[1].Override.ActiveCellAppearance.BackColor = this.GridStandard.ActiveCell.Appearance.BackColor != Color.Empty ? this.GridStandard.ActiveCell.Appearance.BackColor : Color.White;
While playing around, I also have tried generally switch off, the active cell appearance and only work with selected cell appearance. The selected cell appearance is applied in second priority to a cell (active cell -> selected cell -> other cells).
Setting the selected cell border color, the color only affects the left and down border. How I can configure the grid to set all borders of the selected cell (same as for active cell). Do I need a DrawFilter for that? If yes, can you provide a example to achieve this?
I have modified a draw filter sample. Please check my code below: For drawing the top border, I have to deflate the rectangle. Somewhat seems overpaint my borders even if I use the DrawPhase.AfterDrawElement. Furthermore the most right border looks not drawed (see attached pic).
Condition: The all side borders should only be applied to selected cells, skipping the active cell. The active cell is configured with black border and thickness = 3.
Suppressing the focus rect was the draw filter I was using so far and should still alive.
bool IUIElementDrawFilter.DrawElement( DrawPhase drawPhase, ref UIElementDrawParams drawParams ) { if ( drawParams.DrawPhase == DrawPhase.AfterDrawElement ) { CellUIElement cellUIElement = drawParams.Element as CellUIElement; if ( null == cellUIElement ) return false; // nur selektierte, aber nicht aktive Zelle if ( !cellUIElement.Cell.Selected || cellUIElement.Cell.IsActiveCell ) return false; // Draw the borders Rectangle rect = new Rectangle( cellUIElement.Rect.X+1, cellUIElement.Rect.Y+1, cellUIElement.Rect.Width-1, cellUIElement.Rect.Height-1 ); drawParams.DrawBorders( cellUIElement.BorderStyle, Border3DSide.All, Color.Black, Color.Black, rect, drawParams.ElementDrawingClipRect ); // Return true (no default drawing) return true; } if ( drawParams.DrawPhase == DrawPhase.BeforeDrawFocus ) { return true; } return false; } DrawPhase IUIElementDrawFilter.GetPhasesToFilter( ref UIElementDrawParams drawParams ) { return DrawPhase.BeforeDrawFocus | DrawPhase.BeforeDrawBorders | DrawPhase.AfterDrawElement; }
Regards, Markus
Hi Markus,
I've been out sick for a few days, so I'm just catching up. I'm a little lost. :)
Drawing borders on a single cell will be extremely difficult because any one cell doesn't draw all four border sides. It usually only draws one or two borders and then relies on the adjacent objects to draw theirs.
If you want to highlight the the ActiveCell, then there are already properties in the grid that will do this for you.
private void ultraGrid1_InitializeLayout(object sender, Infragistics.Win.UltraWinGrid.InitializeLayoutEventArgs e) { UltraGridLayout layout = e.Layout; UltraGridOverride ov = layout.Override; ov.ActiveCellBorderThickness = 5; ov.ActiveCellAppearance.BorderColor = Color.Red; }
If it's not the active cell, then this will be much more difficult. What you would have to do is use the DrawFilter, but draw over the element that contains the cells and rows. You can't use the CellUIElement, even in AfterDrawElement, because that only means after that particular element is drawn. There's no way to be sure some other element isn't drawing overlapping it.
Personally, I would advise against this approach. There are lot of complications like what happens if the cell is cut off by the edge of the control, or if you are using fixed columns.
If you need just one cell, the easiest thing to do is make it the ActiveCell and use the code above to apply the border.
Another option would be to prevent the cells in the grid from overlapping. You could do that by setting:
e.Layout.Override.CellSpacing = 1;
This, of course, creates padding around every cell, which you probably don't want, but it does make the borders a lot simpler.
Or, just highlight the cells in some other way with an image, BackColor, or ForeColor.