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

Not able to click Add new item

8 Answers 179 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Leo
Top achievements
Rank 2
Leo asked on 05 Dec 2010, 02:35 PM
Hello, I am using LINQ to SQL class in order to retrieve and write data in my SQL. I have a table called Student and Subjects. Student is my parent table and Subjects is my child table. I successfully displays per student his/her subjects with Hierarchical Data Grid. I can add, delete, update, read data in my Subjects using the Property CanUserInsertRows and ShowInsertRow as true. Now my problem is that when I want to add new item in my Student table I cannot click my add new item or it is not clickable. Any help please?
Here's my xaml file
<Window x:Class="HierarchiyGridSuccess.MainWindow"
        xmlns:telerikData="clr-namespace:Telerik.Windows.Data;assembly=Telerik.Windows.Data"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <telerik:RadGridView Grid.Row="0" x:Name="rgvData" ShowInsertRow="True" AutoGenerateColumns="False" telerik:Theming.Theme="Windows7" ItemsSource="{Binding}" >
            <telerik:RadGridView.ChildTableDefinitions>
                <telerik:GridViewTableDefinition />
            </telerik:RadGridView.ChildTableDefinitions>
            <telerik:RadGridView.Columns>
                <telerik:GridViewDataColumn DataMemberBinding="{Binding StudentID}" Header="Student ID" />
                <telerik:GridViewDataColumn DataMemberBinding="{Binding StudentFN}" Header="Student First Name" />
                <telerik:GridViewDataColumn DataMemberBinding="{Binding StudentLN}" Header="Student Last Name" />
            </telerik:RadGridView.Columns>
            <telerik:RadGridView.HierarchyChildTemplate>
                <DataTemplate>
                    <telerik:RadGridView x:Name="RadGridView1" Loaded="rgvData_Loaded" AutoGenerateColumns="False" ShowInsertRow="False"  CanUserInsertRows="False"  ItemsSource="{Binding Subjects}" ShowGroupPanel="False" IsReadOnly="False">
                        <telerik:RadGridView.Columns>
                            <telerik:GridViewDataColumn DataMemberBinding="{Binding SubjectName}" Header="Subject Name" />
                            <telerik:GridViewDataColumn DataMemberBinding="{Binding SubjectProf}" Header="Professor" />
                        </telerik:RadGridView.Columns>
                    </telerik:RadGridView>
                </DataTemplate>
            </telerik:RadGridView.HierarchyChildTemplate>
        </telerik:RadGridView>
        <Button Content="Save!" Width="Auto" Height="Auto" Grid.Row="1" Click="Button_Click" />  
    </Grid>
</Window>

And my class file 

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 System.Collections.Specialized;
using Telerik.Windows.Controls;
using Telerik.Windows.Controls.GridView;
 
namespace HierarchiyGridSuccess
{
    /// <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);
            rgvData.Filtered += new EventHandler<Telerik.Windows.Controls.GridView.GridViewFilteredEventArgs>(rgvData_Filtered);
        }
 
        void rgvData_Loaded(object sender, RoutedEventArgs e)
        {
            var childGrid = (RadGridView)sender;
        var parentRow = childGrid.ParentRow;   
 
        if (parentRow != null)
        {
            rgvData.SelectedItem = childGrid.DataContext;
            parentRow.IsExpandedChanged += new RoutedEventHandler(parentRow_IsExpandedChanged);
        }
         }
 
    void parentRow_IsExpandedChanged(object sender, RoutedEventArgs e)
    {
        rgvData.SelectedItem = ((GridViewRow)sender).DataContext;
    }
         
 
        void rgvData_Filtered(object sender, Telerik.Windows.Controls.GridView.GridViewFilteredEventArgs e)
        {
            rgvData.ItemsSource = m_dcData.Students;
        }
 
        private void Items_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            try
            {
                if (e.Action == NotifyCollectionChangedAction.Add)
                {
                    foreach (Student item in e.NewItems)
                    {
                        this.m_dcData.Students.InsertAllOnSubmit(e.NewItems.OfType<Student>());
                    }
                }
                if (e.Action == NotifyCollectionChangedAction.Remove)
                {
                    this.m_dcData.Students.DeleteAllOnSubmit(e.OldItems.OfType<Student>());
                }
            }
            catch (Exception s)
            { }
        }
        void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            m_dcData = new DataAccessDataContext();
            m_dcData.Log = Console.Out;
            DataContext = m_dcData.Students;
            rgvData.ShowInsertRow = true;
        }
 
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            var changes = this.m_dcData.GetChangeSet();
            rgvData.BeginInsert();
            MessageBox.Show(string.Format("There are {0} inserts and {1} deletes pending.", changes.Inserts.Count, changes.Deletes.Count));
            m_dcData.SubmitChanges();
        }
    }
}

