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 TryTry 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 TryTry 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 Tryhere 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 Trythis 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 NextRichard
AddHandler RadGridView1.ViewCellFormatting, AddressOf RadGridView1_ViewCellFormattingThanks 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 IfEnd SubPrivate 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 IfEnd SubHope 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 IfEnd SubHope that helps, but let me know if you have any further questions or comments
Richard
AddHandler pageView.SelectedItem.RadPropertyChanged, AddressOf SelectedItem_PropertyChangedonly 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