I need to merge two column headers that are side-by-side into a single column header. How do I do that? I'd like the columns themselves to remain separate. I just want the header to look like a single header.
Hi Mike,
I'm trying to do the same thing using your sample code but I'm encountering an issue. Whenever the x-axis of the first column scrolls out of view, a grey space is shown in place of the second column header. I'm using 10.3 version of ultragrid.
Could you please provide me with a working sample project so I can see what I'm doing wrong? Any ideas as to what might be causing this?
Got it working. Thanks for all your help.
Mike,
It worked except I'm not getting the filter icon and though it shows the sort icon when I click on the header, it doesn't actually sort. Is there any way to get those working? I can probably live without it if it's a big deal to add.
Thanks for the help!
Pete
Hi,
The element should always have it's Rect set before the BeforeCreateChildElements fires. But I don't think the approach you took here is quite right, anyway. It's probably not a good idea to move the parent element.
Your code is also making the assumption that you wlil always be using the main column's HeaderUIElement, but that will not work if that column is scrolled out of view.
Here's a better way:
public class ColHeaderSpannerCreationFilter : IUIElementCreationFilter { private UltraGridColumn Column1 { get; set; } private UltraGridColumn Column2 { get; set; } public ColHeaderSpannerCreationFilter(UltraGridColumn column1, UltraGridColumn column2) { this.Column1 = column1; this.Column2 = column2; } public void AfterCreateChildElements(UIElement parent) { if (parent is BandHeadersUIElement) { HeaderUIElement headerElement1 = parent.GetDescendant(typeof(HeaderUIElement), this.Column1) as HeaderUIElement; HeaderUIElement headerElement2 = parent.GetDescendant(typeof(HeaderUIElement), this.Column2) as HeaderUIElement; // If boith of the elements are scrolled out of view, then do nothing. if (headerElement1 == null && headerElement2 == null) { return; } UIElement elementToExtend = headerElement1 != null ? headerElement1 : headerElement2; UIElement elementToRemove = headerElement1 != null ? headerElement2 : headerElement1; // Make one header element fill the space of both column headers. if (elementToRemove != null) { elementToExtend.Rect = Rectangle.Union(elementToExtend.Rect, elementToRemove.Rect); // Remove the other element parent.ChildElements.Remove(elementToRemove); } } } public bool BeforeCreateChildElements(UIElement parent) { //Return false to let the grid know we did not handle the event. return false; } }
This works pretty well, but there is a small problem when you scroll the column(s) out of view and then back into view, because the grid doesn't know it has to dirty both header elements. So you just have to tell the grid to dirty the headers when it scrolls. Like so:
private void ultraGrid1_BeforeColRegionScroll(object sender, BeforeColRegionScrollEventArgs e) { UltraGrid grid = (UltraGrid)sender; UIElement bandHeadersUIElement = grid.DisplayLayout.UIElement.GetDescendant(typeof(BandHeadersUIElement)); if (bandHeadersUIElement != null) bandHeadersUIElement.DirtyChildElements(true); }
Some additional notes. I tried creating a Rectangle property which I default to Rectangle.Empty and then calculate the rectangle only if it's empty. This seems to work for setting the size, but now my caption is missing, as are the filter and sort indicators.