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

Hierarchical Data Grid

24 Answers 389 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Leo
Top achievements
Rank 2
Leo asked on 21 Oct 2010, 11:04 AM
Hello, it's been hours since I've tried and searched for any samples that implements hierarchical data using Linq to SQL. It says in your feature product that it automatically detects hierarchy relationship. Could you please provide a tutorial on how to implement or bind a datacontext to the datatemplate of my hierarchychildtemplate? 

And, i currenty coded
void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            
            m_dcData = new DataAccessDataContext();
            m_dcData.Log = Console.Out;
            rgvData.ItemsSource = m_dcData.Orders;
 
        }


And I tried to commenting out rgvData.ItemsSource = m_dcData.Orders and tried Binding the Linq to SQL class to xaml but I failed. How do I bind a Linq to SQL Class in xaml file so that in my second hierarchical data grid it shows the table that is related to the parent node?
<Grid>
        <Border telerikQuickStart:ThemeAwareBackgroundBehavior.IsEnabled="True" />
        <telerik:RadGridView x:Name="rgvData" CanUserFreezeColumns="False" GridLinesVisibility="Horizontal" ItemsSource="" IsReadOnly="True" AutoGenerateColumns="False">
            <telerik:RadGridView.ChildTableDefinitions>
                <telerik:GridViewTableDefinition />
            </telerik:RadGridView.ChildTableDefinitions>
            <telerik:RadGridView.Columns>
                <telerik:GridViewDataColumn DataMemberBinding="{Binding OrderDate}" Header="Order Date" />
                <telerik:GridViewDataColumn DataMemberBinding="{Binding EmployeeID}" Header="Employee" />
                <telerik:GridViewDataColumn DataMemberBinding="{Binding Freight}" />
                <telerik:GridViewDataColumn DataMemberBinding="{Binding ShipCountry}" Header="Ship Country" />
                <telerik:GridViewDataColumn DataMemberBinding="{Binding ShipCity}" Header="Ship City" />
            </telerik:RadGridView.Columns>
            <telerik:RadGridView.HierarchyChildTemplate>
                <DataTemplate>
                    <telerik:RadGridView x:Name="RadGridView1" CanUserFreezeColumns="False" AutoGenerateColumns="False" ShowGroupPanel="False" IsReadOnly="True">
                        <telerik:RadGridView.Columns>
                            <telerik:GridViewDataColumn DataMemberBinding="{Binding CustomerID}" Header="Customer ID" />
                            <telerik:GridViewDataColumn DataMemberBinding="{Binding Address}" Header="Address" />
                            <telerik:GridViewDataColumn DataMemberBinding="{Binding City}" Header="City" />
                            <telerik:GridViewDataColumn DataMemberBinding="{Binding Country}" Header="Country" />
                        </telerik:RadGridView.Columns>
                    </telerik:RadGridView>
                </DataTemplate>
            </telerik:RadGridView.HierarchyChildTemplate>
        </telerik:RadGridView>
    </Grid>

Thanks!

24 Answers, 1 is accepted

Sort by
0
Yavor Georgiev
Telerik team
answered on 21 Oct 2010, 11:24 AM
Hello Leo,

 You need to set the ItemsSource property of the RadGridView in the HierarchyChildTemplate like 'ItemsSource="{Binding MyProperty}"' where MyProperty is the relevant property of the parent class in the relation.

 Please refer to this blog post to see how you can bind RadGridView to a Linq to SQL context in XAML.

Regards,
Yavor Georgiev
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Leo
Top achievements
Rank 2
answered on 21 Oct 2010, 11:32 AM
Thanks for your fast answer.

I already referred to that blog. But still not displaying the items on my level 2 data grid. 
0
Yavor Georgiev
Telerik team
answered on 21 Oct 2010, 11:42 AM
Hi Leo,

 Are you setting the ItemsSource of the RadGridView in the HierarchyChildTemplate?

All the best,
Yavor Georgiev
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Leo
Top achievements
Rank 2
answered on 21 Oct 2010, 11:46 AM
Yes I want to set the ChildTemplate's itemsource behind the code so that I will no longer bind.