How come I cannot click the add new item of my parent table?

8 Answers, 1 is accepted

Sort by
0
Vlad
Telerik team
answered on 06 Dec 2010, 08:09 AM
Hi,

 You cannot add rows if the ItemsSource is not at least IList. I suggest you to check the application in this thread for more info. 

Best wishes,
Vlad
the Telerik team
Browse the videos here>> to help you get started with RadControls for WPF
0
Leo
Top achievements
Rank 2
answered on 06 Dec 2010, 08:23 PM
Hi, I think you did not get my question..

I can add rows on my child table and it even inserts the current selected item's primary key to the child table. 

Here is my StudentViewModel

using System.ComponentModel;
using System.Windows.Input;
using Telerik.Windows.Data;
 
 
namespace HierarchiyGridSuccess
{
    public class StudentViewModel : INotifyPropertyChanged
    {
        private readonly DataAccessDataContext context;
        private readonly DelegateCommand<Student> addStudentCommand;
        private readonly DelegateCommand<Student> deleteStudentCommand;
        private readonly QueryableCollectionView studentsCollectionView;
        private Student selectedStudent;
 
        public StudentViewModel()
        {
            this.context = new DataAccessDataContext();
            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;
        }
 
    }
}

And here's my delegate class.

using System;
using System.Windows;
using System.Windows.Input;
using System.Windows.Threading;
 
namespace HierarchiyGridSuccess
{
    public class DelegateCommand<T> : ICommand
    {
        private readonly Action<T> executeMethod;
        private readonly Func<T, bool> canExecuteMethod;
        private readonly Dispatcher dispatcher;
 
        public DelegateCommand(Action<T> executeMethod)
            : this(executeMethod, null)
         {}
        public DelegateCommand(Action<T> executeMethod, Func<T, bool> canExecuteMethod)
        {
            if (executeMethod == null && canExecuteMethod == null)
                throw new ArgumentNullException("executeMethod");
 
            this.executeMethod = executeMethod;
            this.canExecuteMethod = canExecuteMethod;
            if (Application.Current != null)
            {
                this.dispatcher = Application.Current.Dispatcher;
            }
        }
 
        public bool CanExecute(T parameter)
        {
            if (this.canExecuteMethod == null) return true;
            return this.canExecuteMethod(parameter);
        }
 
        public void Execute(T parameter)
        {
            if (this.executeMethod == null) return;
            this.executeMethod(parameter);
        }
 
        bool ICommand.CanExecute(object parameter)
        {
            return this.CanExecute((T)parameter);
        }
 
        public event EventHandler CanExecuteChanged;
 
        void ICommand.Execute(object parameter)
        {
            this.Execute((T)parameter);
        }
 
        public void RaiseCanExecuteChanged()
        {
            this.OnCanExecuteChanged();
        }
 
        protected virtual void OnCanExecuteChanged()
        {
            EventHandler canExecuteChangedHandler = this.CanExecuteChanged;
            if (canExecuteChangedHandler != null)
            {
                if (this.dispatcher != null && !this.dispatcher.CheckAccess())
                {
                    this.dispatcher.BeginInvoke(DispatcherPriority.Normal,
                                           (Action)this.OnCanExecuteChanged);
                }
                else
                {
                    canExecuteChangedHandler(this, EventArgs.Empty);
                }
            }
        }
    }
}

