ASP.NET TreeView Display images - c#

I’m trying to display images in a ASP.NET (web) TreeView control. Basically in the DB there is 1, 2 and/or 3 ticked and everything that is checked should cause an appropriate image(s) to appear next to that node on the tree. This all works except for then there is postback
I’ve used this [http://www.codeproject.com/Articles/14031/Displaying-Multiple-Images-In-The-ASP-NET-TreeView] and it works ok, except for when a postback occurs.
In addition to the +- symbols I also use the onselectednodechanged method, this causes the postbacks (this is ok as other things are happening on the page at the same time). But the postback looses the fact that it should display the images and they disappear.
I can only assume that the images are not saved in the viewstate as when the tree is rendered it opens to the correct point but ignores the images.
Is there a better way to have images displayed in a tree view? Or a simple way of telling the view state to remember the images
------------------ Extra info ---------------
I've just watched what happens to the nodes / child nodes during the postback. they revert to there default types.
When I create them they are created a ImageTreeViewNode which is inherited from the TreeNode.
After the post back the nodes are all TreeNode rather then ImageTreeViewNode. Is there a way to stop them reverting and loosing the extra info?

Ended up solving this by extending the TreeView class and the new 'ImageTreeView' class for my treeview control.
I changed the createNode method to use the new ImageTreeNode class (the extended TreeNode class)
Not sue if it's a good or bad solution, but it seams to work.

Related

Multiple custom controls affects control visibility

Ok, this is going to be a 1000ft long question, but there's a lot to cover so here goes:
I am creating a paged items control, the purpose of which is to display very large collections in a paged format. I've created a repository on GitHub which can be found here. I have removed any styling for simplicity.
Upon starting the application, it looks like this:
This is pretty straightforward really, there's navigation buttons, an items per page selector but that isn't really important. The problem here is when you click the button "Open New Window".
This will open a new MainWindow, but on the first window, the collection disappears, as shown below:
The image above shows the old window in front, as you can see, there is no list of content as there is on the new window.
So, after smashing my head against a wall for a couple of hours, I am in need of assistance. I'll provide an overview of how the project is structured.
AnagramPagedItemsControl
The control being used for displaying the content is a custom control called AnagramPagedItemsControl, it is responsible for handling navigation between pages. I think the key property here is the PagedCollection.
The PagedCollection dependency property holds the collection which is bound to the Models property in the TestItemsViewModel.
TestItemsViewModel
This is the DataContext of the MainWindow, each window instance should create it's own view model. The CreateTestItems() method is responsible for creating the list of test items.
LazyPagedCollection
The purpose of this collection is to encapsulate the logic of a paged observable collection, it only loads pages when they are needed, hence the laziness.
It exposes methods like NextPage which are called in the AnagramPagedItemsControl when the user clicks on the various navigation buttons. The view model can also call navigation on the LazyPagedCollection, this allows the view model to call navigation without having to go through the view to do it.
TL;DR
When I create a new Window, the content of the previous window disappears. The problem is almost certainly with the control however I am stuck as to how to fix the problem.
This is quite a large problem to look at so I'd be very grateful for anyone who can look into it. Again, the source code is here, please feel free to suggest alternatives or pick out anything that I may have overlooked.
Had some time to spare, so:
The problem is the setter for the CollectionView property in the style for AnagramPagedItemsControl in generic.xaml.
This does not instantiate a new ListBox every time the style is applied; it will just create the one ListBox, the first time the style is created, and use that value over, and over again. So in effect, every instance of MainWindow shares the same ListBox.
You can see this by setting the Tag property of PART_CollectionView to (for instance) "1" in SetupBindings(ItemsControl PART_CollectionView). When you open a new window, you'll see that PART_CollectionView.Tag contains the same value you previously assigned.

C# ASP.NET - Dynamic MenuItems in a user control are randomly being duplicated outside of control creation

EDIT: I needed to skip control creation during post back -- see my answer below.
I'm working on a very basic front end to a simple tool and I wanted to present some data in a much more sorted and useful way, instead of making one huge wall of text. I found this tutorial on building a simple tabbed interface using MultiView, but have run into a bizarre problem. I can't use Ajax tabs because of legal hissy fits over 3rd party software.
My webpage is a basic ASP.NET page with a user control plopped in the middle of it. In this control's ascx file, I defined the Menu (empty) and the MultiView (also empty) so that I can dynamically populate the tabs with content driven from an external file.
When the default page's OnInitComplete function is called, I call through to the user control to load the data file, then build out the tabs and the view content based on the loaded data. I tried doing this from PageLoad, PreInit, and CreateChildControls, but I kept getting an errors saying that I was setting the the MultiView's active view index at an invalid time (and also that there were 0 views despite the fact I just added a bunch of them):
ActiveViewIndex is being set to '0'. It must be smaller than the
current number of View controls '0'. For dynamically added views, make
sure they are added before or in Page_PreInit event.
But OnInitComplete appears to work just fine, so I went with that.
I iterate over the loaded data (multiple lists of strings), and for each list, I add a MenuItem with the list's title to the Menu and a View to the MultiView. The View is populated with a table->row->cell as in the above tutorial. In the cell, I add the list title and a CheckBoxList data bound to the list of strings.
So far so good, but when I click on a tab (or one of the checkboxes, etc) and there is a postback or something like that (the screen flashes as the site redraws itself), there is now a duplicate set of MenuItems immediately after the original. Each time I click on a tab or checkbox, another set of menu items are added.
I clear the MenuItem's Items list prior to building the controls and I verify that the controls hierarchy is structurally as expected after the control construction. Yet when one of my callbacks is called, my MenuItem list magically has some items added to it. None of my other controls appear affected at all. As a hack, I can remove the duplicates manually in my menu's OnMenuItemClick event, but I'd have to do the same in any of the callbacks I receive. Obviously I'd rather prevent this from happening. This has me stumped and I haven't been able to find anything online about it. Why would one set of controls have some content duplicated, yet every other control maintain its state correctly? My code is really simple so there isn't a way to add additional menu items without also adding the views. Anyway, there are a correct number of items prior to clicking on the tab/checkbox, an additional set immediately following in the callback.
This is my first time using ASP.NET, so I'm learning as I go. :) Thanks!
My problem was that I was not testing for postback before creating the controls. The code below is working for me.
In my user control's code behind:
protected void OnInitComplete( EventArgs e )
{
if( !Page.IsPostBack )
{
CreateMyControls();
}
}

ASP.NET 4.0, ScriptManager and HistoryPoints

I've got an ASP.NET 4.0 site. In the site there's a treeview control inside an UpdatePanel.
Keep in mind - when the user first visits the page, no postback has occurred (more on this in a minute).
When the user clicks on nodes in the tree, it triggers a postback. I can set history points as the user is moving through the tree - that's not a big deal. The history point is the ID of the selected node. (I want to use this to drive other information on the page)
There are two behaviors I'm seeing, and I'm stumped as to how to rectify these:
First, the history points always seem to point to the current item. If I start on Item A, then click Item B, when I hit the back button, I wind up at Item B for a couple of clicks (as if the history points are all set to the same value). I thought the history should be a running list of the nodes the user clicked...but in this case, it seems like the list is always a collection of history points with the current ID. (If anyone knows how to expose the collection of history points in the scriptmanager, I'd love to hear how)
Second, and more of a headache, is that when the tree initially loads, there's no postback. Is there a way to set a history point without an Ajax postback? (I'd like to have a way to preserve the default state for the tree, but right now going to item A from the root, then clicking back takes the user to whatever page they were on before the hit my page)
Has anyone else noticed weird behavior with the ScriptManager's history points?
I've also thought about alternatives - like viewstate, hidden fields, cookies, session variables...but I haven't had any luck with any of the solutions I've tried. Is there a way to get the back button to work without the history points? (I don't think there is)
To set a history point without a postback, you call ScriptManager.AddHistoryPoint().
I would venture a guess that adding your history points is not the problem, but in the ScriptManager.Navigate, you are not correctly loading the state back, or maybe you are relying on session information that has already been updated to Item B.
One way to see what is in the history state is to give each history entry a name/title that is descriptive enough to identify the state of the page. For testing, you could use a shortened version of the state string hash or just build a string to identify the state of the page and then when you click and hold the back button to view recent browser history, you will see the pages with descriptive names to identify them.
Here's the MSDN page talking about that: http://msdn.microsoft.com/en-us/library/cc472966.aspx
BTW: Sorry I'm late getting to this question. If you are still having problems, post some code so we can see what you're doing. I have implemented the history point functionality on pages with the tree control in an update panel on several of my pages.