<DataTemplate>
                    <telerik:RadGridView x:Name="RadGridView1" CanUserFreezeColumns="False" AutoGenerateColumns="False" ShowGroupPanel="False" IsReadOnly="True">
                        <telerik:RadGridView.Columns>
                            <telerik:GridViewDataColumn DataMemberBinding="{Binding CustomerID}" Header="Customer ID" />
                            <telerik:GridViewDataColumn DataMemberBinding="{Binding Address}" Header="Address" />
                            <telerik:GridViewDataColumn DataMemberBinding="{Binding City}" Header="City" />
                            <telerik:GridViewDataColumn DataMemberBinding="{Binding Country}" Header="Country" />
                        </telerik:RadGridView.Columns>
                    </telerik:RadGridView>
                </DataTemplate>

Let's say behind the code when this.Loaded+= event is launched, I want the RadGridView1.ItemsSource = m_dcData.Orders to make it simple rather than binding it but I cannot see my RadGridView1 name only the parent one. I tried rgvData.HierarchicalChild.something but it still did not work, Any idea? Thanks for your help
0
Accepted
Yavor Georgiev
Telerik team
answered on 21 Oct 2010, 11:49 AM
Hello Leo,

 Controls in templates are not accessible like normal controls are. To make it work you need to set the ItemsSource inside the template itself, so that your code becomes something like:
<DataTemplate>
                    <telerik:RadGridView x:Name="RadGridView1" CanUserFreezeColumns="False" AutoGenerateColumns="False" ShowGroupPanel="False" IsReadOnly="True" ItemsSource="{Binding Customers}">
                        <telerik:RadGridView.Columns>
                            <telerik:GridViewDataColumn DataMemberBinding="{Binding CustomerID}" Header="Customer ID" />
                            <telerik:GridViewDataColumn DataMemberBinding="{Binding Address}" Header="Address" />
                            <telerik:GridViewDataColumn DataMemberBinding="{Binding City}" Header="City" />
                            <telerik:GridViewDataColumn DataMemberBinding="{Binding Country}" Header="Country" />
                        </telerik:RadGridView.Columns>
                    </telerik:RadGridView>
                </DataTemplate>


Best wishes,
Yavor Georgiev
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Leo
Top achievements
Rank 2
answered on 21 Oct 2010, 11:57 AM
It did work! Thank you so much! I will blog about telerik's support for their products! This is just like MSDN's  full support to their developers. Thank you so much Sir!
0
Leo
Top achievements
Rank 2
answered on 21 Oct 2010, 12:03 PM
By the way sir I got one more question. How do you set the RadDataGrid by default when inserting new data that there's already a blank rows for the next data to be added? 

Let's say on my level 2 hierarchy there's no data for Table 1 from Table 2 and I would like to add a data to my level 2 hierarchy. Is it possible to set by default that there's a blank row for the level 2 if there's no data and the user can add data to it? Thanks
0
Accepted
Yavor Georgiev
Telerik team
answered on 21 Oct 2010, 12:04 PM
Hello Leo,

 You can set the ShowInsertRow property of RadGridView to True.

Sincerely yours,
Yavor Georgiev
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Leo
Top achievements
Rank 2
answered on 21 Oct 2010, 12:19 PM
Another question, How do I update the inserted row in my level 2 hierarchy data in my database? Is there an event for it since I cannot access it behind the code ?
0
Yavor Georgiev
Telerik team
answered on 21 Oct 2010, 12:31 PM
Hi Leo,

 The inserted row should be added automatically to your Linq to SQL context. You need to call the SubmitChanges() method on your DataAccessDataContext instance for the changes to be pushed back to the database.

Kind regards,
Yavor Georgiev
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Leo
Top achievements
Rank 2
answered on 21 Oct 2010, 12:37 PM
HI thanks for your answer but there is something wrong it did not update, is there something I did not properly coded?

