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

Complete hierachical CRUD example

7 Answers 353 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Pier-Luc
Top achievements
Rank 1
Pier-Luc asked on 04 Oct 2012, 06:31 PM
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!

7 Answers, 1 is accepted

Sort by
0
Julian Benkov
Telerik team
answered on 09 Oct 2012, 01:26 PM
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 >>
0
Pier-Luc
Top achievements
Rank 1
answered on 09 Oct 2012, 04:56 PM
What about Many to Many? How can I create those with the designer? Is there any tutorial or documentation I can look at?
0
Pier-Luc
Top achievements
Rank 1
answered on 09 Oct 2012, 05:15 PM
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.
0
Julian Benkov
Telerik team
answered on 11 Oct 2012, 02:28 PM
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.
0
Marco
Top achievements
Rank 2
Veteran
answered on 05 Sep 2016, 04:38 PM

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.

0
Marco
Top achievements
Rank 2
Veteran
answered on 05 Sep 2016, 05:07 PM

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 ?

0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 06 Sep 2016, 07:41 AM
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.
Tags
GridView
Asked by
Pier-Luc
Top achievements
Rank 1
Answers by
Julian Benkov
Telerik team
Pier-Luc
Top achievements
Rank 1
Marco
Top achievements
Rank 2
Veteran
Dess | Tech Support Engineer, Principal
Telerik team
Share this question
or