using System; using System.Collections.Generic; using System.Text; using Infragistics.Win.UltraWinGrid; using System.Drawing; using Infragistics.Win; using System.Windows.Forms; using System.ComponentModel; namespace McFramework.McGUIHelper { public class McUltraGrid : UltraGrid { protected bool _autoSize = false; protected Size _originalSize = Size.Empty; public McUltraGrid() { this.AutoSize = true; } protected override void OnEndInit() { base.OnEndInit(); _originalSize = this.Size; } public override bool AutoSize { get { return _autoSize; } set { _autoSize = value; } } protected override void OnInitializeLayout(InitializeLayoutEventArgs e) { base.OnInitializeLayout(e); // Fires when we bind to a DataSource if (this.DataSource is IBindingList) { ((IBindingList)this.DataSource).ListChanged += new ListChangedEventHandler(McUltraGrid_ListChanged); } } void McUltraGrid_ListChanged(object sender, ListChangedEventArgs e) { //T.WF(this, "ListChanged: {0}", e.ListChangedType); this.Height = GetMaxGridHeight(); } protected override void OnAfterRowCollapsed(RowEventArgs e) { base.OnAfterRowCollapsed(e); this.Height = GetMaxGridHeight(); } protected override void OnAfterRowExpanded(RowEventArgs e) { base.OnAfterRowExpanded(e); this.Height = GetMaxGridHeight(); } protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified) { Size preferred = this.GetPreferredSize(Size.Empty); base.SetBoundsCore(x, y, width, preferred.Height, specified); } public override System.Drawing.Size GetPreferredSize(System.Drawing.Size proposedSize) { return this.ComputePreferredSize(proposedSize); } protected Size ComputePreferredSize(Size proposedSize) { int width = proposedSize.Width; int height = proposedSize.Height; try { height = this.GetMaxGridHeight(); if (height < _originalSize.Height) height = _originalSize.Height; }catch( Exception ex ) { T.WF(this,"Exception trying to GetMaxGridHeight: {0}", ex); } return new Size(width, height); } protected int GetMaxGridHeight() { int suggHeight=0; if (this.DisplayLayout.Bands[0].CardView) suggHeight = GetMaxGridHeightCardMode(); else suggHeight = GetMaxGridHeightRowMode(); suggHeight = suggHeight + this.Margin.Vertical; return suggHeight; } protected int GetMaxGridHeightCardMode() { int suggHeight = 0; if (this.Rows.Count > 0) { this.ControlUIElement.VerifyChildElements(); if (this.ControlUIElement.ChildElements.Count > 0) { DataAreaUIElement daui = this.ControlUIElement.ChildElements[0] as DataAreaUIElement; RowColRegionIntersectionUIElement rowcol = daui.ChildElements[0] as RowColRegionIntersectionUIElement; if (rowcol.ChildElements.Count > 0) { CardAreaUIElement cardUI = rowcol.ChildElements[0] as CardAreaUIElement; CardAreaScrollRegionUIElement cardAreaScroll = null; foreach (UIElement cardElement in cardUI.ChildElements) { if (cardElement is CardAreaScrollRegionUIElement) { cardAreaScroll = cardElement as CardAreaScrollRegionUIElement; break; } } RowUIElement rowUiElement = null; foreach (UIElement cardAreaScrollElement in cardAreaScroll.ChildElements) { if (cardAreaScrollElement is RowUIElement) { rowUiElement = cardAreaScrollElement as RowUIElement; break; } } suggHeight = rowUiElement.Rect.Height; } } } return suggHeight; } /// /// TODO: make a stack based tree walker, add up rows in any number of bands. /// /// protected int FindRowCount() { int rowCount = 0; foreach(UltraGridRow row in this.Rows) { if (row.IsGroupByRow) { foreach(UltraGridChildBand band in row.ChildBands) { rowCount += band.Rows.Count; } }else{ rowCount++; } } return rowCount; } protected int GetMaxGridHeightRowMode() { int visibleRowsHeightTotal = 0; int visibleRows = 0; int nonRowHeightTotal = 0; // bands, headers, footers. int clippedRows = 0; int nonclippedRows = 0; int collapsedRows = 0; int totalRows = (this.DataSource as BindingSource).Count; int avgRowHeight = 21; // Avg row height -- Initial is a guess // Design time fake rows. if (this.DesignMode) totalRows = FindRowCount(); if (totalRows == 0) return avgRowHeight; this.ControlUIElement.VerifyChildElements(); if (this.ControlUIElement.ChildElements.Count > 0) { DataAreaUIElement daui = this.ControlUIElement.ChildElements[0] as DataAreaUIElement; if (daui != null && daui.ChildElements != null) { foreach (UIElement daElement in daui.ChildElements) { if (daElement is ColScrollbarUIElement) { nonRowHeightTotal += daElement.Rect.Height; } if (daElement is RowColRegionIntersectionUIElement) { RowColRegionIntersectionUIElement rowcol = daElement as RowColRegionIntersectionUIElement; foreach (UIElement element in rowcol.ChildElements) { if (element is RowUIElement) { RowUIElement rowUI = (element as RowUIElement); if (rowUI.IsFullyVisible) { visibleRows++; visibleRowsHeightTotal += element.Rect.Height; } } else { // Test for oblong elements, ignore them (like GroupByRowConnectorUIElement, it's height is redundant). if (element is GroupByRowConnectorUIElement) { // skip } else if (element is GroupByRowUIElement) { nonRowHeightTotal += element.Rect.Height; GroupByRowUIElement groupBy = (element as GroupByRowUIElement); if (!groupBy.GroupByRow.Expanded) { collapsedRows += groupBy.GroupByRow.Rows.Count; } } else { nonRowHeightTotal += element.Rect.Height; } } } } } } } if (this.Rows.Count > 0) avgRowHeight = this.Rows[0].Height; if (visibleRows > 0) avgRowHeight = (visibleRowsHeightTotal / visibleRows); // In design time, TotalRows could be less than collapsed rows. // The 'total' rows can be 1 (1 band) and it has 2 collapsed rows. /* if (totalRows > collapsedRows) clippedRows = totalRows - collapsedRows; else clippedRows = collapsedRows; */ nonclippedRows = visibleRows + collapsedRows; clippedRows = (totalRows - nonclippedRows); //clippedRows = // Suggest height is (nonRowHeight + (All Rows * Avg Row Height)) int suggHeight = (nonRowHeightTotal + visibleRowsHeightTotal + (clippedRows * avgRowHeight)); return suggHeight; } } }