void MainWindow_Loaded(object sender, RoutedEventArgs e)
       {
           
           m_dcData = new DataAccessDataContext();
           m_dcData.Log = Console.Out;
           var Customers = from O in m_dcData.Customers select O;
           rgvData.ItemsSource = Customers;
           rgvData.ShowInsertRow = true;
           this.Unloaded += new RoutedEventHandler(MainWindow_Unloaded);
       }
 
       void MainWindow_Unloaded(object sender, RoutedEventArgs e)
       {
           m_dcData.SubmitChanges();
       }
0
Yavor Georgiev
Telerik team
answered on 21 Oct 2010, 12:46 PM
Hi Leo,

 Since you're binding to the result of a query, you need to handle the CollectionChanged event of the RadGridView's Items collection like so:
public Window1()
{
    this.InitializeComponent();
    this.gridView.Items.CollectionChanged += new NotifyCollectionChangedEventHandler(Items_CollectionChanged);
}
private void Items_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    if (e.Action == NotifyCollectionChangedAction.Add)
    {
        foreach (Customer item in e.NewItems)
        {
            db.Customers.InsertOnSubmit(item);
        }
    }
    if (e.Action == NotifyCollectionChangedAction.Remove)
    {
        foreach (Customer item in e.OldItems)
        {
            db.Customers.DeleteOnSubmit(item);
        }
    }
}

Where db is your existing context.

Greetings,
Yavor Georgiev
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Leo
Top achievements
Rank 2
answered on 21 Oct 2010, 12:53 PM
Hi, still not inserting data. I've a got a problem too.

When I put the property showinsertrow = true and tried to click on my parent node to add data there, i cannot click it. but on my level 2 data when i click the click here to add new item it did show me a blank row but unfortunately it still did not insert when i reload my window.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Telerik.Windows.Controls;
using System.Collections.Specialized;
 
namespace _3_I
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        DataAccessDataContext m_dcData;
        public MainWindow()
        {
            InitializeComponent();
            this.Loaded += new RoutedEventHandler(MainWindow_Loaded);
            this.rgvData.Items.CollectionChanged += new NotifyCollectionChangedEventHandler(Items_CollectionChanged);
        }
 
        private void Items_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (e.Action == NotifyCollectionChangedAction.Add)
            {
                foreach (Customer item in e.NewItems)
                {
                    m_dcData.Customers.InsertOnSubmit(item);
                }
            }
            if (e.Action == NotifyCollectionChangedAction.Remove)
            {
                foreach (Customer item in e.OldItems)
                {
                    m_dcData.Customers.DeleteOnSubmit(item);
                }
            }
        }
        void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
 
            m_dcData = new DataAccessDataContext();
            m_dcData.Log = Console.Out;
            rgvData.ShowInsertRow = true;
        }
    }
}
0
Accepted
Yavor Georgiev
Telerik team
answered on 21 Oct 2010, 02:04 PM
Hello Leo,

 I'm attaching a sample application built around the AdventureWorks database that demonstrates how to add and delete items from the database in RadGridView.

All the best,
Yavor Georgiev
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Leo
Top achievements
Rank 2
answered on 21 Oct 2010, 02:12 PM
Hello, there's an error.

'The invocation of the constructor on type 'Sample.MainWindow' that matches the specified binding constraints threw an exception.' Line number '6' and line position '9'.
0
Yavor Georgiev
Telerik team
answered on 21 Oct 2010, 02:14 PM
Hello Leo,

 Do you have the AdventureWorks database installed? Did you modify the connection string in app.config to match your local setup?

Sincerely yours,
Yavor Georgiev
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Leo
Top achievements
Rank 2
answered on 21 Oct 2010, 02:16 PM
Unfortunately, no. Where can I download the AdventureWorks DB? Cause I only have Northwind, and no I haven't modify the connection string in app.config.

Thanks for your help!
0
Yavor Georgiev
Telerik team
answered on 21 Oct 2010, 02:24 PM
Hi Leo,

 You can find the AdventureWorks database here.

