This is a migrated thread and some comments may be shown as answers.

child tabs in Hierarchy multiple relations

14 Answers 292 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Jonathan Hylton
Top achievements
Rank 1
Jonathan Hylton asked on 07 Jan 2011, 09:09 AM

 

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

Sort by
0
Richard Slade
Top achievements
Rank 2
answered on 07 Jan 2011, 10:15 AM
Hello,

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
0
Jonathan Hylton
Top achievements
Rank 1
answered on 07 Jan 2011, 10:43 AM
Thanks 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

this would give the output that you will find in the pictures listed as OLD-tab1 & Old-tab2

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
0
Emanuel Varga
Top achievements
Rank 1
answered on 07 Jan 2011, 11:26 AM
Hello 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
0
Emanuel Varga
Top achievements
Rank 1
answered on 07 Jan 2011, 11:30 AM
Hello again,

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
0
Jonathan Hylton
Top achievements
Rank 1
answered on 07 Jan 2011, 12:44 PM
thanks for looking into this!

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
0
Richard Slade
Top achievements
Rank 2
answered on 07 Jan 2011, 12:50 PM
Hi,

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
Regards
Richard
0
Richard Slade
Top achievements
Rank 2
answered on 07 Jan 2011, 12:51 PM
and this one (forgot to add before)
AddHandler RadGridView1.ViewCellFormatting, AddressOf RadGridView1_ViewCellFormatting
Richard
0
Emanuel Varga
Top achievements
Rank 1
answered on 07 Jan 2011, 12:57 PM
Hello Richard,

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

0
Richard Slade
Top achievements
Rank 2
answered on 07 Jan 2011, 01:02 PM
Hi Guys,

@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
0
Emanuel Varga
Top achievements
Rank 1
answered on 07 Jan 2011, 01:20 PM
Hello again guys,

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
0
Richard Slade
Top achievements
Rank 2
answered on 07 Jan 2011, 01:44 PM
Hi Guys,

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
0
Richard Slade
Top achievements
Rank 2
answered on 07 Jan 2011, 01:45 PM
Apologies, forgot to add you shoud also change the handler from PropertyChanged to RadPropertyChanged
AddHandler pageView.SelectedItem.RadPropertyChanged, AddressOf SelectedItem_PropertyChanged
Richard
0
Jonathan Hylton
Top achievements
Rank 1
answered on 07 Jan 2011, 03:52 PM
Thanks, However very interesting as I am not getting this type of behavior. I think I am running SP1 or at least the version that I am running in Add / remove programs states that is version 10.3.1220.0

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
0
Jack
Telerik team
answered on 12 Jan 2011, 10:36 AM
@Emanuel, thank you for reporting this issue and for the provider work around. I added the issue in our bug tracking system and it will be addressed in our upcoming release - Q1 2011.

@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
Q3’10 SP1 of RadControls for WinForms is available for download; also available is the Q1'11 Roadmap for Telerik Windows Forms controls.
Tags
GridView
Asked by
Jonathan Hylton
Top achievements
Rank 1
Answers by
Richard Slade
Top achievements
Rank 2
Jonathan Hylton
Top achievements
Rank 1
Emanuel Varga
Top achievements
Rank 1
Jack
Telerik team
Share this question
or