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

[Solved] Using RadGrid with ObjectContainerDataSource from WCSF

5 Answers 157 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Henrik
Top achievements
Rank 1
Henrik asked on 20 Jan 2009, 08:39 AM
Hi,

We are building a webapplication using the Web Client Software Factory Model-View-Presenter pattern.
We would like to take advantage of the Telerik control library, but we cannot find any samples on how to implement this properly in the MVP pattern using the ObjectContainerDataSource. This is what we would like to do:
1. One page with two RadGrids - in a multipage with a pageview for each grid.
2. The page containing the grids have a save button - when clicking this, the data from the grids should be saved. We don't want a save button for each grid, since this is not very user-friendly.

This is how we have done so far:
1. Insert a RadGrid like this:
<tel:RadGrid ID="gridKnuder" AutoGenerateColumns="false" 
                DataSourceID="ocdsKnuder" AllowPaging="True" AllowSorting="True" AllowMultiRowEdit="true" 
                AllowAutomaticUpdates="true" GridLines="None" Skin="Office2007" 
                OnPreRender="GridKnuder_PreRender" OnItemCreated="GridKnuder_ItemCreated" runat="server"
                <MasterTableView DataKeyNames="Kode" EditMode="InPlace" CommandItemDisplay="None"
                    <Columns> 
                        <tel:GridBoundColumn ReadOnly="true" UniqueName="ShowType" HeaderText="Type" DataField="TypeBeskrivelse" /> 
                        <tel:GridBoundColumn HeaderText="Pris" UniqueName="ShowPris" DataField="Pris" /> 
                    </Columns> 
                </MasterTableView> 
            </tel:RadGrid> 

2. Declare an ObjectContainerDataSource like this:
<wcsf:ObjectContainerDataSource ID="ocdsKnuder" DataObjectTypeName="Niras.DasVaerdi.Entity.KKnudeStandardVaerdi" runat="server" /> 




3. We display the grid in edit mode like this:
protected void GridKnuder_PreRender(object sender, System.EventArgs e) 
        { 
            if (!IsPostBack) 
            { 
                foreach (GridItem item in gridKnuder.MasterTableView.Items) 
                { 
                    if (item is GridEditableItem ) 
                    { 
                        GridEditableItem editableItem = item as GridDataItem; 
                        editableItem.Edit = true
                    } 
                } 
 
                gridKnuder.Rebind(); 
            } 
        } 
 
This makes all the rows in the grid editable when the page is loaded, and when the user clicks the "global" save button, we want to retrive the list of objects that was initially bound to the grid like this:
public IList<OurObject> Knuder 
        { 
            set { ocdsKnuder.DataSource = Session[skKnudeStandardVaerdier] = value; } 
        } 


So, we want our save button event-handler do look something like this:
protected void Save(object sender, EventArgs e) 
        { 
// Get the list of objects back from the grid or its datasource          
IList<OurObject> vaerdier = gridKnuder.???????? or ocdsKnuder.???? 
 
            _presenter.OnKnuderUpdated(vaerdier); 
            Knuder = vaerdier; 
        } 

Is this even possible with the ObjectContainerDataSource or does it only allow updating on row at a time, with "Update" and  "Cancel" option on each row? Which is not vey usefull in real-world applications.

Please let me know if I should provide more code to clarify what we want to do

5 Answers, 1 is accepted

Sort by
0
Henrik
Top achievements
Rank 1
answered on 21 Jan 2009, 11:58 AM
Isn't there anybody who can help solving this out or are we trying to achieve something impossible? Please help :)
0
Nikolay Rusev
Telerik team
answered on 23 Jan 2009, 07:58 AM
Hello Henrik,

I am afraid that you won't be able to insert item from event out-side RadGrid. The reason is that on Button.Click event you don't have control on RadGrid insert form.

If you don't need to have Edit/Cancel buttons on each row or RadGrid you use approach similar to the one demonstrated on this online demo:
Using template to customize the command-item contents
Thus you'll be able to update all edited items in your grid control within one button in CommadItemTemplate.

I hope this is suitable in your scenario.

All the best,
Nikolay
the Telerik team

Check out Telerik Trainer, the state of the art learning tool for Telerik products.
0
Henrik
Top achievements
Rank 1
answered on 26 Jan 2009, 09:16 AM
Hi Nikolay,
Thank you for the reply.
I am not interested in inserting new items in the grid. I want to update the existing values.
1. Grid is loaded in edit mode with a name column and a value column (which the user can edit)
2. Once the user is finished edit the values, he clicks a global save button on the page
3. Now the page makes a postback, and I want to get back the values from the grid. So what I want, is the grid to return the list of business objects and their values, like this:
protected void Save(object sender, EventArgs e)    
        {    
// Get the list of objects back from the grid or its datasource             
IList<OurObject> vaerdier = gridKnuder.???????? or ocdsKnuder.????    
    
            _presenter.OnKnuderUpdated(vaerdier);    
            Knuder = vaerdier;    
        }   
 
