This is a migrated thread and some comments may be shown as answers.

Show mulitple images in a gridview column

15 Answers 689 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Alcatraz
Top achievements
Rank 1
Alcatraz asked on 19 Apr 2010, 03:21 PM

hi ,

I have a requirement where in I got to show two or more images inside a single grid column.  Pls advise how to achieve the same.

Pls find the attachment containing the sample image of the grid.

thanks
Krishnan N

15 Answers, 1 is accepted

Sort by
0
Accepted
Svett
Telerik team
answered on 21 Apr 2010, 02:30 PM
Hello KrisYs,

You can achieve that behavior by creating a custom cell which contains the desired images. You can use the following code snippet as basic implementation of your scenario:

public class CustomGridDataCell : GridDataCellElement
    {
        private StackLayoutPanel panel = null;
 
        public CustomGridDataCell(GridViewColumn column, GridRowElement row)
            : base(column, row)
        {
 
        }
 
        protected override void CreateChildElements()
        {
            base.CreateChildElements();
            this.panel = new StackLayoutPanel();
            this.panel.Orientation = Orientation.Horizontal;
            this.panel.StretchHorizontally = true;
            this.panel.StretchVertically = true;
 
            RadButtonElement buttonOne = new RadButtonElement();
            buttonOne.StretchVertically = true;
            buttonOne.StretchHorizontally = true;
            this.Children.Add(buttonOne);
            RadButtonElement buttonTwo = new RadButtonElement();
            buttonTwo.StretchVertically = true;
            buttonTwo.StretchHorizontally = true;
            this.Children.Add(buttonTwo);
            RadButtonElement buttonThree = new RadButtonElement();
            buttonThree.StretchVertically = true;
            buttonThree.StretchHorizontally = true;
            this.Children.Add(buttonThree);
        }
 
 
        public override bool IsEditable
        {
            get { return false; }
        }
 
        protected override SizeF ArrangeOverride(SizeF finalSize)
        {
            RectangleF clientRect = this.GetClientRectangle(finalSize);
            float buttonWidth = clientRect.Size.Width / this.Children.Count;
            RectangleF buttonFinalRect = new RectangleF(clientRect.Location, new SizeF(buttonWidth, clientRect.Height));
 
            foreach (RadButtonElement button in this.Children)
            {
                button.Arrange(buttonFinalRect);
                buttonFinalRect = new RectangleF(new PointF(buttonFinalRect.X + buttonWidth, buttonFinalRect.Y), buttonFinalRect.Size);
            }
 
            return finalSize;
        }
    }

You need only to set the desired images for each of the buttons. I recommend you to create a command column. Hence, you need to replace its default cells with the custom one:

GridViewCommandColumn commandColumn = new GridViewCommandColumn("Actions");
this.radGridView.Columns.Add(commandColumn);

private void radGridView_CreateCell(object sender, GridViewCreateCellEventArgs e)
{
    GridViewCommandColumn dataColumn = e.Column as GridViewCommandColumn;
 
    if (e.Row is GridDataRowElement && dataColumn != null)
    {
        e.CellType = typeof(CustomGridDataCell);
    }
}

If you need further assistance do not hesitate to write us back.

Regards,
Svett
the Telerik team

Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
0
Alquin Cook
Top achievements
Rank 1
answered on 19 May 2010, 03:43 PM
Hello,

I have a cell that must have multiple images. I followed your example above and it worked like a charm, but I can't get the command click event to fire when one of the images (buttons) is clicked. Do you have a code sample that will fire the grid Command Cell Click event?

thanks
0
Svett
Telerik team
answered on 20 May 2010, 04:50 PM
Hello Alquin Cook,

I have added a ButtonClick event to the custom cell. Therefore, you can handle it where you can execute the desired operation:

public class CustomGridDataCell : GridDataCellElement
{
    private StackLayoutPanel panel = null;
    private RadButtonElement buttonOne = null;
    private RadButtonElement buttonTwo = null;
    private RadButtonElement buttonThree = null;
 
