New to Telerik UI for WinForms? Download free 30-day trial

Grouping by GridViewImageColumn

Date Posted Product Author
May 09, 2014 RadGridView Desislava Yordanova

How To

By default, RadGridView does not support grouping by GridViewImageColumn functionality. This article demonstrates how to implement such a behavior.

Solution

1. First, let’s populate the RadGridView with data. For this purpose, we will start with creating a sample class MyObjectwhich have Photo property of type Image.

List<Image> images = new List<Image>()
{
    Properties.Resources.open,
    Properties.Resources.paste,
    Properties.Resources.pdf
};

public Form1()
{
    InitializeComponent();

    Random rand = new Random();
    List<MyObject> list = new List<MyObject>() { };
    for (int i = 0; i < 10; i++)
    {
        list.Add(new MyObject(rand.Next(0, 4), "Name " + i, images[rand.Next(0, images.Count)]));
    }

    radGridView1.DataSource = list;
    radGridView1.AutoSizeRows = true;
    radGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill;
 }

The custom business object:

public class MyObject
{
    public int ID { get; set; }

    public string Title { get; set; }

    public Image Photo { get; set; }

    public MyObject(int iD, string title, Image photo)
    {
        this.ID = iD;
        this.Title = title;
        this.Photo = photo;
    }
}

You will notice that you are not allowed to drag the GridViewImageColumn’s header and drop it over the “Drag a column here to group by this column” area.

grouping-by-gridviewimagecolumn 001

2. In order to enable drag and drop functionality for the GridViewImageColumn’s header over the GroupPanelElement, it is necessary to use the RadDragDropService. Subscribe for its PreviewDragStart event to start the RadDragDropService if you are dragging a GridHeaderCellElement. Use the PreviewDragOver event to allow dropping over the GroupPanelElement:

public Form1()
{
    InitializeComponent();
    //populate the grid with data

    RadDragDropService svc =this.radGridView1.GridViewElement.GetService<RadDragDropService>();
    svc.PreviewDragStart += svc_PreviewDragStart;
    svc.PreviewDragOver += svc_PreviewDragOver;

    radGridView1.GroupByChanged += radGridView1_GroupByChanged;
    radGridView1.EnableCustomGrouping = true;
    radGridView1.CustomGrouping += radGridView1_CustomGrouping;
    radGridView1.GroupSummaryEvaluate += radGridView1_GroupSummaryEvaluate;
}

private void svc_PreviewDragStart(object sender, PreviewDragStartEventArgs e)
{
    SnapshotDragItem dragged = e.DragInstance asSnapshotDragItem;
    if (dragged != null && dragged.Item isGridHeaderCellElement)
    {
        e.CanStart = true;
    }
}

private void svc_PreviewDragOver(object sender, RadDragOverEventArgs e)
{
    SnapshotDragItem dragged = e.DragInstance asSnapshotDragItem;
    if (dragged != null && dragged.Item isGridHeaderCellElement)
    {
        e.CanDrop = e.HitTarget is GroupPanelElement;       
    }
}

3. Use the GroupByChanged event to display the GroupFieldElement.RemoveButton

private void radGridView1_GroupByChanged(object sender, GridViewCollectionChangedEventArgs e)
{
    if(this.radGridView1.GridViewElement.GroupPanelElement.PanelContainer.Children != null &&
        this.radGridView1.GridViewElement.GroupPanelElement.PanelContainer.Children.Count > 0)
    {
        TemplateGroupsElement templateGroupsElement = radGridView1.GridViewElement.GroupPanelElement.PanelContainer.Children[0] as TemplateGroupsElement;
        if (templateGroupsElement != null)
        {
            foreach (GroupElement groupElement intemplateGroupsElement.GroupElements)
            {
                foreach (GroupFieldElement groupFieldsElement in groupElement.GroupingFieldElements)
                {
                    if(groupFieldsElement.RemoveButton.Visibility != ElementVisibility.Visible)
                    {
                        groupFieldsElement.RemoveButton.Visibility = ElementVisibility.Visible;
                    }
                }
            }
        }
    }
}

4. Now, we need to implement the logic for grouping the rows. We will use the custom grouping functionality of the RadGridView. Set the EnableCustomGrouping property to true and subscribe to the CustomGrouping event, where we will group rows by image name:

private void radGridView1_CustomGrouping(object sender, GridViewCustomGroupingEventArgs e)
{
    if (this.UseDefaultGrouping(e.Level))
    {
        e.Handled = false;
        return;
    }
    Image photo = e.Row.Cells["Photo"].Value as Image;
    int index = images.IndexOf(photo);

    switch (index)
    {
        case 0:
            e.GroupKey = "open";

            break;
        case 1:
            e.GroupKey = "paste";
            break;
        case 2:
            e.GroupKey = "pdf";
            break;
        default:
            e.GroupKey = "Other image";
            break;
    }
}

private bool UseDefaultGrouping(int level)
{
    GroupDescriptor groupDescriptor =this.radGridView1.GroupDescriptors[level];
    for (int i = 0; i < groupDescriptor.GroupNames.Count; i++)
    {
        if(groupDescriptor.GroupNames[i].PropertyName.Equals("Photo", StringComparison.InvariantCultureIgnoreCase))
        {
            return false;
        }
    }
    return true;
}

5. The last thing we need to do is to subscribe to the GroupSummaryEvaluate event and construct the desired string for the group’s title:

private void radGridView1_GroupSummaryEvaluate(object sender, GroupSummaryEvaluationEventArgs e)
{
    if (this.UseDefaultGrouping(e.Group.Level))
    {
        return;
    }

    if (e.Value == null)
    {
        e.FormatString = "Photo \"" + e.Group.Key.ToString() + "\"";
    }
}

grouping-by-gridviewimagecolumn 002

A complete solution in C# and VB.NET can be found here.

In this article