Now I'm wondering why I cannot click the parent grid's add new item while my child grid, i could click the add new item of the grid view control.

0
Vlad
Telerik team
answered on 07 Dec 2010, 08:35 AM
Hi,

 Can you post more info about the collection type of m_dcData.Students?

Regards,
Vlad
the Telerik team
Browse the videos here>> to help you get started with RadControls for WPF
0
Leo
Top achievements
Rank 2
answered on 07 Dec 2010, 03:21 PM
#pragma warning disable 1591
//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:4.0.30319.1
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
 
namespace HierarchiyGridSuccess
{
    using System.Data.Linq;
    using System.Data.Linq.Mapping;
    using System.Data;
    using System.Collections.Generic;
    using System.Reflection;
    using System.Linq;
    using System.Linq.Expressions;
    using System.ComponentModel;
    using System;
     
     
    [global::System.Data.Linq.Mapping.DatabaseAttribute(Name="SampleDB")]
    public partial class DataAccessDataContext : System.Data.Linq.DataContext
    {
         
        private static System.Data.Linq.Mapping.MappingSource mappingSource = new AttributeMappingSource();
         
    #region Extensibility Method Definitions
    partial void OnCreated();
    partial void InsertSubject(Subject instance);
    partial void UpdateSubject(Subject instance);
    partial void DeleteSubject(Subject instance);
    partial void InsertStudent(Student instance);
    partial void UpdateStudent(Student instance);
    partial void DeleteStudent(Student instance);
    #endregion
         
        public DataAccessDataContext() :
                base(global::HierarchiyGridSuccess.Properties.Settings.Default.SampleDBConnectionString, mappingSource)
        {
            OnCreated();
        }
         
        public DataAccessDataContext(string connection) :
                base(connection, mappingSource)
        {
            OnCreated();
        }
         
        public DataAccessDataContext(System.Data.IDbConnection connection) :
                base(connection, mappingSource)
        {
            OnCreated();
        }
         
        public DataAccessDataContext(string connection, System.Data.Linq.Mapping.MappingSource mappingSource) :
                base(connection, mappingSource)
        {
            OnCreated();
        }
         
        public DataAccessDataContext(System.Data.IDbConnection connection, System.Data.Linq.Mapping.MappingSource mappingSource) :
                base(connection, mappingSource)
        {
            OnCreated();
        }
         
        public System.Data.Linq.Table<Subject> Subjects
        {
            get
            {
                return this.GetTable<Subject>();
            }
        }
         
        public System.Data.Linq.Table<Student> Students
        {
            get
            {
                return this.GetTable<Student>();
            }
        }
    }
     