    public event EventHandler ButtonClick;
 
    public CustomGridDataCell(GridViewColumn column, GridRowElement row)
        : base(column, row)
    {
 
    }
 
    public RadButtonElement ButtonOne
    {
        get { return this.buttonOne; }
    }
 
    public RadButtonElement ButtonTwo
    {
        get { return this.buttonTwo; }
    }
 
    public RadButtonElement ButtonThree
    {
        get { return this.buttonThree; }
    }
 
    protected override void CreateChildElements()
    {
        base.CreateChildElements();
        this.panel = new StackLayoutPanel();
        this.panel.Orientation = System.Windows.Forms.Orientation.Horizontal;
        this.panel.StretchHorizontally = true;
        this.panel.StretchVertically = true;
 
        buttonOne = new RadButtonElement();
        buttonOne.Click += new EventHandler(Button_Click);
        buttonOne.StretchVertically = true;
        buttonOne.StretchHorizontally = true;
        this.Children.Add(buttonOne);
 
        buttonTwo = new RadButtonElement();
        buttonTwo.Click += new EventHandler(Button_Click);
        buttonTwo.StretchVertically = true;
        buttonTwo.StretchHorizontally = true;
        this.Children.Add(buttonTwo);
 
        buttonThree = new RadButtonElement();
        buttonThree.Click += new EventHandler(Button_Click);
        buttonThree.StretchVertically = true;
        buttonThree.StretchHorizontally = true;
        this.Children.Add(buttonThree);
    }
 
    private void Button_Click(object sender, EventArgs e)
    {
        this.OnButtonClick(sender, e);
    }
 
    public override bool IsEditable
    {
        get { return false; }
    }
 
    protected virtual void OnButtonClick(object sender, EventArgs e)
    {
        if (this.ButtonClick != null)
        {
            this.ButtonClick(sender, e);
        }
    }
 
    protected override SizeF ArrangeOverride(SizeF finalSize)
    {
        RectangleF clientRect = this.GetClientRectangle(finalSize);
        float buttonWidth = clientRect.Size.Width / this.Children.Count;
        RectangleF buttonFinalRect = new RectangleF(clientRect.Location, new SizeF(buttonWidth, clientRect.Height));
 
        foreach (RadButtonElement button in this.Children)
        {
            button.Arrange(buttonFinalRect);
            buttonFinalRect = new RectangleF(new PointF(buttonFinalRect.X + buttonWidth, buttonFinalRect.Y), buttonFinalRect.Size);
        }
 
        return finalSize;
    }
}

You can subscribe for the event by using the following code snippet:

void radGridView_CreateCell(object sender, GridViewCreateCellEventArgs e)
{
    GridViewCommandColumn dataColumn = e.Column as GridViewCommandColumn;
 
    if (e.Row is GridDataRowElement && dataColumn != null)
    {
        CustomGridDataCell cell = new CustomGridDataCell(e.Column, e.Row);
        e.CellElement = cell;
        cell.ButtonClick += new EventHandler(cell_ButtonClick);
    }
}
 
private void cell_ButtonClick(object sender, EventArgs e)
{
    RadButtonElement button = sender as RadButtonElement;
    CustomGridDataCell cell = button.Parent as CustomGridDataCell;
 
    if (button == cell.ButtonOne)
    {
        // TO DO:
    }
    else if (button == cell.ButtonTwo)
    {
        // TO DO:
    }
    else if (button == cell.ButtonThree)
    {
        // TO DO:
    }
}

All the best,
Svett
the Telerik team

Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
0
John
Top achievements
Rank 1
answered on 12 Jul 2011, 12:59 AM
I have a similar requirement but the number of buttons I need in the cell depends on the state of the dataitem for the row.  I don;t seem to be able to get to the bound item in the CreateChildElements() method.  How would I accomplish this - other than creating every possible button needed and then hiding it based on an evaluation in the grids CellFormatting event?

