Complete hierachical CRUD example

8 posts, 0 answers
  1. Pier-Luc
    Pier-Luc avatar
    3 posts
    Member since:
    Sep 2012

    Posted 04 Oct 2012 Link to this post

    I can't find any COMPLETE CRUD example on the web, forum and demo page. Anyone has a clue where I could find one?

    I need to support these features:
    -Support for One to Many relations.
    -Support for Many to Many relations.
    -Deleting relation (mapping table row) when deleting a Many to Many row from child grid.
    -Change FK to null when deleting a One to Many row from a child grid
    -Saving data On Changes.

    Entity Framework or DataSet / DataAdapters will do. EF would be preferable (as it already handles all my relation requirements) but I believe it is not officially supported yet (and I had some troubles getting child deletion to work).

    Thanks!
  2. Julian Benkov
    Admin
    Julian Benkov avatar
    1135 posts

    Posted 09 Oct 2012 Link to this post

    Hi Pier-Luc,

    You can implement this functionality using RadGridView events that reflect the changes from user manipulations. Here is an example of updates using the DataSet based hierarchical data and RowsChanged event:
    void radGridView1_RowsChanged(object sender, Telerik.WinControls.UI.GridViewCollectionChangedEventArgs e)
    {
        if (e.Action == Telerik.WinControls.Data.NotifyCollectionChangedAction.Add
            || e.Action == Telerik.WinControls.Data.NotifyCollectionChangedAction.Remove
            || e.Action == Telerik.WinControls.Data.NotifyCollectionChangedAction.ItemChanged)
        {
            if (e.NewItems.Count > 0)
            {
                if (e.Action == Telerik.WinControls.Data.NotifyCollectionChangedAction.Remove)
                {
                    GridViewRowInfo rowInfo = e.NewItems[0] as GridViewRowInfo;
                    if (rowInfo != null && rowInfo.Parent is GridViewHierarchyRowInfo)
                    {
                        GridViewHierarchyRowInfo parent = rowInfo.Parent as GridViewHierarchyRowInfo;
                        Lab.NwindDataSet.CustomersRow customer = (Lab.NwindDataSet.CustomersRow)((DataRowView)parent.DataBoundItem).Row;
                        if (customer.GetOrdersRows().Length == 0)
                        {
                            this.radGridView1.CurrentRow = null;
                            this.nwindDataSet.Customers.RemoveCustomersRow(customer);
                        }
                    }
                }
     
                this.ordersTableAdapter.Update(this.nwindDataSet.Orders);
                this.customersTableAdapter.Update(this.nwindDataSet.Customers);
            }
        }
    }

    Here is an example demonstrating how to create autosave functionality in RadGridView by using a few events:
    public partial class AutoSavingDataForm : Form
    {
        private List<DataRowView> lastRemovedRows = new List<DataRowView>();
     
        public AutoSavingDataForm()
        {
            InitializeComponent();
     
            this.radGridView1.UserAddedRow += new Telerik.WinControls.UI.GridViewRowEventHandler(radGridView1_UserAddedRow);
            this.radGridView1.UserDeletingRow += new Telerik.WinControls.UI.GridViewRowCancelEventHandler(radGridView1_UserDeletingRow);
            this.radGridView1.UserDeletedRow += new Telerik.WinControls.UI.GridViewRowEventHandler(radGridView1_UserDeletedRow);
            this.radGridView1.CurrentRowChanged += new Telerik.WinControls.UI.CurrentRowChangedEventHandler(radGridView1_CurrentRowChanged);
        }
     
        void radGridView1_UserDeletingRow(object sender, Telerik.WinControls.UI.GridViewRowCancelEventArgs e)
        {
            for (int i = 0; i < e.Rows.Length; i++)
            {
                DataRowView dataRowView = e.Rows[i].DataBoundItem as DataRowView;
                if (dataRowView != null)
                {
                    this.lastRemovedRows.Add(dataRowView);
                }
            }
        }
     
        void radGridView1_CurrentRowChanged(object sender, Telerik.WinControls.UI.CurrentRowChangedEventArgs e)
        {
            if (e.OldRow == null)
            {
                return;
            }
     
            DataRowView dataRowView = e.OldRow.DataBoundItem as DataRowView;
            if (dataRowView != null)
            {
                DataRow dataRow = dataRowView.Row;
                if ( dataRow.RowState == DataRowState.Modified)
                {
                    this.contactTableAdapter.Update(dataRow);
                }
            }
        }
     
        void radGridView1_UserDeletedRow(object sender, Telerik.WinControls.UI.GridViewRowEventArgs e)
        {
            DataRow[] rows = new DataRow[this.lastRemovedRows.Count];
     
            for (int i = 0; i < this.lastRemovedRows.Count; i++)
            {
                            rows[i] = this.lastRemovedRows[i].Row;
            }
     
            this.contactTableAdapter.Update(rows);
            this.lastRemovedRows.Clear();
        }
     
        void radGridView1_UserAddedRow(object sender, Telerik.WinControls.UI.GridViewRowEventArgs e)
        {
            DataRow[] rows = new DataRow[e.Rows.Length];
            for (int i = 0; i < e.Rows.Length; i++)
            {
                DataRowView dataRowView = e.Rows[i].DataBoundItem as DataRowView;
                if (dataRowView != null)
                {
                    rows[i] = this.lastRemovedRows[i].Row;
                }
            }
     
            this.contactTableAdapter.Update(rows);
        }
     
        private void Form18_Load(object sender, EventArgs e)
        {
            // TODO: This line of code loads data into the 'adventureWorksDataSet.Contact' table. You can move, or remove it, as needed.
            this.contactTableAdapter.FillBy(this.adventureWorksDataSet.Contact, null);
        }
    }

    Currently, RadGridView does not support direct binding to EntityFramework objects with CRUD operations. To use the EntityFramework objects you must convert result to ToList() or ToBindingList() and then bind the resulted list to RadGridView. Then you must synchronize the changes in the bound list with the EntityFramework context. 

    I hope this information is useful. 

    All the best,
    Julian Benkov
    the Telerik team
    RadControls for WinForms Q2'12 release is now live! Check out what's new or download a free trial >>
  3. UI for WinForms is Visual Studio 2017 Ready
  4. Pier-Luc
    Pier-Luc avatar
    3 posts
    Member since:
    Sep 2012

    Posted 09 Oct 2012 Link to this post

    What about Many to Many? How can I create those with the designer? Is there any tutorial or documentation I can look at?
  5. Pier-Luc
    Pier-Luc avatar
    3 posts
    Member since:
    Sep 2012

    Posted 09 Oct 2012 Link to this post

    This is what I'm trying to do.

    Table Structure
    Entities
    Employee - EmployeeID, EmployeeName
    Hardware - HardwareID, EmployeeID (Nullable), HardwareName
    Software - SoftwareID, SoftwareName

    Mapping
    EmployeeSoftwareMaps - EmployeeID, SoftwareID

    Relations
    Employee (1...*) Hardware
    Employee (*...*) Software

    Goal
    3 DataGrids to manipulate that data and those relations.

    Employee DataGrid
    Tabbed details of which Hardware and Software each employee has.
    Ability assign or remove hardware and software from this employee (not delete it, only remove the relation from the mapping table).

    Hardware DataGrid
    EmployeeID column as a combobox of employes.
    Ability to set EmployeeID to Null.

    Software DataGrid
    Detail list of Employees that has a license of that software.
    Ability to assign or remove a license to an employee.
  6. Julian Benkov
    Admin
    Julian Benkov avatar
    1135 posts

    Posted 11 Oct 2012 Link to this post

    Hi Pier-Luc,

    RadGridView does not support many-to-many relation hierarchy mode built-in and can not be used for some CRUD operations in this scenario. The solution in this situation is to use Load-on-demand hierarchy mode and prepare and update all the data manually. Please view the attached example based on AdventureWorks demo database.

    I hope this helps.

    Regards,
    Julian Benkov
    the Telerik team
    You’ve been asking for it and now it’s time for us to deliver. RadControls for WinForms Q3 2012 release is just around the corner. Sign up for a free webinar to see first all the latest enhancements.
  7. Marco
    Marco avatar
    87 posts
    Member since:
    Apr 2011

    Posted 05 Sep in reply to Julian Benkov Link to this post

    I think there is a little mistake on your exemple.

    On the radGridView1_UserAddedRow Sub, you should replace

    rows[i] = this.lastRemovedRows[i].Row;

    By

    rows[i] = dataRowView

    If I'm right, thanks for correcting. And feel free to remove mine.

  8. Marco
    Marco avatar
    87 posts
    Member since:
    Apr 2011

    Posted 05 Sep Link to this post

    I also think that the CurrentRowChanged event is not the best choice for tracking the modification of a row.

    When you edit some cells on a row, then you directly close the forms, this event isn't raised.

    What's your opinion on handling this case ?

  9. Dess
    Admin
    Dess avatar
    1609 posts

    Posted 06 Sep Link to this post

    Hello Marco,

    Thank you for writing.  

    You can use the CellValueChanged event for tracking changes in RadGridView. The following KnowledgeBase article is quite useful about CRUD in Object Relational Hierarchy Mode: http://www.telerik.com/support/kb/winforms/gridview/details/radgridview-crud-in-object-relational-hierarchy-mode

    I hope this information helps. Should you have further questions I would be glad to help.

    Regards,
    Dess
    Telerik by Progress
    Check out the Windows Forms project converter, which aids the conversion process from standard Windows Forms applications written in C# or VB to Telerik UI for WinForms.For more information check out this blog post and share your thoughts.
Back to Top
UI for WinForms is Visual Studio 2017 Ready