Filter GridViewImageColumns with HeaderCellButtons

3 posts, 1 answers
  1. Andreas Håkansson
    Andreas Håkansson avatar
    3 posts
    Member since:
    Nov 2009

    Posted 15 Oct 2015 Link to this post

    Hi,
    I am using a RadGridView, with a GridViewImageColumn (and some other columns). I want to let the user filter all columns, using the HeaderCellButtons.

    I can get it to work on GridViewTextBoxColumns, just not the GridViewImageColumn. I use RadGridView.ShowHeaderCellButtons=true to bring out the filter icons, and I've made sure the column's AllowFiltering is true too.

    Interestingly, I can get it to work with a filtering row (RadGridView.ShowFilteringRow=true), but not with just the header cells (RadGridView.ShowHeaderCellButtons=true). I've attached a pic where both filteringrow and headercellbuttons are enabled, where you can see that the headercellbutton for the image column is just not there.

    I'm using Q3 2014 SP1. 

    Please help: How do I filter on a GridViewImageColumn using HeaderCellButtons?

    Thanks!



     

  2. Answer
    Dess
    Admin
    Dess avatar
    1609 posts

    Posted 20 Oct 2015 Link to this post

    Hello Andreas,

    Thank you for writing.
     
    Excel-Like Filtering of GridViewImageColumn is not designed to be supported, as there is no readable value which to be displayed in the pop-up for each cell. However, here is a sample approach how to extend the GridViewTextBoxColumn in order to show the popup and display values. The value stored in each cell in the popup is equal to the image's hash code. Afterwards, use the custom filtering functionality to determine which rows to be visible. Note that each value in the popup should be IComparable and this is just a sample approach which can direct you to achieve the required behavior:
    List<Image>images = new List<Image>() { Properties.Resources.alert, Properties.Resources.clock };
     
    public Form1()
    {
        InitializeComponent();
        radGridView1.ViewCellFormatting += radGridView1_ViewCellFormatting;
     
        List<Item> items = new List<Item>();
        for (int i = 0; i < 10; i++)
        {
            items.Add(new Item(i,"Item" + i,images[i % 2]));
        }
     
        this.radGridView1.DataSource = items;
        this.radGridView1.AutoSizeColumnsMode = Telerik.WinControls.UI.GridViewAutoSizeColumnsMode.Fill;
        this.radGridView1.AutoSizeRows = true;
     
        this.radGridView1.Columns.Remove("Picture");
        CustomImageColumn imageCol = new CustomImageColumn();
        imageCol.FieldName = "Picture";
          
        this.radGridView1.Columns.Add(imageCol);
     
        this.radGridView1.EnableFiltering = true;
        this.radGridView1.ShowFilteringRow = false;
        this.radGridView1.ShowHeaderCellButtons = true;
        this.radGridView1.EnableCustomFiltering = true;
        this.radGridView1.CustomFiltering += radGridView1_CustomFiltering;
        this.radGridView1.FilterExpressionChanged += radGridView1_FilterExpressionChanged;
        this.radGridView1.FilterPopupInitialized += radGridView1_FilterPopupInitialized;
    }
     
    private void radGridView1_FilterPopupInitialized(object sender, FilterPopupInitializedEventArgs e)
    {
        RadListFilterPopup popup = e.FilterPopup as RadListFilterPopup;
        if (popup != null)
        {
            popup.MenuTreeElement.TreeView.NodeFormatting -= TreeView_NodeFormatting;
            popup.MenuTreeElement.TreeView.NodeFormatting += TreeView_NodeFormatting;
        }
    }
     
    private void TreeView_NodeFormatting(object sender, TreeNodeFormattingEventArgs e)
    {
        if (e.Node.Text != "All")
        {
            e.NodeElement.Image = GetImageByHashCode(e.Node.Text);
            e.NodeElement.ImageLayout = ImageLayout.Zoom;
            e.NodeElement.ContentElement.DrawText = false;
        }
        else
        {
            e.NodeElement.Image = null;
            e.NodeElement.ContentElement.DrawText = true;
        }
    }
     
    private Image GetImageByHashCode(object value)
    {
        int hashCode;
        if (int.TryParse(value + "", out hashCode))
        {
            foreach (Image img in images)
            {
                if (img.GetHashCode() == hashCode)
                {
                    return img;
                }
            }
        }
        return null;
    }
     
    string filter = "";
     
    private void radGridView1_FilterExpressionChanged(object sender, FilterExpressionChangedEventArgs e)
    {
        filter = e.FilterExpression;
    }
     
    private void radGridView1_CustomFiltering(object sender, GridViewCustomFilteringEventArgs e)
    {
        if (!string.IsNullOrEmpty(filter))
        {
            if (filter.Contains('('))
            {
                filter = filter.Remove(filter.IndexOf(@"("), 1);
            }
            if (filter.Contains(')'))
            {
                filter = filter.Remove(filter.IndexOf(@")"), 1);
            }
            
            string[] images = filter.Split(new string[] { " OR " }, int.MaxValue, StringSplitOptions.RemoveEmptyEntries);
            List<string> filterValues = new List<string>();
            string columnName = this.radGridView1.Columns["Picture"].Name;
            foreach (string hashItem in images)
            {
                string[] imagesHashCode = hashItem.Split(new string[] { columnName + " = " }, int.MaxValue, StringSplitOptions.RemoveEmptyEntries);
                
                filterValues.Add(imagesHashCode[0]);
            }
            int hashVal = ((MyImage)e.Row.Cells["Picture"].Value).Picture.GetHashCode();
            e.Visible = filterValues.Contains(hashVal.ToString());
        }
    }
     
    private void radGridView1_ViewCellFormatting(object sender, Telerik.WinControls.UI.CellFormattingEventArgs e)
    {
        if (e.CellElement is GridHeaderCellElement)
        {
            GridFilterButtonElement filter = e.CellElement.Children[0].Children[0] as GridFilterButtonElement;
            filter.Visibility = Telerik.WinControls.ElementVisibility.Visible ;
        }
     
        if (e.Row is GridViewDataRowInfo && e.Column.Name == "Picture")
        {
            e.CellElement.Image = ((MyImage)e.CellElement.Value).Picture;
            e.CellElement.DrawText = false;
        }
        else
        {
            e.CellElement.ResetValue(LightVisualElement.ImageProperty, ValueResetFlags.Local);
            e.CellElement.ResetValue(LightVisualElement.DrawTextProperty, ValueResetFlags.Local);
        }
    }
     
    public class CustomImageColumn : GridViewTextBoxColumn
    {
        protected override GridViewColumnValuesCollection GetDistinctValues()
        {
            int index = this.Index;
            if (index >= 0)
            {
                GridViewColumnValuesCollection distinctValues = new GridViewColumnValuesCollection();
                List<object> distinctValuesTmp = new List<object>();
                foreach (GridViewDataRowInfo row in this.OwnerTemplate.Rows)
                {
                    object cellValue = row.Cells[index].Value;
                    if (!distinctValuesTmp.Contains(cellValue, new MyComparer()))
                    {
                        distinctValuesTmp.Add(cellValue);
                        distinctValues.Add(((MyImage)cellValue).Picture.GetHashCode());
                    }
                }
                if (distinctValues.Count > 0)
                {
                    return distinctValues;
                }
            }
            return null;
        }
     
        protected override GridViewColumnValuesCollection GetDistinctValuesWithFilter()
        {
            int index = this.Index;
            if (index >= 0)
            {
                GridViewColumnValuesCollection distinctValues = new GridViewColumnValuesCollection();
                List<object> distinctValuesTmp = new List<object>();
                foreach (GridViewDataRowInfo row in this.OwnerTemplate.ChildRows)
                {
                    object cellValue = row.Cells[index].Value;
                    if (!distinctValuesTmp.Contains(cellValue, new MyComparer()))
                    {
                        distinctValuesTmp.Add(cellValue);
                        distinctValues.Add(((MyImage)cellValue).Picture.GetHashCode());
                    }
                }
                if (distinctValues.Count > 0)
                {
                    return distinctValues;
                }
            }
            return null;
        }
    }
     
    public class MyComparer : IEqualityComparer<object>
    {
        public bool Equals(object x, object y)
        {
            MyImage img1 = x as MyImage;
            MyImage img2 = y as MyImage;
            if (img1 != null && img2 != null)
            {
                return img1.Picture.Equals(img2.Picture);
            }
            return x.Equals(y);
        }
     
        public int GetHashCode(object obj)
        {
            MyImage img = obj as MyImage;
            if (img != null)
            {
                return img.Picture.GetHashCode();
            }
            return obj.GetHashCode();
        }
    }
     
    public class Item
    {
        public int Id { get; set; }
     
        public string Name { get; set; }
     
        public MyImage Picture { get; set; }
         
        public Item(int id, string name, Image picture)
        {
            this.Id = id;
            this.Name = name;
            this.Picture = new MyImage(picture);
        }
    }
     
    public class MyImage : IComparable
    {
        public Image Picture { get; set; }
     
        public MyImage(Image picture)
        {
            this.Picture = picture;
        }
     
        public override bool Equals(object obj)
        {
            MyImage img = obj as MyImage;
            if (img != null)
            {
                this.Picture.Equals(img.Picture);
            }
            return base.Equals(obj);
        }
     
        public int CompareTo(object obj)
        {
            MyImage other = obj as MyImage;
            if (other != null)
            {
                return this.Picture.GetHashCode().CompareTo(other.Picture.GetHashCode());
            }
            return this.GetHashCode().CompareTo(obj.GetHashCode());
        }
    }
     
    I hope this information helps. Should you have further questions I would be glad to help.
     
    Regards,
    Dess
    Telerik
    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 Feedback Portal and vote to affect the priority of the items
  3. UI for WinForms is Visual Studio 2017 Ready
  4. Andreas Håkansson
    Andreas Håkansson avatar
    3 posts
    Member since:
    Nov 2009

    Posted 09 Nov 2015 in reply to Dess Link to this post

    Hi,

    Thank you for your response! (And sorry about my late response.)

    Since I only needed to filter on "image exists" vs "no image" I went with using the CellClick event and using that for turning on/off my filter. It seemed much simpler.

    Regards,

    Andreas

Back to Top