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 Answers, 1 is accepted
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 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.
Dess
Telerik
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