Embed Any Control with UltraControlContainerEditor does not work for Image column

382 views Asked by At

I want to display a picture in another scaling mode in an UltraGridCell. The mode should scale the image to the cell height and clip the rest of the image from the right to fit into the cell. This is easy if I could just draw it myself as the EmbeddableImageRenderer does not allow me to set its scaling behaviour (I am not talking about MaintainAspectRatio as I still want to maintain the aspect ratio).

I tried it with the tutorial to embed any control in a cell. And it is working fine with the given example of a TrackBar (and in my tiny testing project also with a ProgressBar as RendererControl). But it appears not to work with columns that are displaying images.

As a DataSource I have a list of my own class with an Image property which is displayed in the grid. As Editor-/RendererControl I set two regular PictureBoxes.

Any suggestions to solve the main problem of scaling the image or to set any control to the picture column (that would then deal with the scaling)?

1

There are 1 answers

1
Mike On

I can't see any reason why the UltraControlContainerEditor shouldn't work with an image column, provided that the control you are using has a property that takes an Image and that you specify the correct PropertyName on the editor. But that's probably not the most efficient approach, anyway.

A better approach would be to use a DrawFilter to draw the image yourself.

public class ImageScalingDrawFilter : IUIElementDrawFilter
{
    bool IUIElementDrawFilter.DrawElement(DrawPhase drawPhase, ref UIElementDrawParams drawParams)
    {
        switch (drawPhase)
        {
            case DrawPhase.BeforeDrawImage:

                ImageUIElement imageElement = (ImageUIElement)drawParams.Element;
                Image image = imageElement.Image;                    

                int availableHeight = drawParams.Element.RectInsideBorders.Height;
                float ratio = (float)availableHeight / (float)image.Height;

                float newHeight = image.Height * ratio;
                float newWidth = image.Width * ratio;

                Rectangle rect = new Rectangle(
                    imageElement.Rect.X,
                    imageElement.Rect.Y,
                    (int)(newWidth),
                    (int)(newHeight)

                    );

                // Draw the scaled image.
                drawParams.Graphics.DrawImage(image, rect);

                // This tells the grid not to draw the image (since we've already drawn it). 
                return true;
        }

        return false;
    }

    DrawPhase IUIElementDrawFilter.GetPhasesToFilter(ref UIElementDrawParams drawParams)
    {
        UIElement element = drawParams.Element;
        // Look for an ImageUIElement
        if (element is ImageUIElement)
        {
            // Presumably, we only want to this images in cells
            // and not every image in the entire grid, so make sure it's in a cell.
            CellUIElement cellElement = element.GetAncestor(typeof(CellUIElement)) as CellUIElement;
            if (null != cellElement)
            {
                // We could also limit this to a particular column or columns.
                switch (cellElement.Cell.Column.Key)
                {
                    case "Image":
                        return DrawPhase.BeforeDrawImage;
                }
            }
        }

        return DrawPhase.None;
    }
}

You assign the DrawFilter to the grid like so:

    private void Form1_Load(object sender, EventArgs e)
    {
        this.ultraGrid1.DrawFilter = new ImageScalingDrawFilter();
    }