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

[Solved] InlineTemplate with databound items

15 Answers 335 Views
TreeView
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Eva
Top achievements
Rank 1
Eva asked on 17 Jan 2012, 04:51 PM
I know this should be fairly simple but I have combed the forums and docs and can't seem to find my answer!

I have the following binding in my treeview:.BindTo(Model, mappings =>      
{
    mappings.For<ACS.CSG.ReviewContentManager.Models.LayerViewModel>(binding => binding
        .ItemDataBound((item, layer) =>
        {
            item.Template.InlineTempate =
                @<text>
                    @Html.TextBoxFor(l => layer.Name)
                </text>;
            item.Text = layer.Name;
        })
        .Children(layer => layer.Children));
})

But the syntax on this is clearly not right.  The l in the LINQ statement of the TextBoxFor points to the list.  So I tried limiting it to the layer.Index but that didn't do the trick.  How do I create a template that allows for a textboxfor for the Name property of the current item?

Thanks!

15 Answers, 1 is accepted

Sort by
0
Eva
Top achievements
Rank 1
answered on 17 Jan 2012, 06:04 PM
I wanted to add some more detail on this as I uncovered more forum posts to read and feel further from a solution than I was before :(

The actual error I am getting is: "error CS0136: A local variable named 'item' cannot be declared in this scope because it would give a different meaning to 'item', which is already used in a 'parent or current' scope to denote something else"  Based on that I changed the code block to appear as below:
.BindTo(Model, mappings =>      
{
    mappings.For<ACS.CSG.ReviewContentManager.Models.LayerViewModel>(binding => binding
        .ItemDataBound((itm, layer) =>
        {
            itm.Template.InlineTempate =
                @<text>
                    @Html.TextBoxFor(l => l[layer.Index].Name)
                </text>;
        })
        .Children(layer => layer.Children));
})

However, now the For section of the mappings declaration is underlined in red with the following error: "Telerik.Web.Mvc.UI.TreeViewItem' does not contain a definition for 'For' and no extension method 'For' accepting a first argument of type 'Telerik.Web.Mvc.UI.TreeViewItem' could be found (are you missing a using directive or an assembly reference?)"

You can also see here how I tried to apply the index of the selected item to pull the property I am looking for.  Bottom line, is this possible?  If so, how do I do this?

Thank you!
0
Eva
Top achievements
Rank 1
answered on 17 Jan 2012, 10:04 PM
I am closer but I am still missing something.  I now have the following:
@{Html.Telerik().Splitter()
    .Name("Outline")
    .Orientation(SplitterOrientation.Horizontal)
    .Panes(hPanes =>
    {
        hPanes.Add()
            .Collapsible(true)
            .Size("30%")
            .Content(Html.Telerik().TreeView()
                .Name("Outline")
                .BindTo(Model, mappings =>      
                {
                    mappings.For<ACS.CSG.ReviewContentManager.Models.LayerViewModel>(binding => binding
                        .ItemDataBound((item, layer) =>
                        {
                            item.Value = layer.ID.ToString();
                            item.Content = () => { Html.RenderPartial("_Layer", layer); };
                        })
                        .Children(layer => layer.NonQuestionChildren));
 
                })
                .ToString()
            );
        hPanes.Add()
            .Collapsible(true)
            .Size("70%")
            .Content(@<p>Questions go here</p>);
    })
    .Render();
}

It puts the right controls on the screen but not in the right order.  I have attached an image of what the output looks like.  The View for the RenderPartial is:

@model ACS.CSG.ReviewContentManager.Models.LayerViewModel

@Html.HiddenFor(x => x.ID)          
@Html.CheckBoxFor(x => x.InDesignator) @Html.TextBoxFor(x => x.Designator) @Html.TextBoxFor(x => x.Name)

I could really, truly use some help on this.


0
Daniel
Telerik team
answered on 19 Jan 2012, 12:20 PM
Hello Eva,

To your questions:
  1. The item variable referred in the error message is the Raroz's item which comes into scope when using the Content method.
  2. In order for the compiler to pick the right overload of the BindTo method you should declare the type of the mappings parameter to be NavigationBindingFactory<TreeViewItem>.
  3. When nesting components you should use the Render method e.g:
    .Content(()=>
        Html.Telerik().TreeView()
        .Name("Outline")
        .BindTo(Model, (NavigationBindingFactory<TreeViewItem> mappings) =>     
        {
            mappings.For<ACS.CSG.ReviewContentManager.Models.LayerViewModel>(binding => binding
                .ItemDataBound((item, layer) =>
                {
                    item.Value = layer.ID.ToString();
                    item.Content = () => { Html.RenderPartial("_Layer", layer); };
                })
                .Children(layer => layer.NonQuestionChildren));
     
        })
        .Render()
    );


Greetings,
Daniel
the Telerik team
If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the Telerik Extensions for ASP.MET MVC, subscribe to their blog feed now
0
Eva
Top achievements
Rank 1
answered on 19 Jan 2012, 02:08 PM
Thank you for the pointer of where the object is coming from so I surely will not get the item conflict again.

However, I was already successful, sort of, using the RenderPartial command.  It just puts the controls in the wrong place.  Using exactly what you posted here the result is 100% the same as the image I attached to my third post.  So, still not solving my problem.  What do I need to do go ensure the controls appear actually IN the treeview and not on top of it and outside the scope of the panel even?

Thanks!
0
Daniel
Telerik team
answered on 20 Jan 2012, 03:18 PM
Hello Eva,

At least on my side, the TreeView is rendered correctly. I attached a screenshot of the page and the project used to generate it. Could you check it and see if I missed something?

All the best,
Daniel
the Telerik team
If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the Telerik Extensions for ASP.MET MVC, subscribe to their blog feed now
0
Eva
Top achievements
Rank 1
answered on 20 Jan 2012, 03:34 PM
I am not sure why you are not getting it on top since it is 100% the same View code.  However, what you have here and even your image is still not right.  The template should not appear as the child of a blank root.  It should BE the root.  I have the grid appearing as I would like without the editing controls right now.  The use of a template is still not working as expected.  I have attached an image here so you can see what I mean about the items being the root elements.

The Splitter code looks like this:

@{Html.Telerik().Splitter()
    .Name("Outline")
    .Orientation(SplitterOrientation.Horizontal)
    .Panes(hPanes =>
    {
        hPanes.Add()
            .Collapsible(true)
            .Size("30%")
            .Content(Html.Telerik().TreeView()
                .Name("OutlineTree")
                .DragAndDrop(true)
                .ClientEvents(events => events.OnSelect("tv_OnSelect"))
                .BindTo(Model, (NavigationBindingFactory<TreeViewItem> mappings) =>      
                {
                    mappings.For<ACS.CSG.ReviewContentManager.Models.LayerViewModel>(binding => binding
                        .ItemDataBound((item, layer) =>
                        {
                            item.Text = layer.Designator + " " + layer.Name;
                            item.Value = layer.ID.ToString();
                            if (layer.InDesignator)
                            {
                                item.ImageUrl = "~/Content/Common/Images/Icons/accept.png";
                                item.ImageHtmlAttributes.Add("style", "width: 16px; height: 16px;");
                                item.ImageHtmlAttributes.Add("alt", "Included in Designator");
                            }
                            else
                            {
                                item.ImageUrl = "~/Content/Common/Images/Icons/spacer.png";
                                item.ImageHtmlAttributes.Add("style", "width: 16px; height: 16px;");
                                item.ImageHtmlAttributes.Add("alt", "Not Included in Designator");
                            }
                        })
                        .Children(layer => layer.NonQuestionChildren));

                })
                .ToString()
            );
        hPanes.Add()
            .Collapsible(true)
            .Size("70%")
            .Content(@<p>Questions go here</p>);
    })
    .Render();
}



Eva
0
Daniel
Telerik team
answered on 21 Jan 2012, 05:05 PM
Hello Eva,

The template is rendered on the top because you are using the ToString method instead of the Render method on the TreeView. This way the template gets written directly into the response and not as part of the node.
To set the template as the node's root you should set it to the Text property. You should also set the Encoded property to false when there are HTML elements in the Text.
.Content(Html.Telerik().TreeView()
    .Name("OutlineTree")
    .DragAndDrop(true)
    .ClientEvents(events => events.OnSelect("tv_OnSelect"))
    .BindTo(Model, (NavigationBindingFactory<TreeViewItem> mappings) =>     
    {
        mappings.For<ACS.CSG.ReviewContentManager.Models.LayerViewModel>(binding => binding
            .ItemDataBound((item, layer) =>
            {
                item.Text = Html.Partial("_Layer", layer).ToString();
                item.Encoded = false;
                item.Value = layer.ID.ToString();
            })
            .Children(layer => layer.NonQuestionChildren));
    })
    .Render()
);



Regards,
Daniel
the Telerik team
If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the Telerik Extensions for ASP.MET MVC, subscribe to their blog feed now
0
Eva
Top achievements
Rank 1
answered on 23 Jan 2012, 01:51 PM
If I change it from ToString to Render, both Render and the Content keyword from the Slider control are underlined.  The error for Content reads: The best overloaded method match for 'Telerik.Web.Mvc.UI.Fluent.SplitterPaneBuilder.Content(string)' has some invalid arguments.  The error for Render reads: cannot convert from 'void' to 'string'.  So now the issue may just be how do I do all this inside the splitter!

Thank you so much for you continued attention.
0
Daniel
Telerik team
answered on 24 Jan 2012, 02:34 PM
Hi Eva,

I am sorry. I missed a part in the code snippet. The Content should be declared as an Action e.g.
.Content( () =>
    Html.Telerik().TreeView()
    .Name("OutlineTree")
    .DragAndDrop(true)
    .ClientEvents(events => events.OnSelect("tv_OnSelect"))
    .BindTo(Model, (NavigationBindingFactory<TreeViewItem> mappings) =>    
    {
        mappings.For<ACS.CSG.ReviewContentManager.Models.LayerViewModel>(binding => binding
            .ItemDataBound((item, layer) =>
            {
                item.Text = Html.Partial("_Layer", layer).ToString();
                item.Encoded = false;
                item.Value = layer.ID.ToString();
            })
            .Children(layer => layer.NonQuestionChildren));
    })
    .Render()
);

 
Kind regards,
Daniel
the Telerik team
If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the Telerik Extensions for ASP.MET MVC, subscribe to their blog feed now
0
Eva
Top achievements
Rank 1
answered on 25 Jan 2012, 09:03 PM
Copying and pasting what you have here I am getting the following errors:

1) Cannot convert lambda expression to type 'string' because it is not a delegate type
2) Cannot use a lambda expression as an argument to a dynamically dispatched operation without first casting it to a delegate or expression tree type
3) Delegate 'System.Func<object,object>' does not take 0 arguments
0
Eva
Top achievements
Rank 1
answered on 25 Jan 2012, 09:17 PM
I have found a workaround for all this that is working basically as expected based a lot of what you have suggested in this thread.  I have a partial page with the treeview in it.  I set that as the content using:
.Content(@<text>  @Html.Partial("_LayerTree") </text> );

