Hello Telerik,
I am having a situation when using expandable rows.
When they have no children, the Expand Button keeps displaying.
Since it will come up empty, there is no reason for it to be there
so what I want is to hide it in case the row has no children.
I another ticket, I was guided to see this link
http://www.telerik.com/forums/show-and-hide-expand-button-dynamically
But in my case I will have no such "clean" button. I simply want to hide the expand buttons during the grid load time without losing performance (I have 1 mil rows and 4 mil children spread among them)
Please show me the best way to achieve this.
it has to do with
row.IsExpandable = false;
at some point, right? What's is it?
Thank you.
17 Answers, 1 is accepted
You can use a RowStyleSelector to achieve the desired effect. Assuming you have a Clubs -> Players hierarchy, the following RowStyleSelector can be defined:
public
class
IsExpandedStyleSelector : System.Windows.Controls.StyleSelector
{
public
Style HierarchyStyle {
get
;
set
; }
public
Style NoHierarchyStyle {
get
;
set
; }
public
override
Style SelectStyle(
object
item, DependencyObject container)
{
var row = container
as
GridViewRow;
if
(row ==
null
)
{
return
base
.SelectStyle(item, container);
}
if
((item
as
Club).Players.Count > 0)
{
return
this
.HierarchyStyle;
}
else
{
return
this
.NoHierarchyStyle;
}
}
}
<
telerik:RadGridView.RowStyleSelector
>
<
my:IsExpandedStyleSelector
>
<
my:IsExpandedStyleSelector.HierarchyStyle
>
<
Style
TargetType
=
"telerik:GridViewRow"
>
<
Setter
Property
=
"IsExpandable"
Value
=
"True"
/>
</
Style
>
</
my:IsExpandedStyleSelector.HierarchyStyle
>
<
my:IsExpandedStyleSelector.NoHierarchyStyle
>
<
Style
TargetType
=
"telerik:GridViewRow"
>
<
Setter
Property
=
"IsExpandable"
Value
=
"False"
/>
</
Style
>
</
my:IsExpandedStyleSelector.NoHierarchyStyle
>
</
my:IsExpandedStyleSelector
>
</
telerik:RadGridView.RowStyleSelector
>
I'm attaching a sample project with the implementation. Please let me know if you find it helpful.
Regards,
Dilyan Traykov
Telerik
Hello Dilyan, thank you for your reply.
Your sample works in its own case, where you can use this piece of code for your children rows
<
telerik:RadGridView.ChildTableDefinitions
>
<
telerik:GridViewTableDefinition
>
<
telerik:GridViewTableDefinition.Relation
>
<
telerik:PropertyRelation
ParentPropertyName
=
"Players"
/>
</
telerik:GridViewTableDefinition.Relation
>
</
telerik:GridViewTableDefinition
>
</
telerik:RadGridView.ChildTableDefinitions
>
But in my case, my children's grid will be designed further than automatically.
this is my code for the children's grid
<
Grid
>
<
Grid.Resources
>
<
DataTemplate
x:Key
=
"RowDetailsTemplate"
>
<
telerik:RadGridView
Name
=
"playersGrid"
Style
=
"{StaticResource VitorStyle}"
ItemsSource
=
"{Binding Children}"
>
<
telerik:RadGridView.Columns
>
<
telerik:GridViewDataColumn
DataMemberBinding
=
"{Binding ID}"
/>
<
telerik:GridViewDataColumn
DataMemberBinding
=
"{Binding Name}"
/>
<
telerik:GridViewDataColumn
DataMemberBinding
=
"{Binding ParentID}"
/>
</
telerik:RadGridView.Columns
>
</
telerik:RadGridView
>
</
DataTemplate
>
</
Grid.Resources
>
thus, in my parent's grid, I have to use this line here among with the other columns, to see the EXPANDING button row
<
telerik:GridViewToggleRowDetailsColumn
/>
this is my case. and the method you provided me:
public
override
Style SelectStyle(
object
item, DependencyObject container)
{
return
this
.NoHierarchyStyle;
}
won't work, even if I always return NoHierarchyStyle, the buttons will still appear...
design:
<
Window
x:Class
=
"TelerikVirtualization.MainWindow"
xmlns:telerik
=
"http://schemas.telerik.com/2008/xaml/presentation"
xmlns:my
=
"clr-namespace:TelerikVirtualization"
Title
=
"MainWindow"
Height
=
"900"
Width
=
"700"
Loaded
=
"Window_Loaded"
>
<
Window.Resources
>
<
Style
x:Key
=
"VitorStyle"
TargetType
=
"telerik:RadGridView"
>
<
Setter
Property
=
"AutoGenerateColumns"
Value
=
"False"
></
Setter
>
<
Setter
Property
=
"FilteringMode"
Value
=
"FilterRow"
></
Setter
>
</
Style
>
</
Window.Resources
>
<
Grid
>
<
Grid.Resources
>
<
DataTemplate
x:Key
=
"RowDetailsTemplate"
>
<
telerik:RadGridView
Name
=
"playersGrid"
Style
=
"{StaticResource VitorStyle}"
ItemsSource
=
"{Binding Children}"
>
<
telerik:RadGridView.ControlPanelItems
>
<
telerik:ControlPanelItem
ButtonTooltip
=
"Column chooser"
>
<
telerik:ControlPanelItem.Content
>
<
ListBox
ItemsSource
=
"{Binding Columns}"
BorderThickness
=
"0"
>
<
ListBox.ItemTemplate
>
<
DataTemplate
>
<
CheckBox
Content
=
"{Binding Header, Mode=OneWay}"
IsChecked
=
"{Binding IsVisible, Mode=TwoWay}"
/>
</
DataTemplate
>
</
ListBox.ItemTemplate
>
</
ListBox
>
</
telerik:ControlPanelItem.Content
>
</
telerik:ControlPanelItem
>
</
telerik:RadGridView.ControlPanelItems
>
<
telerik:RadGridView.Columns
>
<
telerik:GridViewDataColumn
DataMemberBinding
=
"{Binding ID}"
/>
<
telerik:GridViewDataColumn
DataMemberBinding
=
"{Binding Name}"
/>
<
telerik:GridViewDataColumn
DataMemberBinding
=
"{Binding ParentID}"
/>
</
telerik:RadGridView.Columns
>
</
telerik:RadGridView
>
</
DataTemplate
>
</
Grid.Resources
>
<
telerik:RadGridView
Name
=
"RadGridView"
ItemsSource
=
"{Binding View}"
Style
=
"{StaticResource VitorStyle}"
RowDetailsTemplate
=
"{StaticResource RowDetailsTemplate}"
AutoGenerateColumns
=
"False"
>
<
telerik:RadGridView.RowStyleSelector
>
<
my:IsExpandedStyleSelector
>
<
my:IsExpandedStyleSelector.HierarchyStyle
>
<
Style
TargetType
=
"telerik:GridViewRow"
>
<
Setter
Property
=
"IsExpandable"
Value
=
"True"
/>
</
Style
>
</
my:IsExpandedStyleSelector.HierarchyStyle
>
<
my:IsExpandedStyleSelector.NoHierarchyStyle
>
<
Style
TargetType
=
"telerik:GridViewRow"
>
<
Setter
Property
=
"IsExpandable"
Value
=
"False"
/>
</
Style
>
</
my:IsExpandedStyleSelector.NoHierarchyStyle
>
</
my:IsExpandedStyleSelector
>
</
telerik:RadGridView.RowStyleSelector
>
<
telerik:RadGridView.Columns
>
<
telerik:GridViewToggleRowDetailsColumn
/>
<
telerik:GridViewDataColumn
DataMemberBinding
=
"{Binding ID}"
/>
<
telerik:GridViewDataColumn
DataMemberBinding
=
"{Binding Name}"
/>
<
telerik:GridViewDataColumn
DataMemberBinding
=
"{Binding UnitPrice}"
Header
=
"UnitPrice"
/>
<
telerik:GridViewDataColumn
DataMemberBinding
=
"{Binding Date}"
Header
=
"Date"
DataFormatString
=
"{}{0:dd/MM/yyyy}"
/>
<
telerik:GridViewDataColumn
DataMemberBinding
=
"{Binding Discontinued}"
/>
</
telerik:RadGridView.Columns
>
</
telerik:RadGridView
>
</
Grid
>
</
Window
>
CS
using
System.ComponentModel;
using
System.Windows;
namespace
TelerikVirtualization
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public
partial
class
MainWindow : Window
{
BackgroundWorker worker =
new
BackgroundWorker();
bool
complete =
false
;
public
MainWindow(
bool
complete)
{
InitializeComponent();
DataContext =
new
ViewModel();
this
.complete = complete;
}
private
void
Window_Loaded(
object
sender, RoutedEventArgs e)
{
((ViewModel)DataContext).Load(complete);
}
}
public
class
IsExpandedStyleSelector : System.Windows.Controls.StyleSelector
{
public
Style HierarchyStyle {
get
;
set
; }
public
Style NoHierarchyStyle {
get
;
set
; }
public
override
Style SelectStyle(
object
item, DependencyObject container)
{
return
this
.NoHierarchyStyle;
}
}
}
as I said, the buttons wont hide, even tho the debugger shows it goes through the return this.NoHierarchyStyle; line
Would it work for you to use the ChildTableDefinitions approach from my last reply and set the HierarchyChildTemplate instead of the RowDetailsTemplate? In this case, you won't need to define the GridViewToggleRowDetailsColumn. Please refer to my modified project.
Regards,
Dilyan Traykov
Telerik
Hello,
the approach WORKED!
Now there is just one more thing regarding the solution:
i dont really like to create a whole class just because of One specific gridview.
Imagine i will have it repeated over and over in my project. maybe even twice (two grids like that) in the same page
how can i extend that solution to involve all my grids in it, avoiding code repetition?
also, this design isnot really under MVVM pattern... please help me with that.
public
class
IsExpandedStyleSelector : System.Windows.Controls.StyleSelector
{
public
Style HierarchyStyle {
get
;
set
; }
public
Style NoHierarchyStyle {
get
;
set
; }
public
override
Style SelectStyle(
object
item, DependencyObject container)
{
var row = container
as
GridViewRow;
if
(row ==
null
)
{
return
base
.SelectStyle(item, container);
}
if
(item.GetType() ==
typeof
(MyTableEntity))
{
if
(((System.Linq.IQueryable)((((MyTableEntity)item).Children
as
System.Linq.IQueryable<MyChildTableEntity>))).GetEnumerator().MoveNext())
{
return
this
.HierarchyStyle;
}
else
{
return
this
.NoHierarchyStyle;
}
}
else
return
this
.NoHierarchyStyle;
}
}
and here is my XAML
<
Window
x:Class
=
"TelerikVirtualization.MainWindow"
xmlns:telerik
=
"http://schemas.telerik.com/2008/xaml/presentation"
xmlns:my
=
"clr-namespace:TelerikVirtualization"
Title
=
"MainWindow"
Height
=
"900"
Width
=
"700"
Loaded
=
"Window_Loaded"
>
<
Window.Resources
>
<
Style
x:Key
=
"VitorStyle"
TargetType
=
"telerik:RadGridView"
>
<
Setter
Property
=
"AutoGenerateColumns"
Value
=
"False"
></
Setter
>
<
Setter
Property
=
"FilteringMode"
Value
=
"FilterRow"
></
Setter
>
</
Style
>
</
Window.Resources
>
<
Grid
>
<
telerik:RadGridView
Name
=
"RadGridView"
ItemsSource
=
"{Binding View}"
Style
=
"{StaticResource VitorStyle}"
AutoGenerateColumns
=
"False"
>
<
telerik:RadGridView.RowStyleSelector
>
<
my:IsExpandedStyleSelector
>
<
my:IsExpandedStyleSelector.HierarchyStyle
>
<
Style
TargetType
=
"telerik:GridViewRow"
>
<
Setter
Property
=
"IsExpandable"
Value
=
"True"
/>
</
Style
>
</
my:IsExpandedStyleSelector.HierarchyStyle
>
<
my:IsExpandedStyleSelector.NoHierarchyStyle
>
<
Style
TargetType
=
"telerik:GridViewRow"
>
<
Setter
Property
=
"IsExpandable"
Value
=
"False"
/>
</
Style
>
</
my:IsExpandedStyleSelector.NoHierarchyStyle
>
</
my:IsExpandedStyleSelector
>
</
telerik:RadGridView.RowStyleSelector
>
<
telerik:RadGridView.Columns
>
<
telerik:GridViewDataColumn
DataMemberBinding
=
"{Binding ID}"
/>
<
telerik:GridViewDataColumn
DataMemberBinding
=
"{Binding Name}"
/>
<
telerik:GridViewDataColumn
DataMemberBinding
=
"{Binding UnitPrice}"
Header
=
"UnitPrice"
/>
<
telerik:GridViewDataColumn
DataMemberBinding
=
"{Binding Date}"
Header
=
"Date"
DataFormatString
=
"{}{0:dd/MM/yyyy}"
/>
<
telerik:GridViewDataColumn
DataMemberBinding
=
"{Binding Discontinued}"
/>
</
telerik:RadGridView.Columns
>
<
telerik:RadGridView.ChildTableDefinitions
>
<
telerik:GridViewTableDefinition
>
<
telerik:GridViewTableDefinition.Relation
>
<
telerik:PropertyRelation
ParentPropertyName
=
"Children"
/>
</
telerik:GridViewTableDefinition.Relation
>
</
telerik:GridViewTableDefinition
>
</
telerik:RadGridView.ChildTableDefinitions
>
<
telerik:RadGridView.HierarchyChildTemplate
>
<
DataTemplate
>
<
telerik:RadGridView
Style
=
"{StaticResource VitorStyle}"
IsBusy
=
"True"
ItemsSource
=
"{Binding Children}"
>
<
telerik:RadGridView.ControlPanelItems
>
<
telerik:ControlPanelItem
ButtonTooltip
=
"Column chooser"
>
<
telerik:ControlPanelItem.Content
>
<
ListBox
ItemsSource
=
"{Binding Columns}"
BorderThickness
=
"0"
>
<
ListBox.ItemTemplate
>
<
DataTemplate
>
<
CheckBox
Content
=
"{Binding Header, Mode=OneWay}"
IsChecked
=
"{Binding IsVisible, Mode=TwoWay}"
/>
</
DataTemplate
>
</
ListBox.ItemTemplate
>
</
ListBox
>
</
telerik:ControlPanelItem.Content
>
</
telerik:ControlPanelItem
>
</
telerik:RadGridView.ControlPanelItems
>
<
telerik:RadGridView.Columns
>
<
telerik:GridViewDataColumn
DataMemberBinding
=
"{Binding ID}"
/>
<
telerik:GridViewDataColumn
DataMemberBinding
=
"{Binding Name}"
/>
<
telerik:GridViewDataColumn
DataMemberBinding
=
"{Binding ParentID}"
/>
</
telerik:RadGridView.Columns
>
</
telerik:RadGridView
>
</
DataTemplate
>
</
telerik:RadGridView.HierarchyChildTemplate
>
</
telerik:RadGridView
>
</
Grid
>
</
Window
>
In the following blog post, one of my colleagues has given an excellent example of how you can achieve the desired result using attached behaviors. I believe it would be applicable in your scenario as you will only need to change the IsExpandableSourcePropertyName of the behavior for each GridView in your project. I've modified my sample project accordingly and attached it to my reply.
Let me know if this would work for you.
Regards,
Dilyan Traykov
Telerik
WORKED
LIKE
A
CHARM
thank you very much!
I was wondering,
is it possible to include the xaml code of the provided solution, into a style page?
<
i:Interaction.Behaviors
>
<
my:IsExpandableBehavior
IsExpandableSourcePropertyName
=
"Children.Count"
/>
</
i:Interaction.Behaviors
>
I dont feel like repeating it in all my pages
Unfortunately, there is no straightforward way to set Behaviors through Styles so that a single one is shared for all RadGridViews. You can review the following thread from StackOverflow though - How to Add a Blend Behavior Through Style - as there is an approach suggested that might work for you.
I have refactored the project so that it uses AttachedProperty instead of the Behavior. You can set the attached property in a as follows:
<
Style
TargetType
=
"telerik:RadGridView"
>
<
Setter
Property
=
"my:IsExpandableHelper.IsExpandableAttachedProperty"
Value
=
"True"
></
Setter
>
</
Style
>
Regards,
Stefan Nenchev
Telerik
hmm
it is ok. I am fine with the previous solution
thank you !
Hello, I'm trying out this example here and ran into the following issue with the HierarchyIsExpandable.zip example:
When the following GridView properties is set: AlternationCount="2" then the rows that have the alternate color, the IsExpandedStyleSelector is not firing... So, even though there are no children items I still get the expander.
How can I work around that?
Hello Ilya,
As there are 3 different projects with the name "HierarchyIsExpandable" could you please clarify to which specific one you're referring? Based on your description I assume it's the one from 18 Mar 2016, but please let me know if that is not the case.
If you're using alternate rows by defining the AlternationCount property, you also need to specify the AlternateRowStyle property:
<telerik:RadGridView.RowStyleSelector>
<my:IsExpandedStyleSelector>
<my:IsExpandedStyleSelector.HierarchyStyle>
<Style TargetType="telerik:GridViewRow">
<Setter Property="IsExpandable" Value="True" />
</Style>
</my:IsExpandedStyleSelector.HierarchyStyle>
<my:IsExpandedStyleSelector.NoHierarchyStyle>
<Style TargetType="telerik:GridViewRow">
<Setter Property="IsExpandable" Value="False" />
</Style>
</my:IsExpandedStyleSelector.NoHierarchyStyle>
</my:IsExpandedStyleSelector>
</telerik:RadGridView.RowStyleSelector>
<telerik:RadGridView.AlternateRowStyleSelector>
<my:IsExpandedStyleSelector>
<my:IsExpandedStyleSelector.HierarchyStyle>
<Style TargetType="telerik:GridViewRow">
<Setter Property="IsExpandable" Value="True" />
</Style>
</my:IsExpandedStyleSelector.HierarchyStyle>
<my:IsExpandedStyleSelector.NoHierarchyStyle>
<Style TargetType="telerik:GridViewRow">
<Setter Property="IsExpandable" Value="False" />
</Style>
</my:IsExpandedStyleSelector.NoHierarchyStyle>
</my:IsExpandedStyleSelector>
</telerik:RadGridView.AlternateRowStyleSelector>
Please give this a try and let me know if it resolves your issue.
Regards,
Dilyan Traykov
Progress Telerik
Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.
Thank you for the reply. That fixes my issue with correctly identifying items that should and should not have the IsExapandable set, however, now the alternate row background doesn't show up.
So then I see that I can just add two more setters in the AlternateRowStyleSelector section for Background color.
My follow up question is, how do I pick the default theme alternate color in the setter?
This is almost what I want, except I want it to be the default color for the Office_BlueTheme.
<
telerik:RadGridView.AlternateRowStyleSelector
>
<
myIssues:IsExpandedStyleSelector
>
<
myIssues:IsExpandedStyleSelector.HierarchyStyle
>
<
Style
TargetType
=
"telerik:GridViewRow"
>
<
Setter
Property
=
"IsExpandable"
Value
=
"True"
/>
<
Setter
Property
=
"Background"
Value
=
"AliceBlue"
/>
</
Style
>
</
myIssues:IsExpandedStyleSelector.HierarchyStyle
>
<
myIssues:IsExpandedStyleSelector.NoHierarchyStyle
>
<
Style
TargetType
=
"telerik:GridViewRow"
>
<
Setter
Property
=
"IsExpandable"
Value
=
"False"
/>
<
Setter
Property
=
"Background"
Value
=
"AliceBlue"
/>
</
Style
>
</
myIssues:IsExpandedStyleSelector.NoHierarchyStyle
>
</
myIssues:IsExpandedStyleSelector
>
</
telerik:RadGridView.AlternateRowStyleSelector
>
Hi Ilya,
The default value for the AlternateRowBackground property in the Office_Blue theme is #FFF5FAFF. You can either hard-code this value in the setter or use a RelativeSource binding to access this property from the RadGridView control:
<telerik:RadGridView.AlternateRowStyleSelector>
<my:IsExpandedStyleSelector>
<my:IsExpandedStyleSelector.HierarchyStyle>
<Style TargetType="telerik:GridViewRow">
<Setter Property="IsExpandable" Value="True" />
<Setter Property="Background" Value="{Binding AlternateRowBackground, RelativeSource={RelativeSource AncestorType=telerik:RadGridView}}" />
</Style>
</my:IsExpandedStyleSelector.HierarchyStyle>
<my:IsExpandedStyleSelector.NoHierarchyStyle>
<Style TargetType="telerik:GridViewRow">
<Setter Property="Background" Value="#FFF5FAFF" />
<Setter Property="IsExpandable" Value="False" />
</Style>
</my:IsExpandedStyleSelector.NoHierarchyStyle>
</my:IsExpandedStyleSelector>
</telerik:RadGridView.AlternateRowStyleSelector>
Regards,
Dilyan Traykov
Progress Telerik
Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.