I have a grid linked to sparse object data, and would like to hide any areas that don't have data from the user. In other words, I'm linked to objects that have child collections, and would like to hide the tabs for the rows that don't have any child data. I used the advice here to hide the expander when it's not needed, but all child tabs are still shown even if only one of them has child data. Is there a way to hide tabs that don't have child data?
10 Answers, 1 is accepted
0

Richard Slade
Top achievements
Rank 2
answered on 15 Feb 2011, 11:02 PM
Hello Cat,
A quick scan of the forums reminded me of a similar question. Have a read of this forum post as I believe it deals with the issue you have here.
Regards,
Richard
A quick scan of the forums reminded me of a similar question. Have a read of this forum post as I believe it deals with the issue you have here.
Regards,
Richard
0

Cat
Top achievements
Rank 1
answered on 16 Feb 2011, 03:56 AM
Upon further testing, it appears that the [+] is removed if (and only if) the first child collection is empty. I want this to be removed if *all* the child collections are empty, so the solution I linked to doesn't quite work for me. I've attached my code showing how this works/doesn't work. Here are my goals:
1) Show the [+] only if one or more of the child collections has data,
2) Then only show tabs for the child collections that do have data,
3) Finally (probably pipe dream here) be able to update the Caption property of the tab so that the tab also shows the number of rows it contains. E.g. - "Tab Title (3)", where the 3 refers to the number of rows in that tab.
Richard, I'd already seen the forum post you directed to me too, and it doesn't appear to work at all. All tabs appear regardless of whether they contain data or not. The user simply is unable to activate that tab, which is probably as misleading as being able to activate the tab and see garbage data.
I assume that this can probably be handled by catching the proper events, but I seem to be failing in that department. Any help would be greatly appreciated!!
Below is the code I'm testing with.
Form1.cs
TestData.cs (using NBuilder)
1) Show the [+] only if one or more of the child collections has data,
2) Then only show tabs for the child collections that do have data,
3) Finally (probably pipe dream here) be able to update the Caption property of the tab so that the tab also shows the number of rows it contains. E.g. - "Tab Title (3)", where the 3 refers to the number of rows in that tab.
Richard, I'd already seen the forum post you directed to me too, and it doesn't appear to work at all. All tabs appear regardless of whether they contain data or not. The user simply is unable to activate that tab, which is probably as misleading as being able to activate the tab and see garbage data.
I assume that this can probably be handled by catching the proper events, but I seem to be failing in that department. Any help would be greatly appreciated!!
Below is the code I'm testing with.
Form1.cs
using
System.Collections.Generic;
using
System.Linq;
using
System.Windows.Forms;
using
Telerik.WinControls.UI;
namespace
RadGridViewExample
{
public
partial
class
Form1 : Form
{
public
Form1()
{
InitializeComponent();
gvGridView = CreateGridViewFromSearch(gvGridView);
}
private
RadGridView CreateGridViewFromSearch(RadGridView gvResults)
{
gvResults.Dock = DockStyle.Fill;
gvResults.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.None;
gvResults.ReadOnly =
true
;
gvResults.Text =
"Test of Hierarchial Data in Grid"
;
gvResults.ViewCellFormatting += radGridView1_ViewCellFormatting;
gvResults.ChildViewExpanding += radGridView1_ChildViewExpanding;
DataBlob resultsBlob = TestData.GetTestData();
// Set up the master template
gvResults.MasterTemplate.AllowAddNewRow =
false
;
gvResults.MasterTemplate.AutoGenerateColumns =
false
;
gvResults.MasterTemplate.Tag = TestData.MainCollectionName;
gvResults.DataSource = resultsBlob.Data;
gvResults.TableElement.BeginUpdate();
gvResults.MasterTemplate.Columns.Clear();
// First do the main level
NameAliasSet mainAliasSet = resultsBlob.AliasDictionaries.Where(x => x.CollectionName == TestData.MainCollectionName).FirstOrDefault();
NameAliasSet columnAliasSet = resultsBlob.AliasDictionaries.Where(x => x.CollectionName == TestData.CollectionAliasCollectionName).FirstOrDefault();
NameAliasSet childParentSet = resultsBlob.AliasDictionaries.Where(x => x.CollectionName == TestData.ChildParentCollectionName).FirstOrDefault();
// Create columns from alias collection
foreach
(var record
in
mainAliasSet.ColumnAliases)
{
GridViewTextBoxColumn column =
new
GridViewTextBoxColumn();
column.Name = record.Key;
column.HeaderText = record.Value;
column.FieldName = record.Key;
column.MinWidth = 50;
column.MaxWidth = 250;
column.AutoSizeMode = BestFitColumnMode.DisplayedDataCells;
gvResults.MasterTemplate.Columns.Add(column);
}
// Now do the child sets
foreach
(NameAliasSet aliasSet
in
resultsBlob.AliasDictionaries.Where(x => IsNotACollection(x.CollectionName)))
{
string
name = aliasSet.CollectionName;
Dictionary<
string
,
string
> dictionary = aliasSet.ColumnAliases;
GridViewTemplate template =
new
GridViewTemplate();
GridViewTemplate parentTemplate = GetParentTemplateByName(name, gvResults, childParentSet);
parentTemplate.Templates.Add(template);
template.Tag = name;
template.Caption = columnAliasSet.ColumnAliases[name];
// Create columns from alias collection
foreach
(var record
in
dictionary)
{
GridViewTextBoxColumn column =
new
GridViewTextBoxColumn();
column.Name = record.Key;
column.HeaderText = record.Value;
column.FieldName = record.Key;
column.MinWidth = 50;
column.MaxWidth = 250;
column.AutoSizeMode = BestFitColumnMode.DisplayedDataCells;
template.Columns.Add(column);
}
template.BestFitColumns();
GridViewRelation relation =
new
GridViewRelation(parentTemplate, template);
relation.RelationName = name +
"Relation"
;
relation.ChildColumnNames.Add(name);
gvResults.Relations.Add(relation);
}
gvResults.TableElement.EndUpdate(
false
);
gvResults.MasterTemplate.BestFitColumns();
return
gvResults;
}
private
bool
IsExpandable(GridViewRowInfo rowInfo)
{
if
(rowInfo.ChildRows !=
null
&& rowInfo.ChildRows.Count > 0)
{
return
true
;
}
return
false
;
}
private
void
radGridView1_ViewCellFormatting(
object
sender, CellFormattingEventArgs e)
{
GridGroupExpanderCellElement cell = e.CellElement
as
GridGroupExpanderCellElement;
if
(cell !=
null
&& e.CellElement.RowElement
is
GridDataRowElement)
{
if
(!IsExpandable(cell.RowInfo))
{
cell.Expander.Visibility = Telerik.WinControls.ElementVisibility.Hidden;
}
else
{
cell.Expander.Visibility = Telerik.WinControls.ElementVisibility.Visible;
}
}
}
private
void
radGridView1_ChildViewExpanding(
object
sender, ChildViewExpandingEventArgs e)
{
e.Cancel = !IsExpandable(e.ParentRow);
}
private
GridViewTemplate GetParentTemplateByName(
string
name, RadGridView gvResults, NameAliasSet childParentSet)
{
string
parentName = childParentSet.ColumnAliases[name];
GridViewTemplate template = GetTemplateByNameRecursive(parentName, gvResults.MasterTemplate);
return
template ?? gvResults.MasterTemplate;
}
private
static
GridViewTemplate GetTemplateByNameRecursive(
string
name, GridViewTemplate template)
{
if
(template.Tag.ToString() == name)
return
template;
if
(template.Templates.Count > 0)
{
foreach
(GridViewTemplate viewTemplate
in
template.Templates)
{
GridViewTemplate result = GetTemplateByNameRecursive(name, viewTemplate);
if
(result !=
null
)
return
result;
}
}
return
null
;
}
private
static
bool
IsNotACollection(
string
collection)
{
return
collection != TestData.MainCollectionName &&
collection != TestData.CollectionAliasCollectionName &&
collection != TestData.ChildParentCollectionName;
}
}
}
TestData.cs (using NBuilder)
using
System;
using
System.Collections.Generic;
using
System.ComponentModel;
using
System.Linq;
using
System.Text;
using
FizzWare.NBuilder;
namespace
RadGridViewExample
{
public
class
MainDataClass
{
public
string
Name {
get
;
set
; }
public
string
Country {
get
;
set
; }
public
string
Remarks {
get
;
set
; }
public
string
Comments {
get
;
set
; }
public
string
Title {
get
;
set
; }
[Browsable(
false
)]
public
string
Id {
get
;
set
; }
[Browsable(
false
)]
public
decimal
X {
get
;
set
; }
[Browsable(
false
)]
public
decimal
Y {
get
;
set
; }
public
List<BuildingClass> BuildingCollection {
get
;
set
; }
public
List<SpaceshipClass> ShipCollection {
get
;
set
; }
}
public
static
class
TestData
{
public
static
readonly
string
MainCollectionName =
"Main"
;
public
static
readonly
string
ChildParentCollectionName =
"ParentChildCollection"
;
public
static
readonly
string
CollectionAliasCollectionName =
"CollectionAliasCollection"
;
public
static
DataBlob GetTestData()
{
DataBlob result =
new
DataBlob();
result.Data = GenerateMainResultList(10);
result.AliasDictionaries =
new
List<NameAliasSet>();
result.AliasDictionaries.Add(
new
NameAliasSet() { CollectionName =
"Main"
, ColumnAliases = GetMainDictionary()});
result.AliasDictionaries.Add(
new
NameAliasSet() { CollectionName =
"BuildingCollection"
, ColumnAliases = GetSub1Dictionary() });
result.AliasDictionaries.Add(
new
NameAliasSet() { CollectionName =
"ShipCollection"
, ColumnAliases = GetSub2Dictionary() });
result.AliasDictionaries.Add(
new
NameAliasSet() { CollectionName =
"TrainCollection"
, ColumnAliases = GetSubSubDictionary() });
result.AliasDictionaries.Add(
new
NameAliasSet() { CollectionName =
"ParentChildCollection"
, ColumnAliases = GetChildParentDictionary() });
result.AliasDictionaries.Add(
new
NameAliasSet() { CollectionName =
"CollectionAliasCollection"
, ColumnAliases = GetCollectionAliasDictionary() });
return
result;
}
public
static
List<MainDataClass> GenerateMainResultList(
int
size)
{
var rand =
new
RandomGenerator();
var test = rand.Next(0, 6);
return
Builder<MainDataClass>.CreateListOfSize(size)
.WhereTheFirst(3)
.Have(x => x.BuildingCollection =
new
List<BuildingClass>())
.Have(x => x.ShipCollection =
new
List<SpaceshipClass>())
.AndTheNext(2)
.Have(x => x.BuildingCollection =
new
List<BuildingClass>())
.Have(x => x.ShipCollection = GenerateSpaceshipList(3))
.AndTheNext(2)
.Have(x => x.BuildingCollection = GenerateBuildingList(3))
.Have(x => x.ShipCollection =
new
List<SpaceshipClass>())
.AndTheNext(3)
.Have(x => x.BuildingCollection = GenerateBuildingList(3))
.Have(x => x.ShipCollection = GenerateSpaceshipList(3))
.Build().ToList();
}
public
static
List<BuildingClass> GenerateBuildingList(
int
size)
{
if
(size == 0)
return
new
List<BuildingClass>();
return
Builder<BuildingClass>.CreateListOfSize(size)
.WhereAll()
.WhereRandom(1)
.Have(x => x.BuildingName =
"Yea! Building!"
)
.Build().ToList();
}
public
static
List<SpaceshipClass> GenerateSpaceshipList(
int
size)
{
if
(size == 0)
return
new
List<SpaceshipClass>();
return
Builder<SpaceshipClass>.CreateListOfSize(size)
.WhereAll()
.Have(x => x.TrainCollection = GenerateTrainList(5))
.WhereRandom(1)
.Have(x => x.StarshipType =
"Yea! Spaceship!"
)
.Build().ToList();
}
public
static
List<TrainClass> GenerateTrainList(
int
size)
{
if
(size == 0)
return
new
List<TrainClass>();
return
Builder<TrainClass>.CreateListOfSize(size)
.WhereRandom(1)
.Have(x => x.TrainType =
"Yea! Train!"
)
.Build().ToList();
}
public
static
Dictionary<
string
,
string
> GetMainDictionary()
{
Dictionary<
string
,
string
> dictionary =
new
Dictionary<
string
,
string
>();
dictionary.Add(
"Name"
,
"Name"
);
dictionary.Add(
"Country"
,
"Country"
);
dictionary.Add(
"Remarks"
,
"Remarks"
);
dictionary.Add(
"Comments"
,
"Comments"
);
dictionary.Add(
"Title"
,
"Title"
);
return
dictionary;
}
public
static
Dictionary<
string
,
string
> GetSub1Dictionary()
{
Dictionary<
string
,
string
> dictionary =
new
Dictionary<
string
,
string
>();
dictionary.Add(
"BuildingName"
,
"Building Name"
);
dictionary.Add(
"Purpose"
,
"Purpose"
);
return
dictionary;
}
public
static
Dictionary<
string
,
string
> GetSub2Dictionary()
{
Dictionary<
string
,
string
> dictionary =
new
Dictionary<
string
,
string
>();
dictionary.Add(
"StarshipType"
,
"Starship Type"
);
dictionary.Add(
"Engine"
,
"Engine"
);
return
dictionary;
}
public
static
Dictionary<
string
,
string
> GetSubSubDictionary()
{
Dictionary<
string
,
string
> dictionary =
new
Dictionary<
string
,
string
>();
dictionary.Add(
"TrainType"
,
"Train Type"
);
dictionary.Add(
"Name"
,
"Name"
);
return
dictionary;
}
public
static
Dictionary<
string
,
string
> GetChildParentDictionary()
{
Dictionary<
string
,
string
> dictionary =
new
Dictionary<
string
,
string
>();
dictionary.Add(
"BuildingCollection"
,
"Main"
);
dictionary.Add(
"ShipCollection"
,
"Main"
);
dictionary.Add(
"TrainCollection"
,
"ShipCollection"
);
return
dictionary;
}
public
static
Dictionary<
string
,
string
> GetCollectionAliasDictionary()
{
Dictionary<
string
,
string
> dictionary =
new
Dictionary<
string
,
string
>();
dictionary.Add(
"BuildingCollection"
,
"Buildings"
);
dictionary.Add(
"ShipCollection"
,
"Ships"
);
dictionary.Add(
"TrainCollection"
,
"Trains"
);
return
dictionary;
}
}
public
class
BuildingClass
{
public
string
BuildingName {
get
;
set
; }
public
string
Purpose {
get
;
set
; }
}
public
class
SpaceshipClass
{
public
string
StarshipType {
get
;
set
; }
public
string
Engine {
get
;
set
; }
public
List<TrainClass> TrainCollection {
get
;
set
; }
}
public
class
TrainClass
{
public
string
TrainType {
get
;
set
; }
public
string
Name {
get
;
set
; }
}
public
class
DataBlob
{
public
List<MainDataClass> Data {
get
;
set
; }
public
List<NameAliasSet> AliasDictionaries {
get
;
set
; }
}
public
class
NameAliasSet
{
public
string
CollectionName {
get
;
set
; }
public
Dictionary<
string
,
string
> ColumnAliases {
get
;
set
; }
}
}
0