Hiding CheckBoxes And Edit Buttons in a RadTreeList

I'm new to the "Telerik"-controls and I have a few questions! First of all, I'll give you a small resume of what we want to achieve and how I did it for now.
The customers has several clients who come to present themselves and they need to fill in their qualities (language skills, education, ....). Therefor we've created some templates (that already contains some crucial data). The templates can be hierarchical => Language Skill Dutch has two children : "Writing", "Speaking". They see that in an Hiearchical treeview (for now).
If they select the item in that tree, they automatically create a quality (with the templateid, contactid, etc...) for that type of template. Each time they call the treeview for that contact, the template who has a quality will be checked! And if they click on "Edit", they'll be able chaging some info of the quality.
That's in short what it does now and what's behind it. Now, they wanted a nicer looking method without having popups and such (everything in one screen). Then i found the "RadTreeList" of telerik. But for now I'm having the following problems :
The root of the tree can't be selected (best would be that the checkbox is hidden) => how do I achieve this?
Is it possible to hide the "EDIT"-button on the root? The root should never be selected on his own (no qualities for root elements).
So the big question, how can I take an item while looping through the whole treelist collection and say that I don't want to show checkbox and such?
With my treeview I iterated through all the nodes and then I did the needed modifications. But 1 => It was slow, 2 => It looked that nice, 3 => It didn't match they look of the CRM 2011.
What i've already achieved is showing everything hiearchical and select the "Node-Templates" (if I can call it so) that contains Qualities.
Hopefully you have enough info... If there are better alternatives, I'm open for everything, but it's kind off urgent, cause we'll have a demo-session soon :)
Info => It has to be in ASP.NET (C#)
It is true that you cannot select the 'root' of the treelist, but you can place an item in the first column to add new items at root level as illustrated here: http://demos.telerik.com/aspnet-ajax/treelist/examples/dataediting/net35automaticdataediting/defaultcs.aspx.
To hide the edit button for root level items, listen to the ItemCreated event, locate the edit button in the root items only and set its Visible property to false. This should work for checkboxes or other server controls inside the treelist rows and you do not have to perform explicit loops through the items later on.

Better than TreeView

I'm binding a lot of data to a TreeView control as the data is a natural category hierarchy. The problem is that there is a lot of it. I have managed to remove a lot of the overhead by only binding those nodes which appear in the visible tree, but this still leaves a lot in the ViewState, et al.
Does anyone have a method or alternative control for improving this kind of performance issue, please?
I was thinking about trying to inherit the TreeView control and dump it's viewstate value into Sesssion and back - but it's quite a hack I don't really have time for, right now...
Yes ... you can use On-demand Loading or Lazy loading of Tree View Items
i.e.
1- Only show root level nodes as in the Window Explorer.
2- when user Clicks a node , than only fetch the child nodes and show.
in this way , you will see only those nodes which actually user requested.
and you can give a checbox , which say 'SHOW WHOLE TREE EXPANDED' obviously , it would take more time to show.
you can also implement Node search functionality but please remember tree is specilized form a graph so use proper grpah algorithm while finding a node like (BFS or DFS)
you can also cache the results of nodes but this should be only done in the case when your tree itself is not used for hierarchy updation.
apart from the solution of dynamically loading tree view on expand, try ViewStateCompression for viewstate enhancement, use Asp.net Caching for output caching or just cache the objects by dynamically adding objects to cache using generating keys like "tree_" & parent. Cache objects are shared between sessions, so it will even be more helpful.
Hope this will help.

Categories

Resources