Sincerely yours,
Yavor Georgiev
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Leo
Top achievements
Rank 2
answered on 21 Oct 2010, 02:33 PM
Am I downloading the right now, lol I think the file size im downloading is too big for a sample database? 82.3 mb. and SQL 2008 R2 for RTM? What's R2? 
0
Leo
Top achievements
Rank 2
answered on 21 Oct 2010, 03:11 PM
Hello, your sample app still doesn't insert a new data.

I tried searching old threads and modified them and it did add and delete the data 
using System.ComponentModel;
using System.Windows.Input;
using Telerik.Windows.Data;
 
 
namespace Sample.ViewModels
{
    public class StudentViewModel : INotifyPropertyChanged
    {
        private readonly AdventureWorksDataContext context;
        private readonly DelegateCommand<Student> addStudentCommand;
        private readonly DelegateCommand<Student> deleteStudentCommand;
        private readonly QueryableCollectionView studentsCollectionView;
        private Student selectedStudent;
 
        public StudentViewModel()
        {
            this.context = new AdventureWorksDataContext();
            this.addStudentCommand = new DelegateCommand<Student>(this.AddStudent);
            this.deleteStudentCommand = new DelegateCommand<Student>(this.DeleteStudent, this.CanDeleteStudent);
 
            this.studentsCollectionView = new QueryableCollectionView(this.context.Students);
        }
 
        public event PropertyChangedEventHandler PropertyChanged;
 
        public ICommand AddStudentCommand
        {
            get { return this.addStudentCommand; }
        }
 
        public ICommand DeleteStudentCommand
        {
            get { return this.deleteStudentCommand; }
        }
 
        public QueryableCollectionView Students
        {
            get { return this.studentsCollectionView; }
        }
 
        public Student SelectedStudent
        {
            get { return this.selectedStudent; }
            set
            {
                this.selectedStudent = value;
                this.OnPropertyChanged("SelectedStudent");
                this.deleteStudentCommand.RaiseCanExecuteChanged();
            }
        }
 
        protected virtual void OnPropertyChanged(PropertyChangedEventArgs args)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, args);
            }
        }
 
        protected void OnPropertyChanged(string propertyName)
        {
            this.OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
        }
 
        private void AddStudent(Student student)
        {
            var newStudent = student ?? DefaultStudent;
            this.InsertAndSubmitStudent(newStudent);
 
            this.Students.Refresh();
        }
 
        private static Student DefaultStudent
        {
            get
            {
                return new Student { StudentFN = "Default Name" };
            }
        }
 
        private void InsertAndSubmitStudent(Student student)
        {
            this.context.Students.InsertOnSubmit(student);
            this.context.SubmitChanges();
        }
 
        private void DeleteStudent(Student student)
        {
            var deleteStudent = student ?? this.selectedStudent;
            this.DeleteAndSubmitStudent(deleteStudent);
            this.Students.Refresh();
        }
 
        private void DeleteAndSubmitStudent(Student student)
        {
            this.context.Students.DeleteOnSubmit(student);
            this.context.SubmitChanges();
        }
 
        private bool CanDeleteStudent(Student student)
        {
            if (student != null)
                return true;
            return this.selectedStudent != null;
        }
 
    }
}
ViewModel.cs