I guess I am asking for some kind og two-way databinding.
Isn't that possible?

Best regards

Henrik
0
Nikolay Rusev
Telerik team
answered on 28 Jan 2009, 05:16 PM
Hello Henrik,

I've prepared sample application. You can find it attached to this post.
I guess this is what you are after.

Best wishes,
Nikolay
the Telerik team

Check out Telerik Trainer, the state of the art learning tool for Telerik products.
0
johnv
Top achievements
Rank 2
answered on 10 Mar 2010, 09:31 PM
Hey Henrik,

There is no need to use that ObjectContainerDataSource stuff; if you are I think you will find that your objects that are too specific. Instead of passing an IEnumerable<T> or ICollection<T> to your presenter, which is the normal tendency for MVP developers, you need to use a type that is higher in the stack - object.

Remember that there should be no references to your model or to data in your views. If there are, you aren't following the MVP development methodology correctly.

Make your repo class, since it knows about OurObject (in my example SecPage) return an ICollection<OurObject> and then make your presenter map it to the DataSource of you menu, grid, combo box, etc as an object.

Since it is an ICollection described as an object, the RadGrid's datasource (who's base type is object already), will consume it just fine.

Check this out:
Model.SecPage 
 
      public class SecPage 
      { 
        public int PageId { getset; } 
        public string PageText { getset; } 
        public string PageTarget { getset; } 
        public int ParentId { getset; } 
        public int UpdatedBy { getset; } 
        public DateTime UpdatedOn { getset; } 
        public int AccessType { getset; } 
        public bool AnonymousAccess { getset; } 
      } 
 
Model.ISecPageRepository 
 
 
    interface ISecPageRepostory 
    { 
        ICollection<SecPage> GenerateMenu(Decimal UserId); 
        SecPage CreateFrom(NAVPass.Model.Data.Oracle.SecPage sp); 
    } 
 
Model.SecPageRepository 
 
        public ICollection<SecPage> GenerateMenu(Decimal UserId) 
        { 
            var pages = from sp in context.SecPages 
                        join pg in 
                            (from a in context.SecRoleAccess 
                             where 
                             (from role in context.UserRoles 
                              where role.UserId == UserId
                              select role.RoleId).Contains(a.RoleId) 
                             select new { a.PageId, a.AccessType }) 
                        on sp.PageId equals pg.PageId into pagetemp 
                        from x in pagetemp.DefaultIfEmpty() 
                        where ((sp.PageAnonAccess == "1") || (x.AccessType != null)) 
                        orderby sp.PageId 
 
                        select CreateFrom(sp); 
            return pages.ToList(); 
        } 
 
        public SecPage CreateFrom(Project.Model.Data.Oracle.SecPage sp) 
        { 
            SecPage _secPage = new SecPage(); 
            _secPage.PageId = Convert.ToInt32(sp.PageId); 
            _secPage.PageTarget = sp.PageTarget; 
            _secPage.PageText = sp.PageText; 
            _secPage.ParentId = Convert.ToInt32(sp.PageParentId); 
            _secPage.UpdatedBy = Convert.ToInt32(sp.UpdatedBy); 
            _secPage.UpdatedOn = sp.UpdatedDts;             
            _secPage.AnonymousAccess = Convert.ToBoolean(Convert.ToInt32(sp.PageAnonAccess)); 
            return _secPage; 
        } 
 
Presenter.MainMenuPresenter 
 
        IMainMenuView _view; 
 
        public MainMenuPresenter(IMainMenuView view) 
        { 
            _view = view; 
            _view.StartUp += view_StartUp; 
        } 
 
        void view_StartUp(object sender, EventArgs e) 
        { 
            var ds = SecPageRepository.Instance.GenerateMenu(5); // TODO: change to something usable 
            _view.SetMenuDataSource(ds); 
        } 
 
Presenter.IMainMenuView 
 
      public interface IMainMenuView 
      { 
        event EventHandler StartUp; 
 
        void SetMenuDataSource(object ds); 
      } 
 
Project.Web.UI.Controls.MainMenu 
 
 
        public event EventHandler StartUp; 
 
        public void SetMenuDataSource(object ds) 
        { 
            RadMenu1.DataSource = ds; 
            RadMenu1.DataBind(); 
        } 
 

So the binding continues to be down from the view keeping it passive. Using this pattern, you can save your grids using one event call from your view. Just don't forget to update your interfaces and presenter classes to implement your new events.

So try to remember:

Keep it simple at the UI, no IEnumerable<T> or IList<T> or ICollection<T> (No Types from your problem domain).
Basically, stay away from anything that requires your UI to have any knowledge of your problem domain and you will be fine.

I hope you find this useful, I know we have!

Kind Regards,

John



Tags
Grid
Asked by
Henrik
Top achievements
Rank 1
Answers by
Henrik
Top achievements
Rank 1
Nikolay Rusev
Telerik team
johnv
Top achievements
Rank 2
Share this question
or