Cat
Top achievements
Rank 1
answered on 16 Feb 2011, 06:23 PM
I was able to get 1) "Show the [+] only if one or more of the child collections has data," working by modifying the IsExpandable method, as seen below. This checks all child collections, not just the first. Still need help with 2 & 3 though!
private
bool
IsExpandable(GridViewRowInfo rowInfo)
{
GridViewHierarchyRowInfo hRowInfo = rowInfo
as
GridViewHierarchyRowInfo;
if
(hRowInfo ==
null
)
return
false
;
if
(hRowInfo.ChildRow !=
null
&& hRowInfo.ChildRow.ChildViewInfos.Count > 0)
{
int
count = 0;
return
hRowInfo.ChildRow.ChildViewInfos.Any(info => info.ChildRows.Count > 0);
}
return
false
;
}
0

Richard Slade
Top achievements
Rank 2
answered on 16 Feb 2011, 06:43 PM
Hi Cat,
I'm glad you've found a solution for the first part, regarding #3 - the tab row count. I haven't had chance to try this in a full version yet, but could you put the following into your code and give it a go. It assumes that there is a Master Template, and then two equal child templates below that.
Richard
I'm glad you've found a solution for the first part, regarding #3 - the tab row count. I haven't had chance to try this in a full version yet, but could you put the following into your code and give it a go. It assumes that there is a Master Template, and then two equal child templates below that.
void
radGridView1_ViewCellFormatting(
object
sender, CellFormattingEventArgs e)
{
if
(e.CellElement
is
GridDetailViewCellElement && e.CellElement.Children.Count != 0)
{
var pageView = e.CellElement.Children[0]
as
RadPageViewStripElement;
if
(pageView ==
null
)
{
return
;
}
pageView.Items[0].Text =
"Something "
+ e.CellElement.RowInfo.Parent.ChildRows.Count.ToString();
pageView.Items[1].Text =
"Something else "
+ ((GridViewTemplate)e.CellElement.RowInfo.Parent).Templates[0].ChildRows.Count.ToString();
}
}
Richard
0

