Hi There,
I have a project that I have currently started to rebuild with the latest version of the telerik controls that seems to behave differently than the initial project did with version 2009 Q2. Basically I have a grid that has 3 child tabs for each row using this example:
Main Grid
User Information
--HR Data --Security Group Membership --Users who report to this person
the problem is HR Data always has information in the sub tab, however Security and / or Users who report might not.
the problem that I am getting now is that in the previous version of the gird I would see the child row with the headers and no information below so for instance:
HR - DATA
Full Name Phone Home Address
first last 555-111-222 example lane
Security Group
GroupName GroupOwner GroupType
the problem is now if there is no data for Security group the tab is now displayed as such:
HR - DATA
Full Name Phone Home Address
first last 555-111-222 example lane
Security Group
Full Name Phone Home Address
first last 555-111-222 example lane
If there is no data in the child tab grid, can I hide that tab or is it possible to set where I still see the column headers without any data in the grid.
thanks!
Jonathan
14 Answers, 1 is accepted
There were some large changes to the RadGridView from Q2 2010, however, I have not seen this exact behavior before. Are you able to post a small example of the issue using the format code block?
If you can provide an example, i'll be happy to help
All the best
Richard
here is the originial code that I was using to generate this:
Try
Dim
Rangetemplate
As
New
GridViewTemplate()
GV_Scopes.MasterGridViewTemplate.ChildGridViewTemplates.Add(Rangetemplate)
Dim
relation
As
New
GridViewRelation(GV_Scopes.MasterGridViewTemplate)
relation.ChildTemplate = Rangetemplate
relation.RelationName =
"Scopes"
relation.ParentColumnNames.Add(
"Sys_ID"
)
relation.ChildColumnNames.Add(
"Sys_ID"
)
relation.ParentColumnNames.Add(
"Scope_Address"
)
relation.ChildColumnNames.Add(
"Scope_Address"
)
GV_Scopes.Relations.Add(relation)
GV_Scopes.DataSource = ds.Tables(
"SCOPES"
)
Rangetemplate.DataSource = ds.Tables(
"SCOPE_RANGES"
)
Rangetemplate.Caption =
"Scope Ranges"
GV_Scopes.MasterGridViewTemplate.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill
GV_Scopes.MasterGridViewTemplate.ChildGridViewTemplates(0).AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill
Catch
ex
As
Exception
End
Try
Try
Dim
Optiontemplate
As
New
GridViewTemplate()
GV_Scopes.MasterGridViewTemplate.ChildGridViewTemplates.Add(Optiontemplate)
Dim
Optionrelation
As
New
GridViewRelation(GV_Scopes.MasterGridViewTemplate)
Optionrelation.ChildTemplate = Optiontemplate
Optionrelation.RelationName =
"OPTIONS"
Optionrelation.ParentColumnNames.Add(
"Sys_ID"
)
Optionrelation.ChildColumnNames.Add(
"Sys_ID"
)
Optionrelation.ParentColumnNames.Add(
"Scope_Address"
)
Optionrelation.ChildColumnNames.Add(
"Scope_Address"
)
GV_Scopes.Relations.Add(Optionrelation)
GV_Scopes.DataSource = ds.Tables(
"SCOPES"
)
Optiontemplate.DataSource = ds.Tables(
"SCOPE_OPTIONS"
)
Optiontemplate.Caption =
"Scope Options"
GV_Scopes.MasterGridViewTemplate.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill
GV_Scopes.MasterGridViewTemplate.ChildGridViewTemplates(1).AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill
Catch
ex
As
Exception
End
Try
Try
Dim
Reservationtemplate
As
New
GridViewTemplate()
GV_Scopes.MasterGridViewTemplate.ChildGridViewTemplates.Add(Reservationtemplate)
Dim
Reservationrelation
As
New
GridViewRelation(GV_Scopes.MasterGridViewTemplate)
Reservationrelation.ChildTemplate = Reservationtemplate
Reservationrelation.RelationName =
"RESERVATIONS"
Reservationrelation.ParentColumnNames.Add(
"Sys_ID"
)
Reservationrelation.ChildColumnNames.Add(
"Sys_ID"
)
Reservationrelation.ParentColumnNames.Add(
"Scope_Address"
)
Reservationrelation.ChildColumnNames.Add(
"Scope_Address"
)
GV_Scopes.Relations.Add(Reservationrelation)
GV_Scopes.DataSource = ds.Tables(
"SCOPES"
)
Reservationtemplate.DataSource = ds.Tables(
"SCOPE_RESERVATIONS"
)
Reservationtemplate.Caption =
"Scope Reservations"
GV_Scopes.MasterGridViewTemplate.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill
GV_Scopes.MasterGridViewTemplate.ChildGridViewTemplates(2).AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill
Catch
ex
As
Exception
End
Try
here is the code that i am using now since the code listed above is obsolete now:
Try
GV_Scopes.DataSource = ds
GV_Scopes.DataMember =
"SCOPES"
GV_Scopes.Columns(
"Sys_ID"
).IsVisible =
False
Catch
ex
As
Exception
MsgBox(ex.Message)
End
Try
Try
Dim
Rangetemplate
As
New
GridViewTemplate()
Rangetemplate.DataSource = ds
Rangetemplate.DataMember =
"SCOPE_RANGES"
Rangetemplate.Caption =
"Scope Ranges"
GV_Scopes.MasterTemplate.Templates.Add(Rangetemplate)
Dim
Rangerelation
As
New
GridViewRelation(GV_Scopes.MasterTemplate)
Rangerelation.ChildTemplate = Rangetemplate
Rangerelation.RelationName =
"Ranges"
Rangerelation.ParentColumnNames.Add(
"Sys_ID"
)
Rangerelation.ChildColumnNames.Add(
"Sys_ID"
)
Rangerelation.ParentColumnNames.Add(
"Scope_Address"
)
Rangerelation.ChildColumnNames.Add(
"Scope_Address"
)
GV_Scopes.Relations.Add(Rangerelation)
Rangetemplate.AutoSizeColumnsMode =GridViewAutoSizeColumnsMode.Fill
Rangetemplate.Columns(
"Sys_ID"
).IsVisible =
False
Rangetemplate.Columns(
"Scope_Name"
).IsVisible =
False
Rangetemplate.Columns(
"Scope_Address"
).IsVisible =
False
Catch
ex
As
Exception
End
Try
Try
Dim
Optiontemplate
As
New
GridViewTemplate()
Optiontemplate.DataSource = ds
Optiontemplate.DataMember =
"SCOPE_OPTIONS"
Optiontemplate.Caption =
"Scope Options"
GV_Scopes.MasterTemplate.Templates.Add(Optiontemplate)
Dim
OptionRelation
As
New
GridViewRelation(GV_Scopes.MasterTemplate)
OptionRelation.ChildTemplate = Optiontemplate
OptionRelation.RelationName =
"Options"
OptionRelation.ParentColumnNames.Add(
"Sys_ID"
)
OptionRelation.ChildColumnNames.Add(
"Sys_ID"
)
OptionRelation.ParentColumnNames.Add(
"Scope_Address"
)
OptionRelation.ChildColumnNames.Add(
"Scope_Address"
)
GV_Scopes.Relations.Add(OptionRelation)
Optiontemplate.AutoSizeColumnsMode =GridViewAutoSizeColumnsMode.Fill
Optiontemplate.Columns(
"Sys_ID"
).IsVisible =
False
Optiontemplate.Columns(
"Scope_Name"
).IsVisible =
False
Optiontemplate.Columns(
"Scope_Address"
).IsVisible =
False
Catch
ex
As
Exception
MsgBox(ex.Message)
End
Try
Try
Dim
Reservationtemplate
As
New
GridViewTemplate()
Reservationtemplate.DataSource = ds
Reservationtemplate.DataMember =
"SCOPE_RESERVATIONS"
Reservationtemplate.Caption =
"Scope Reservations"
GV_Scopes.MasterTemplate.Templates.Add(Reservationtemplate)
Dim
ReservationRelation
As
New
GridViewRelation(GV_Scopes.MasterTemplate)
ReservationRelation.ChildTemplate = Reservationtemplate
ReservationRelation.RelationName =
"Reservations"
ReservationRelation.ParentColumnNames.Add(
"Sys_ID"
)
ReservationRelation.ChildColumnNames.Add(
"Sys_ID"
)
ReservationRelation.ParentColumnNames.Add(
"Scope_Address"
)
ReservationRelation.ChildColumnNames.Add(
"Scope_Address"
)
GV_Scopes.Relations.Add(ReservationRelation)
Reservationtemplate.AutoSizeColumnsMode =GridViewAutoSizeColumnsMode.Fill
Reservationtemplate.Columns(
"Sys_ID"
).IsVisible =
False
Reservationtemplate.Columns(
"Scope_Name"
).IsVisible =
False
Reservationtemplate.Columns(
"Scope_Address"
).IsVisible =
False
Catch
ex
As
Exception
MsgBox(ex.Message)
End
Try
Try
Dim
Leasetemplate
As
New
GridViewTemplate()
Leasetemplate.DataSource = ds
Leasetemplate.DataMember =
"SCOPE_LEASES"
Leasetemplate.Caption =
"Scope Leases"
GV_Scopes.MasterTemplate.Templates.Add(Leasetemplate)
Dim
LeaseRelation
As
New
GridViewRelation(GV_Scopes.MasterTemplate)
LeaseRelation.ChildTemplate = Leasetemplate
LeaseRelation.RelationName =
"Options"
LeaseRelation.ParentColumnNames.Add(
"Sys_ID"
)
LeaseRelation.ChildColumnNames.Add(
"Sys_ID"
)
LeaseRelation.ParentColumnNames.Add(
"Scope_Address"
)
LeaseRelation.ChildColumnNames.Add(
"Scope_Address"
)
GV_Scopes.Relations.Add(LeaseRelation)
Leasetemplate.AutoSizeColumnsMode =GridViewAutoSizeColumnsMode.Fill
Leasetemplate.Columns(
"Sys_ID"
).IsVisible =
False
Leasetemplate.Columns(
"Scope_Address"
).IsVisible =
False
Catch
ex
As
Exception
'MsgBox(ex.Message)
End
Try
this output gives me what you see on the images New-tab1 and New-tab2.
from what i can tell from the code that i am using it is relatively the same just getting rid of the old obsolete data and using the new.
thanks for looking!
Jonathan
Actually, in my tests (Q3 2010) apparently once you selected a tab with no rows it won't display the rows for the tabs that have rows, unless you resize the form...
I've found a workaround for this but it's not very clean... can you please try this and let me know:
using
System.Collections.Generic;
using
System.Windows.Forms;
using
Telerik.WinControls.UI;
public
partial
class
Form1 : Form
{
private
RadGridView radGridView1;
private
List<Product> products;
private
List<Car> cars;
private
List<Customer> customers;
public
Form1()
{
InitializeComponent();
this
.Size =
new
System.Drawing.Size(640, 480);
this
.Controls.Add(radGridView1 =
new
RadGridView());
radGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill;
radGridView1.Dock = DockStyle.Fill;
InitDataSources();
InitRelations();
radGridView1.ViewCellFormatting +=
new
CellFormattingEventHandler(radGridView1_ViewCellFormatting);
}
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
;
}
foreach
(var item
in
pageView.Items)
{
item.Click -=
new
System.EventHandler(item_Click);
item.Click +=
new
System.EventHandler(item_Click);
}
}
}
void
item_Click(
object
sender, System.EventArgs e)
{
var pageItem = sender
as
RadPageViewItem;
var detailCell = pageItem.Owner.Parent
as
GridDetailViewCellElement;
detailCell.RowInfo.InvalidateRow();
}
private
void
InitDataSources()
{
customers =
new
List<Customer>();
customers.Add(
new
Customer(1,
"John Smith"
));
customers.Add(
new
Customer(2,
"Jane Doe"
));
products =
new
List<Product>();
products.Add(
new
Product(1, 1,
"Computer X"
));
products.Add(
new
Product(2, 1,
"Mobile Y"
));
//products.Add(new Product(1, 1, "Hairdrier"));
cars =
new
List<Car>();
//cars.Add(new Car(1, 1, "VW"));
cars.Add(
new
Car(1, 2,
"A3"
));
}
private
void
InitRelations()
{
radGridView1.DataSource = customers;
var productsTemplate =
new
GridViewTemplate();
productsTemplate.DataSource = products;
productsTemplate.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill;
radGridView1.MasterTemplate.Templates.Add(productsTemplate);
productsTemplate.Caption =
"Products"
;
var productsRelation =
new
GridViewRelation(radGridView1.MasterTemplate);
productsRelation.ChildTemplate = productsTemplate;
productsRelation.RelationName =
"ParentChild"
;
productsRelation.ParentColumnNames.Add(
"Id"
);
productsRelation.ChildColumnNames.Add(
"CustomerId"
);
radGridView1.Relations.Add(productsRelation);
var carsTemplate =
new
GridViewTemplate();
carsTemplate.DataSource = cars;
carsTemplate.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill;
radGridView1.MasterTemplate.Templates.Add(carsTemplate);
carsTemplate.Caption =
"Cars"
;
var carsRelation =
new
GridViewRelation(radGridView1.MasterTemplate);
carsRelation.ChildTemplate = carsTemplate;
carsRelation.RelationName =
"ParentChild"
;
carsRelation.ParentColumnNames.Add(
"Id"
);
carsRelation.ChildColumnNames.Add(
"CustomerId"
);
radGridView1.Relations.Add(carsRelation);
}
}
public
class
Customer
{
public
int
Id
{
get
;
set
;
}
public
string
Name
{
get
;
set
;
}
public
Customer(
int
id,
string
name)
{
this
.Id = id;
this
.Name = name;
}
}
public
class
Product
{
public
int
Id
{
get
;
set
;
}
public
int
CustomerId
{
get
;
set
;
}
public
string
ProductName
{
get
;
set
;
}
public
Product(
int
id,
int
customerId,
string
name)
{
this
.Id = id;
this
.CustomerId = customerId;
this
.ProductName = name;
}
}
public
class
Car
{
public
int
Id
{
get
;
set
;
}
public
int
CustomerId
{
get
;
set
;
}
public
string
CarName
{
get
;
set
;
}
public
Car(
int
id,
int
customerId,
string
name)
{
this
.Id = id;
this
.CustomerId = customerId;
this
.CarName = name;
}
}
Hope this helps, if you have any other questions or comments, please let me know,
Best Regards,
Emanuel Varga
Telerik WinForms MVP
P.s. sorry for the code in c# didn't reload the page before posting, if you need any help converting just let me know (or use the telerik code converter)
Anyway, i believe that if you use the workaround i have provided it will solve your problem.
Best Regards,
Emanuel Varga
Telerik WinForms MVP
i am having one problem with converting to VB and that is the "VAR" as there seems to be no equivilent in VB for this:
foreach (var item in pageView.Items)
{
item.Click -= new System.EventHandler(item_Click);
item.Click += new System.EventHandler(item_Click);
}
I also can not seem to specifiy radGridView1.ViewCellFormatting += New CellFormattingEventHandler(radGridView1_ViewCellFormatting)
in the new loaded part of the form.
Not sure if I fully understood, but i have no problems clicking on other tabs in the childs to see data. see New-tab3 as this was just iterating through all tabs without resizing the form.
thanks again!
Jonathan
this would translate as something like this
For
Each
item
In
Me
.PageView.Items
RemoveHandler
item.Click,
AddressOf
Item_Click
AddHandler
item.Click,
AddressOf
Item_Click
Next
Richard
AddHandler
RadGridView1.ViewCellFormatting,
AddressOf
RadGridView1_ViewCellFormatting
Thanks for the help, i told them the converter was having some problems with the event conversion but += and -= are widely used and it could be hard deciding when to convert or when not to convert them.
Jonathan, (in the latest version Q3 SP1) if you open a tab without any data on it, and switch to a tab with data on it (or if you are on a tab with data and after switching to a tab with no data and then to a tab with data) you will not see anything in any of the tabs you are opening after that (I'm guessing bug somewhere). So in order to fix this, the easiest things to do is to register for a Tab click (RadPageViewItem) event in order to call a refresh on the details row we are on, so that data will be reloaded.
Hope this helps, if you have any other questions or comments, please let me know,
Best Regards,
Emanuel Varga
Telerik WinForms MVP
@Emanuel, yes, I've not seen event handlers converted well by any code converter actually. The Telerik one though does a really good job at most of it.
@Jonathan - I've also tried this out now, and have come to the same conclusion as Emanuel. I think this is probably the best way to go and I can't offer a better solution than the one Emanuel has come up with at this time.
Regards,
Richard
A "cleaner" solution would be to just register to the page view strip SelectedItem PropertyChanged event and if property name is IsSelected refresh the row, it's a tad cleaner because you are not only registering the click event, it goes something like this:
C#
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.SelectedItem.PropertyChanged -=
new
System.ComponentModel.PropertyChangedEventHandler(SelectedItem_PropertyChanged);
pageView.SelectedItem.PropertyChanged +=
new
System.ComponentModel.PropertyChangedEventHandler(SelectedItem_PropertyChanged);
}
}
void
SelectedItem_PropertyChanged(
object
sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if
(e.PropertyName ==
"IsSelected"
)
{
var pageItem = sender
as
RadPageViewItem;
var detailCell = pageItem.Owner.Parent
as
GridDetailViewCellElement;
detailCell.RowInfo.InvalidateRow();
}
}
VB:
Private
Sub
radGridView1_ViewCellFormatting(sender
As
Object
, e
As
CellFormattingEventArgs)
If
TypeOf
e.CellElement
Is
GridDetailViewCellElement
AndAlso
e.CellElement.Children.Count <> 0
Then
Dim
pageView = TryCast(e.CellElement.Children(0), RadPageViewStripElement)
If
pageView
Is
Nothing
Then
Return
End
If
RemoveHandler
pageView.SelectedItem.PropertyChanged,
AddressOf
SelectedItem_PropertyChanged
AddHandler
pageView.SelectedItem.PropertyChanged,
AddressOf
SelectedItem_PropertyChanged
End
If
End
Sub
Private
Sub
SelectedItem_PropertyChanged(sender
As
Object
, e
As
System.ComponentModel.PropertyChangedEventArgs)
If
e.PropertyName =
"IsSelected"
Then
Dim
pageItem = TryCast(sender, RadPageViewItem)
Dim
detailCell = TryCast(pageItem.Owner.Parent, GridDetailViewCellElement)
detailCell.RowInfo.InvalidateRow()
End
If
End
Sub
Hope this helps, if you have any other questions or comments, please let me know,
Best Regards,
Emanuel Varga
Telerik WinForms MVP
I'd suggest one small change to this. Instead of inspecting the PropertyName, it's cleaner to inspect the property type
Private
Sub
SelectedItem_PropertyChanged(
ByVal
sender
As
Object
,
ByVal
e
As
RadPropertyChangedEventArgs)
If
e.
Property
Is
RadPageViewItem.IsSelectedProperty
Then
Dim
pageItem = TryCast(sender, RadPageViewItem)
Dim
detailCell = TryCast(pageItem.Owner.Parent, GridDetailViewCellElement)
detailCell.RowInfo.InvalidateRow()
End
If
End
Sub
Hope that helps, but let me know if you have any further questions or comments
Richard
AddHandler
pageView.SelectedItem.RadPropertyChanged,
AddressOf
SelectedItem_PropertyChanged
only thing that I can think that might be different in my set up vs how you are testing is with the form. this is my setup:
Rad Ribbon Form
Rad Doc as auto mdi form
I am launching a seperate form into a document pane inside the doc from a treeview that is in a doc'ed pannel on the left.
the form that I am launching into the Document Pane is comprised of a radpageview that is filling the entire form. The radpageview has 12 tabs or 12 pages if you will. Each of these pages has a RadGridView. Only one of these pages uses the hierarchy grid for displaying information.
the form is using Office 2007 theming and every other component (doc, grid, pageview, etc) is using office2010 theming.
i am able to see the grid in each of the tabs regardless if I have clicked on a tab that does not have data. the only issue for me is that if a tab does not have data, then it defaults to showing the data of the last tab that was clicked that does have data. I would like to have the problem that you are stating as at least you have been able to offer a work around and would be better then users being confused by my "Scope Options" tab showing "Scope Range" information.
thanks again for your help here!
Jonathan
@Jonathan Hylton, it looks that the issue which you are describing is similar to the one that Emanuel has reported, but I was not able to reproduce it and because of this I am not able to find a suitable workaround. Please open a support ticket and send me your application and describe in detail how to reproduce the issue. This will help me to understand it and to provide you with adequate support.
I am looking forward to your project.
Kind regards,
Jack
the Telerik team