Thanks in advance!
0
Svett
Telerik team
answered on 12 Jul 2011, 12:53 PM
Hello John,

You can create the button in the CreateChildElement method of GridDataCellElement class. Then you can manage its states in the UpdateInfo method, where you can access the DataBoundItem of the row:

public class MyCellElement: GridCellElement
{
    public override void UpdateInfo()
    {
        base.UpdateInfo();
 
        // TO DO: You update logic here
    }
}

I hope this helps.

All the best,
Svett
the Telerik team

Register for the Q2 2011 What's New Webinar Week. Mark your calendar for the week starting July 18th and book your seat for a walk through of all the exciting stuff we will ship with the new release!

0
Michelle
Top achievements
Rank 1
answered on 03 Sep 2013, 06:56 AM
Thank you for this thread as it provides a solution the problem I was looking for.

However, the code samples above disable HotTracking for the cells that use the inherited MyCellElement class. Thus these cells do not change their background color with the rest of the row when the user moves the mouse cursor over the row.

Could you please show which method must be overridden to get HotTracking working correctly for the MyCellElement cells?

Thanks!
0
Anton
Telerik team
answered on 05 Sep 2013, 12:13 PM
Hello Michelle,

Thank you for writing.

To style your custom element according to the theme, you should override the ThemeEffectiveType property in your custom element. This property should return the type of its base class. For example :
protected override Type ThemeEffectiveType
{
    get
    {
        return typeof(GridDataCellElement);
    }
}

In this KB you can find more information: http://www.telerik.com/support/kb/winforms/themes/inherit-themes-from-radcontrols.aspx

I hope this helps.

Regards,
Anton
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WINFORMS.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
0
Michelle
Top achievements
Rank 1
answered on 06 Sep 2013, 04:20 AM
That is outstanding, and works perfectly. I looked myself into the source, but never would have found such an elegant and simple solution. Thanks!!
0
Anton
Telerik team
answered on 09 Sep 2013, 05:12 AM
Hi Michelle,

I am glad to hear that my support was useful. If you have further questions, feel free to write back.

Regards,
Anton
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WINFORMS.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
0
Michelle
Top achievements
Rank 1
answered on 11 Sep 2013, 04:49 AM
Hello, one more question regarding mouse events to clarify this thread. The example above shows adding a new ButtonClick event for the new child items. When the user clicks the cell, is it possible to propagate the click event (without coding the new ButtonClick event) so that the parent GridView's CellClicked and ContextMenuOpening events are raised? I've tried calling base.PerformClick and base.OnClick but neither work.

Thanks again!
0
Anton
Telerik team
answered on 12 Sep 2013, 11:45 AM
Hi Michelle,

Thank you for writing back.

I am not sure that I fully understand your scenario by using the provided information. However , I assume that you want to modify the default context menu of the custom cell. If so you can do that by subscribing to the ContextMenuOpening event of RadGridView. For example:
    this.radGridView1.ContextMenuOpening += new ContextMenuOpeningEventHandler(radGridView1_ContextMenuOpening);
}
 
void radGridView1_ContextMenuOpening(object sender, ContextMenuOpeningEventArgs e)
{
    if (e.ContextMenuProvider is CustomGridDataCell)
    {
        //your modification
    }
}

You can find more information about modifying of context menu in this documentation article:http://www.telerik.com/help/winforms/gridview-context-menus-modifying-the-default-context-menu.html

If this is not your case, could you open new ticket where you can attach a sample application that demonstrates it and I will be glad to help further.

I am looking forward to your reply.

Regards,
Anton
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WINFORMS.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
0
Michelle
Top achievements
Rank 1
answered on 16 Sep 2013, 02:10 AM
Hello Anton,