    [global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.Subject")]
    public partial class Subject : INotifyPropertyChanging, INotifyPropertyChanged
    {
         
        private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
         
        private int _SubjectID;
         
        private string _SubjectName;
         
        private string _SubjectProf;
         
        private int _StudentID;
         
        private EntityRef<Student> _Student;
         
    #region Extensibility Method Definitions
    partial void OnLoaded();
    partial void OnValidate(System.Data.Linq.ChangeAction action);
    partial void OnCreated();
    partial void OnSubjectIDChanging(int value);
    partial void OnSubjectIDChanged();
    partial void OnSubjectNameChanging(string value);
    partial void OnSubjectNameChanged();
    partial void OnSubjectProfChanging(string value);
    partial void OnSubjectProfChanged();
    partial void OnStudentIDChanging(int value);
    partial void OnStudentIDChanged();
    #endregion
         
        public Subject()
        {
            this._Student = default(EntityRef<Student>);
            OnCreated();
        }
         
        [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_SubjectID", DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)]
        public int SubjectID
        {
            get
            {
                return this._SubjectID;
            }
            set
            {
                if ((this._SubjectID != value))
                {
                    this.OnSubjectIDChanging(value);
                    this.SendPropertyChanging();
                    this._SubjectID = value;
                    this.SendPropertyChanged("SubjectID");
                    this.OnSubjectIDChanged();
                }
            }
        }
         
        [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_SubjectName", DbType="NChar(20)")]
        public string SubjectName
        {
            get
            {
                return this._SubjectName;
            }
            set
            {
                if ((this._SubjectName != value))
                {
                    this.OnSubjectNameChanging(value);
                    this.SendPropertyChanging();
                    this._SubjectName = value;
                    this.SendPropertyChanged("SubjectName");
                    this.OnSubjectNameChanged();
                }
            }
        }
         
        [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_SubjectProf", DbType="NChar(20)")]
        public string SubjectProf
        {
            get
            {
                return this._SubjectProf;
            }
            set
            {
                if ((this._SubjectProf != value))
                {
                    this.OnSubjectProfChanging(value);
                    this.SendPropertyChanging();
                    this._SubjectProf = value;
                    this.SendPropertyChanged("SubjectProf");
                    this.OnSubjectProfChanged();
                }
            }
        }
         
        [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_StudentID", DbType="Int NOT NULL")]
        public int StudentID
        {
            get
            {
                return this._StudentID;
            }
            set
            {
                if ((this._StudentID != value))
                {
                    if (this._Student.HasLoadedOrAssignedValue)
                    {
                        throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
                    }
                    this.OnStudentIDChanging(value);
                    this.SendPropertyChanging();
                    this._StudentID = value;
                    this.SendPropertyChanged("StudentID");
                    this.OnStudentIDChanged();
                }
            }
        }
         
        [global::System.Data.Linq.Mapping.AssociationAttribute(Name="Student_Subject", Storage="_Student", ThisKey="StudentID", OtherKey="StudentID", IsForeignKey=true)]
        public Student Student
        {
            get
            {
                return this._Student.Entity;
            }
            set
            {
                Student previousValue = this._Student.Entity;
                if (((previousValue != value)
                            || (this._Student.HasLoadedOrAssignedValue == false)))
                {
                    this.SendPropertyChanging();
                    if ((previousValue != null))
                    {
                        this._Student.Entity = null;
                        previousValue.Subjects.Remove(this);
                    }
                    this._Student.Entity = value;
                    if ((value != null))
                    {
                        value.Subjects.Add(this);
                        this._StudentID = value.StudentID;
                    }
                    else
                    {
                        this._StudentID = default(int);
                    }
                    this.SendPropertyChanged("Student");
                }
            }
        }
         
        public event PropertyChangingEventHandler PropertyChanging;
         
        public event PropertyChangedEventHandler PropertyChanged;
         
        protected virtual void SendPropertyChanging()
        {
            if ((this.PropertyChanging != null))
            {
                this.PropertyChanging(this, emptyChangingEventArgs);
            }
        }
         
        protected virtual void SendPropertyChanged(String propertyName)
        {
            if ((this.PropertyChanged != null))
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
     
    [global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.Student")]
    public partial class Student : INotifyPropertyChanging, INotifyPropertyChanged
    {
         
        private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
         
        private int _StudentID;
         
        private string _StudentFN;
         
        private string _StudentLN;
         
        private EntitySet<Subject> _Subjects;
         
    #region Extensibility Method Definitions
    partial void OnLoaded();
    partial void OnValidate(System.Data.Linq.ChangeAction action);
    partial void OnCreated();
    partial void OnStudentIDChanging(int value);
    partial void OnStudentIDChanged();
    partial void OnStudentFNChanging(string value);
    partial void OnStudentFNChanged();
    partial void OnStudentLNChanging(string value);
    partial void OnStudentLNChanged();
    #endregion
         
        public Student()
        {
            this._Subjects = new EntitySet<Subject>(new Action<Subject>(this.attach_Subjects), new Action<Subject>(this.detach_Subjects));
            OnCreated();
        }
         
        [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_StudentID", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)]
        public int StudentID
        {
            get
            {
                return this._StudentID;
            }
            set
            {
                if ((this._StudentID != value))
                {
                    this.OnStudentIDChanging(value);
                    this.SendPropertyChanging();
                    this._StudentID = value;
                    this.SendPropertyChanged("StudentID");
                    this.OnStudentIDChanged();
                }
            }
        }
         
        [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_StudentFN", DbType="NChar(50)")]
        public string StudentFN
        {
            get
            {
                return this._StudentFN;
            }
            set
            {
                if ((this._StudentFN != value))
                {
                    this.OnStudentFNChanging(value);
                    this.SendPropertyChanging();
                    this._StudentFN = value;
                    this.SendPropertyChanged("StudentFN");
                    this.OnStudentFNChanged();
                }
            }
        }
         
        [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_StudentLN", DbType="NChar(50)")]
        public string StudentLN
        {
            get
            {
                return this._StudentLN;
            }
            set
            {
                if ((this._StudentLN != value))
                {
                    this.OnStudentLNChanging(value);
                    this.SendPropertyChanging();
                    this._StudentLN = value;
                    this.SendPropertyChanged("StudentLN");
                    this.OnStudentLNChanged();
                }
            }
        }
         
        [global::System.Data.Linq.Mapping.AssociationAttribute(Name="Student_Subject", Storage="_Subjects", ThisKey="StudentID", OtherKey="StudentID")]
        public EntitySet<Subject> Subjects
        {
            get
            {
                return this._Subjects;
            }
            set
            {
                this._Subjects.Assign(value);
            }
        }
         
        public event PropertyChangingEventHandler PropertyChanging;
         
        public event PropertyChangedEventHandler PropertyChanged;
         
        protected virtual void SendPropertyChanging()
        {
            if ((this.PropertyChanging != null))
            {
                this.PropertyChanging(this, emptyChangingEventArgs);
            }
        }
         
        protected virtual void SendPropertyChanged(String propertyName)
        {
            if ((this.PropertyChanged != null))
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
         
        private void attach_Subjects(Subject entity)
        {
            this.SendPropertyChanging();
            entity.Student = this;
        }
         
        private void detach_Subjects(Subject entity)
        {
            this.SendPropertyChanging();
            entity.Student = null;
        }
    }
}
#pragma warning restore 1591
0
Nedyalko Nikolov
Telerik team
answered on 09 Dec 2010, 04:09 PM
Hi Leo,

Your underlying data source (UDS) should implement IList and business object (BO) should have public default constructor (parameterless constructor) in order to use adding new item feature out of the box.

1. If UDS doesn't implement IList - you will need special UI to add new row (RadGridView.ShowInsertRow = true) and you should handle RadGridView.RowEditEnded and add item to UDS manually.
2. If BO doesn't have a default constructor you should handle RadGridView.AddingNewDataItem event and provide new BO instance to e.NewObject property.

Let me know if this doesn't help.

Kind regards,
Nedyalko Nikolov
the Telerik team
Browse the videos here>> to help you get started with RadControls for WPF
0
Leo
Top achievements
Rank 2
answered on 09 Dec 2010, 06:38 PM
Sorry, I'm just a student.  I'm not sure if I did understand what you said, can you point out which part of my code do I have to edit and make it into an IList and the BO part? Many thanks!
0
Nedyalko Nikolov
Telerik team
answered on 11 Dec 2010, 08:35 AM
Hi Leo,

I've missed one part when underlying data source doesn't implement IList interface (first point from my previous answer). In that case you should handle AddingNewDataItem event also.

You can take a look at this forum thread for more information how to achieve CRUD operation with RadGridView and LinqToSql.

Greetings,
Nedyalko Nikolov
the Telerik team
Browse the videos here>> to help you get started with RadControls for WPF
0
Leo
Top achievements
Rank 2
answered on 11 Dec 2010, 08:54 PM
You mean on my StudentViewModel.cs I have to add an IList? How do I do that? and How do I handle the AddingNewItems in my parent grid? Cause I could add new data on my child grid without having an IList
Tags
GridView
Asked by
Leo
Top achievements
Rank 2
Answers by
Vlad
Telerik team
Leo
Top achievements
Rank 2
Nedyalko Nikolov
Telerik team
Share this question
or