Cat
Top achievements
Rank 1
answered on 16 Feb 2011, 08:45 PM
Hi Richard,
Thanks for the reply. I tried your code, but unfortunately it's still not quite right. The first line:
only returns the number of rows of the parent set, and the second line:
appears to only return zero, apparently because the templates (other than the master template) don't have the row counts. I think this is because I'm using an object collection as the datasource.
Thanks for the reply. I tried your code, but unfortunately it's still not quite right. The first line:
pageView.Items[0].Text =
"Something "
+ e.CellElement.RowInfo.Parent.ChildRows.Count.ToString();
only returns the number of rows of the parent set, and the second line:
pageView.Items[1].Text =
"Something else "
+ ((GridViewTemplate)e.CellElement.RowInfo.Parent).Templates[0].ChildRows.Count.ToString();
appears to only return zero, apparently because the templates (other than the master template) don't have the row counts. I think this is because I'm using an object collection as the datasource.
0

Richard Slade
Top achievements
Rank 2
answered on 16 Feb 2011, 08:48 PM
Hi.
Yes, I've since realised this and I'm going to try and put together a sample and see if I can get it to work the way that you need.
I'll get back to you as soon as I can.
regards
Richard
Yes, I've since realised this and I'm going to try and put together a sample and see if I can get it to work the way that you need.
I'll get back to you as soon as I can.
regards
Richard
0
Accepted