The treeview partial view looks like as follows.  I have given up on the inline editing entirely and am doing this via a button, etc. now.
@{
    Html.Telerik().TreeView()
        .Name("OutlineTree")
        .DragAndDrop(true)
        .ClientEvents(events => events.OnSelect("tv_OnSelect"))
        .BindTo(Model, (NavigationBindingFactory<TreeViewItem> mappings) =>
        {
            mappings.For<ACS.CSG.ReviewContentManager.Models.LayerViewModel>(binding => binding
                .ItemDataBound((item, layer) =>
                {
                    item.Text = Html.Partial("_LayerTreeItem", layer).ToString();
                    item.Value = layer.ID.ToString();
                    item.Encoded = false;
                    if (layer.InDesignator)
                    {
                        item.ImageUrl = "~/Content/Common/Images/Icons/accept.png";
                        item.ImageHtmlAttributes.Add("style", "width: 16px; height: 16px;");
                        item.ImageHtmlAttributes.Add("alt", "Included in Designator");
                    }
                    else
                    {
                        item.ImageUrl = "~/Content/Common/Images/Icons/spacer.png";
                        item.ImageHtmlAttributes.Add("style", "width: 16px; height: 16px;");
                        item.ImageHtmlAttributes.Add("alt", "Not Included in Designator");
                    }
                })
                .Children(layer => layer.NonQuestionChildren));
        })
        .Render();
}