The examples earlier in this thread add a new ButtonClick event for the child items in the CustomGridDataCell cells. In my application, I have already subscribed to the parent grid's CellClicked (for left mouse button) and ContextMenuOpening (for right mouse button) events, which are raised whenever a user clicks (or right-clicks) any of the other cells in the grid. However these two events are not raised by the parent grid when the user clicks in the CustomGridDataCells.

I do not want to use this new ButtonClick event or have to subscribe to it -- I do not want it at all. I simply want the grid to raise the same events when a user clicks in these new inherited cells, as it does everywhere else.

What I have tried: from the CustomGridDataCell inherited class, I have privately subscribed to the Click event on the new child items and tried calling base.PerformClick(), base.OnClick(), base.DoClick(), base.RaiseClick(), when they are clicked, but none of them result in the parent grid's CellClicked or ContextMenuOpening events being raised.

Does this make more sense?

Thanks!
0
Anton
Telerik team
answered on 18 Sep 2013, 12:34 PM
Hi Michelle,

Thank you for writing back.

Now your case is more clear, but I was not able to reproduce the issue on my side with version 2013.2.724. both events - CellClick and ContextMenuOpening were raised when I was clicking on the custom cell. There is a demo project attached which I used during my tests. Could you please take a look at it and modify it on a way to replicate the undesired behavior. This will allow me to investigate it and provide you with further support.

In order to send me project that demonstrates undesired behavior you should open new ticket because the forum does not allow to attach projects.

I am looking forward to your reply.

Regards,
Anton
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WINFORMS.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
0
Michelle
Top achievements
Rank 1
answered on 22 Sep 2013, 12:21 AM
Hello again Anton,

Thank you so much for your help in this, and for spending the time to create a sample project. I have solved the problem, and will describe below.

I am running an older version of Telerik than you, and when I ran the project you posted I had the same issue on my system as before. However, in looking through the source code that Telerik provided when I purchased the package, I have learned what is going on.

When RadGridView receives a mouse click event, it drills back down to see what control is at the coordinates of the mouse by using the recursive method GetElementAtPoint(), and then tries to cast it to GridCellElement. If successful, it raises the CellClick event:

RadElement element = this.ElementTree.GetElementAtPoint(e.Location);
GridCellElement cell = element as GridCellElement;
 
if (cell != null)
{
    this.MasterTemplate.EventDispatcher.RaiseEvent<GridViewCellEventArgs>(EventDispatcher.CellClick,
	cell, new GridViewCellEventArgs(cell.RowInfo, cell.ColumnInfo, this.GridViewElement.ActiveEditor));
}

In my case, the element returned when I clicked on one of the added child controls was the child control itself, but that cannot be cast to a GridCellElement (I have 2 RadImageElement and a RadLabelElement). I wanted their parent CustomGridDataCell returned to that method, which *can* be case to GridCellElement, not the child that I was clicking on.

I looked into the GetElementAtPoint() method, and saw a test for element.ShouldHandleMouseInput  Thus to solve my problem, when creating the controls in the CreateChildElements() override I simple set: 

label.ShouldHandleMouseInput = false;
image1.ShouldHandleMouseInput = false;
image2.ShouldHandleMouseInput = false;
And now these children no longer get returned from GetElementAtPoint(), and everything worked as I wanted. Viola!

0
Anton
Telerik team
answered on 25 Sep 2013, 10:02 AM
Hello Michelle,

Thank you for writing back.

I am glad to hear that you found solution for this case. Your solution is good and we often use this approach in our controls. However, when are answering on forum thread we are testing with our latest version, because we do not have information about the version that you are using, unless explicitly specified. So, if you include the information about the version that you are using in your future forum threads, we will able to test with the appropriate version.

Should you have any other questions, I will be glad to assist you.

Regards,
Anton
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WINFORMS.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
Tags
GridView
Asked by
Alcatraz
Top achievements
Rank 1
Answers by
Svett
Telerik team
Alquin Cook
Top achievements
Rank 1
John
Top achievements
Rank 1
Michelle
Top achievements
Rank 1
Anton
Telerik team
Share this question
or