<Window x:Class="Sample.MainWindow"
        Title="MainWindow" Height="350" Width="525"
        xmlns:local="clr-namespace:Sample.ViewModels">
    <Window.Resources>
        <local:StudentViewModel x:Key="StudentViewModel"></local:StudentViewModel>
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
 
        <telerik:RadGridView x:Name="radGridView1" ShowInsertRow="True"
                ItemsSource="{Binding Students, Source={StaticResource StudentViewModel}}"
                SelectedItem="{Binding SelectedStudent, Source={StaticResource StudentViewModel}}" >
            <telerik:RadGridView.ChildTableDefinitions>
                <telerik:GridViewTableDefinition />
            </telerik:RadGridView.ChildTableDefinitions>
            <telerik:RadGridView.HierarchyChildTemplate>
                <DataTemplate>
                    <telerik:RadGridView ItemsSource="{Binding CustomerAddresses}" AutoGenerateColumns="False" ShowInsertRow="True">
                        <telerik:RadGridView.Columns>
                            <telerik:GridViewDataColumn DataMemberBinding="{Binding AddressType}"/>
                            <telerik:GridViewDataColumn DataMemberBinding="{Binding Address.AddressLine1}"/>
                            <telerik:GridViewDataColumn DataMemberBinding="{Binding Address.City}"/>
                            <telerik:GridViewDataColumn DataMemberBinding="{Binding Address.CountryRegion}"/>
                        </telerik:RadGridView.Columns>
                    </telerik:RadGridView>
                </DataTemplate>
            </telerik:RadGridView.HierarchyChildTemplate>
        </telerik:RadGridView>
        <WrapPanel Grid.Row="2">
            <telerik:RadButton>Save changes</telerik:RadButton>
            <Button
                Content="Add New"
                Command="{Binding AddStudentCommand, Source={StaticResource StudentViewModel}}" />
            <Button
                Content="Delete selected"
                Command="{Binding DeleteStudentCommand, Source={StaticResource StudentViewModel}}"
                CommandParameter="{Binding SelectedItem, ElementName=radGridView1}" />
        </WrapPanel>
    </Grid>
</Window>
Here's the xaml file

Now it smoothly adds data and deletes data. But I have a problem if I uncomment out this part on my MainPage.xaml.cs which literally shouldn't have any code beside Initialize(); for it to run smoothly.

  // only shows customers with addresses for the sake of brevity.
    //    this.radGridView1.ItemsSource = context.Students.ToList();
    //    this.radGridView1.Items.CollectionChanged += new NotifyCollectionChangedEventHandler(Items_CollectionChanged);
    //}
 
//    void radGridView1_AddingNewDataItem(object sender, GridViewAddingNewEventArgs e)
//    {
//        e.NewObject = new Student();
//    }
 
    //private void Items_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    //{
    //    if (e.Action == NotifyCollectionChangedAction.Add)
    //    {
    //        this.context.Students.InsertAllOnSubmit(e.NewItems.OfType<Student>());
    //    }
    //    else if (e.Action == NotifyCollectionChangedAction.Remove)
    //    {
    //        this.context.Students.DeleteAllOnSubmit(e.OldItems.OfType<Student>());
    //    }
    //}
 
//    private void RadButton_Click(object sender, RoutedEventArgs e)
//    {
//        var changes = this.context.GetChangeSet();
//        radGridView1.BeginInsert();
//        MessageBox.Show(string.Format("There are {0} inserts and {1} deletes pending.", changes.Inserts.Count, changes.Deletes.Count));
//    }

Now when I try to click the add new item it doesn't show blank row. Please help. Thanks
0
Leo
Top achievements
Rank 2
answered on 22 Oct 2010, 01:46 PM
Help,please. Been almost 24 hours figuring out why it doesn't add or show.
0
Yavor Georgiev
Telerik team
answered on 25 Oct 2010, 12:29 PM
Hello Leo,

 I don't call SubmitChanges on the Linq To SQL context in my sample app, I simply query the context for the number of changes to verify that any manipulations done in RadGridView have translated to the context. You simply need to add the SubmitChanges call.

All the best,
Yavor Georgiev
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Leo
Top achievements
Rank 2
answered on 25 Oct 2010, 02:18 PM
Hello, 

Thanks for your answer. Already tried that but got error cause of the database itself restriction of the date. I modified it and it worked. Thank you so much,

I have another question, how do you disable when your inserting a row data a certain row? Let's say your StudentID row is disable and automatically when the user is inserting it will be automatically be on row 2 for student name
0
Yavor Georgiev
Telerik team
answered on 25 Oct 2010, 02:27 PM
Hello Leo,

 You can set the IsReadOnly property of the relevant GridViewColumn to true.

Best wishes,
Yavor Georgiev
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
Tags
GridView
Asked by
Leo
Top achievements
Rank 2
Answers by
Yavor Georgiev
Telerik team
Leo
Top achievements
Rank 2
Share this question
or