Only, doing it this way, the item Value is not being set.  I am sure I will be able to find a workaround for that as well, but it seems like the value feature should work using this method outlined above.
0
Daniel
Telerik team
answered on 26 Jan 2012, 04:07 PM
Hi Eva,

The Troubleshooting section of the documentation contains the known causes for the error you are getting. Loading the TreeView from a Partial View should also work.
I am not sure what may be preventing the value from being set. Could you send a sample project which reproduces the problem so I could check the exact setup?

Regards,
Daniel
the Telerik team
If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the Telerik Extensions for ASP.MET MVC, subscribe to their blog feed now
0
Eva
Top achievements
Rank 1
answered on 26 Jan 2012, 04:11 PM
Actually I made a change in my partial page and now I am getting the value so all is well there and at this point I am actually happy with the redirection, so I am going with it.

Thank you so much for all your help here as I would not have gotten to where I am now without it.  Even though it is not the original way I was looking to do it, it was still a successful forum thread if you ask me!

So again, THANKS!!
0
Jaganathan
Top achievements
Rank 1
answered on 23 Jul 2012, 04:24 AM

The model item passed into the dictionary is of type 'System.Data.Objects.ObjectQuery`1[TreeViewDB.Sales_Org_Master]', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable`1[TreeViewDB.Models.SalesOrgTree]'.


Can you please help me out with this?

I am trying to bind treeview to a model .

My Model Class:

public class SalesOrgTree
    {
        public int OrgId { get; set; }
        public string ParentId { get; set; }
        public string Name { get; set; }
       
    }

My Controller:

public class HomeController : Controller
    {
        public ActionResult Index()
        {
            ViewBag.Message = "Sales Org Tree";

            return View(GetNodes());
        }

        public ActionResult About()
        {
            return View();
        }

        private IEnumerable<Sales_Org_Master> GetNodes()
        {
            MyCompR2Entities ENT = new MyCompR2Entities();
            return ENT.Sales_Org_Master.Where(e => e.ParentId==null);
        }

My View:


      @model IEnumerable<TreeViewDB.Models.SalesOrgTree>
           
@{
    ViewBag.Title = "Sales Org Tree";
}

@(Html.Telerik().TreeView()
        .Name("TreeView")
        .HtmlAttributes(new { style = "width: 300px; float: left; margin-bottom: 30px;" })
        .ShowCheckBox(true)
        .DragAndDrop(true)
        .BindTo(Model, (NavigationBindingFactory<TreeViewItem> mappings) =>
            {
                
                mappings.For<TreeViewDB.Models.SalesOrgTree>(binding => binding
                        .ItemDataBound((item, sot) =>
                            {
                                item.Text=sot.Name.ToString();
                              
                            })
                            .Children(child => child.Name));
                            
                            
                            

               
            })
            

      )

Look forward for your reply.

Thank You.
J













0
Daniel
Telerik team
answered on 25 Jul 2012, 08:43 PM
Hi,

As the exception message suggests, the returned type from the controller is not the same as the one declared in the view. You should either use projection to convert the collection to one with generic type SalesOrgTree or change the model definition in the view and in the TreeView binding configuration to use Sales_Org_Master.
 

Regards,
Daniel
the Telerik team
Check out the successor of Telerik MVC Extensions - Kendo UI for ASP.NET MVC - and deem it for new ASP.NET MVC development.
Tags
TreeView
Asked by
Eva
Top achievements
Rank 1
Answers by
Eva
Top achievements
Rank 1
Daniel
Telerik team
Jaganathan
Top achievements
Rank 1
Share this question
or