Richard Slade
Top achievements
Rank 2
answered on 16 Feb 2011, 09:18 PM
Hi again Cat,
Whilst I ewas preparing this, I had a look in the PITS system (public issue tracking system) for a bug that I think is in the hierarcy grid, but came upon this issue to be fixed (Issue ID 4717 - FIX When you delete all rows of a child view in tabbed hierarchy, the tab item should become invisible.), which means it's good news as Telerik are already aware of this and are going to be making this a feature in one of the upcoming releases. You can click on the link given to vote for the issue which helps raise it's priority.
More to follow
Richard
Whilst I ewas preparing this, I had a look in the PITS system (public issue tracking system) for a bug that I think is in the hierarcy grid, but came upon this issue to be fixed (Issue ID 4717 - FIX When you delete all rows of a child view in tabbed hierarchy, the tab item should become invisible.), which means it's good news as Telerik are already aware of this and are going to be making this a feature in one of the upcoming releases. You can click on the link given to vote for the issue which helps raise it's priority.
More to follow
Richard
0

Cat
Top achievements
Rank 1
answered on 16 Feb 2011, 09:45 PM
Thanks Richard!
I guess this means there isn't a workaround available yet? Well, at least I know not to spend much more time working on this. I'm going to consider this thread closed as it appears to be a design oversight. <sigh> I'll still keep a watch on this thread if you come up with more ideas though.
Again, thank you for your help Richard!
I guess this means there isn't a workaround available yet? Well, at least I know not to spend much more time working on this. I'm going to consider this thread closed as it appears to be a design oversight. <sigh> I'll still keep a watch on this thread if you come up with more ideas though.
Again, thank you for your help Richard!
0

Richard Slade
Top achievements
Rank 2
answered on 16 Feb 2011, 10:09 PM
No problem. i'll spend some time on it inbetween others to see if I can get something that's useful to you.
Regards,
Richard
Regards,
Richard
0
Hello Cat,
The following code should do the job:
Best wishes,
Jack
the Telerik team
The following code should do the job:
void
radGridView1_ViewCellFormatting(
object
sender, CellFormattingEventArgs e)
{
GridDetailViewCellElement cell = e.CellElement
as
GridDetailViewCellElement;
if
(cell !=
null
)
{
GridViewHierarchyRowInfo hierarchyRow = (GridViewHierarchyRowInfo)((GridViewDetailsRowInfo)cell.RowInfo).Owner;
for
(
int
i = 0; i < cell.PageViewElement.Items.Count; i++)
{
RadPageViewItem item = cell.PageViewElement.Items[i];
GridViewInfo viewInfo = hierarchyRow.Views[i];
item.Text = viewInfo.ViewTemplate.Caption + viewInfo.ChildRows.Count;
}
}
}
Jack
the Telerik team