I have a RadGridView. One of column is an Expander(Not RadExpander, just a regular WPF Expander). For some reason I want to get all Expanders. So by this solution.
private List<
T
> GetVisualTreeObjects<
T
>(DependencyObject obj) where T : DependencyObject
{
List<
T
> objects = new List<
T
>();
int count = VisualTreeHelper.GetChildrenCount(obj);
for (int i = 0; i <
count
; i++)
{
DependencyObject
child
=
VisualTreeHelper
.GetChild(obj, i);
if (child != null)
{
T
requestedType
=
child
as T;
if (requestedType != null)
objects.Add(requestedType);
objects.AddRange(this.GetVisualTreeObjects<T>(child));
}
}
return objects;
}
I can get all Expanders by
var all = GetVisualTreeObjects<
Expander
>(this.grv);
Now I have a RadDataPager for this GridView,
<
telerik:RadDataPager
x:Name
=
"radDataPager"
Source
=
"{Binding Items, ElementName=radGridView}"
PageSize
=
"5"
/>
if I switch to another page, in the PageIndexChanged event. I want to get the all expanders for the current page. But the result is always wrong.
Not sure why?
gg
5 Answers, 1 is accepted
If by "the result is always wrong" you mean that the count of the returned objects is not equal to the PageSize, but rather to the rows in the viewport, this would be expected as, due to RadGridView's UI virtualization mechanism, only the visual elements that are loaded in its viewable area are processed. Disabling this feature will return all of the expected expanders, but please bear in mind that this is highly unrecommended.
If you could specify your exact requirement for processing these expanders, I may be able to suggest a viable solution without disabling the UI virtualization mechanism.
Regards,Dilyan Traykov
Progress Telerik
Dear Dilyaan,
Outside the RadGridView, there is a button. Its function is to expand or collapse all. So I want to get all expanders in the Grid, then use foreach loop to set IsExpanded = true for each expander.
Therefore my plan was to get current expanders when the Grid loaded, then in the PageIndexChanged event to get the expanders in that corresponding viewport as well.
In such a scenario, I can recommend using the underlying data objects to achieve the desired result. You can introduce an IsExpanded property to them and bind this property to the IsExpanded property of the Expander in the CellTemplate.
You can then handle the click of the button and set the IsExpanded property for each of the items in the current page - through the Items property of the RadGridView control.
I'm attaching a small sample project to better demonstrate what I have in mind. Note that I'm toggling the IsExpanded property via a single button, but if you prefer, you can have two separate buttons to set its value to True and False respectively.
I hope you find such an approach applicable. Please let me know if this is the case.
Regards,
Dilyan Traykov
Progress Telerik
So you are using DataItem Collection from the sender.
I also want to change the Button's content. I mean toggle the content between "Expand All" and "Collapse All".
Many thanks,
One possible approach would be to introduce two new properties in your viewmodel to control this behavior. For example:
public
string
ToggleButtonContent
{
get
{
return
this
.IsExpanded ?
"Collapse All"
:
"Expand All"
; }
}
private
bool
isExpanded;
public
bool
IsExpanded
{
get
{
return
isExpanded; }
set
{
isExpanded = value;
this
.OnPropertyChanged(
"IsExpanded"
);
this
.OnPropertyChanged(
"ToggleButtonContent"
);
}
}
The OnChangeIsExpandedExecuted method can then be modified like so:
private
void
OnChangeIsExpandedExecuted(
object
obj)
{
this
.IsExpanded = !
this
.IsExpanded;
var clubs = obj
as
DataItemCollection;
foreach
(Club club
in
clubs)
{
club.IsExpanded =
this
.IsExpanded;
}
}
And you can bind the Content of the button to the ToggleButtonContent property.
<
Button
Name
=
"Button1"
Content
=
"{Binding ToggleButtonContent}"
... />
I've attached the modified project for your reference.
Please let me know whether this meets your requirements.
Regards,
Dilyan Traykov
Progress Telerik