WP7 - Implementing a tree of comments. ListBox, Tree controls, etc? - windows-phone-7

I want to implement a screen to display a tree of comments in WP7. Each comment can have children comments and so on. Each child comment will be visually distinct from its parent via indenting
ie:
"comment text"
"Some child comment text"
"Some child comment text"
"some child comment text"
"comment text"
"Some child comment text"
What would be the best way to go about implementing this? I'd like to keep the implementation as simple as possible so initially I was thinking I could use a single ListBox and programmatically set the Padding/Margin of each comment/ListItem, depending on its depth in the tree. But I can't seem to get it working. Any examples, suggestions, recommendations, etc?
Edit: Doing some additional reading, it seems like a DataTrigger would have been perfect for this sort of thing http://www.codeproject.com/Articles/113152/Applying-Data-Templates-Dynamically-by-Type-in-WP7 ...But WP7 doesn't support triggers.
One other idea I had was to make the Margin/Padding a Property of the Comment class, and then databind to that...this should work, but I'm contaminating my Comment class with display information. Any ideas on how I could databind the Margin/Padding value but somehow not mix model & view codes?

You'll have to roll your own, either from scratch, or by assembling something out of existing controls. ListBox looks like a good bet for this purpose.
Take a peek at this MSDN thread (web archive - thread now moved/deleted), it has several suggestions about simulating a TreeView using a ListBox, and a claim (which I have not verified) that you can use System.Windows.Controls.TreeView in WP7 (with the caveat that you also need System.Windows.Controls.Toolkit).
The marked answer, written by Shaun Taulbee:
Tree view behaviour in a listbox could be mimiced with a bit of smarts in the collection handling. Features your classes would need to support that come to mind are
a collection whose elements supports retrieving child collections
similarly to be able to detect if an element has child collections
in the data template for the listbox show one element of the stackpanel for expansion state based on presence of children and whether or not expanded
in the data template for the listbox show one element of the stackpanel for indent which reflects the depth of the child - to accomplish this best you should have a collection that represents a flat version of your tree data to bind to - then when you insert items you can make the indent based on the indent of the parent item that was just clicked
when a node is clicked in the listbox you insert the children from that node into the flat collection that the listbox is bound to
when the node is clicked again the children are deleted from the flat collection
You could encapsulate all of this into some neat classes to provide a fairly simple reusable api I would imagine if you wanted.
This thread has a fair amount of noise, but down at the bottom there's a comment from Mark Chamberlain:
"TreeView is not a natural fit for the phone, you can emulate Treeview
in other ways, for example, with ListBox item templates, Pivot or with
other List patterns. It will depend on how many levels of the tree
you will have.
"For example, you can template your ListItem to contain a label and
another Listbox with same item template. Doing this you can emulate
as many drill in levels as you need to handle, but only one branch at
a time."
"You may be able to re-template the TreeView (source is also available
in the Silverlight Toolkit), but it isn’t a supported scenario, and
you would need to do a decent amount of work to get it looking good on
the phone from a design & re-templating standpoint."

The following should be good starting points, both altering the ItemTemplate for a ListBox control :-
http://3water.wordpress.com/2010/07/25/listbox-on-wp7/
http://weblogs.asp.net/psheriff/archive/2010/10/27/windows-phone-list-box-with-images.aspx

For WP8 you can use this one TreeView_WP8

Related

UI Collapsible items in Elm: a css-only solution vs storing more data in the model

For example when implementing these collapsible items:
First approach that comes to my mind is to store a variable in the model expandedItems: List ItemId
to verify if an item is expanded you check if its id is in the list
to expand an item you add its id to the list
to collapse an item you remove its id from the list
There also are css-only solutions like this one https://jsfiddle.net/5hcwzf7s/2/
What would the advantages / disadvantages of css-only over the id list be?
I think storing the list in the model is common, easy to understand, and the usual way to do things like these.
I find a few downsides to the css solution:
is hard to read and understand
is fragile and hard to maintain
might not work on all browsers
uses href which makes the item id show up in the url when you click to expand
treats expanding as a url change, and when the user clicks back it unexpands the item instead of navigating to the previous page
only allows one item to be expanded at a time
On the other hand, I find no downsides to the expandedItems list approach. Performance might be a concern because we're operating on a list, but the user will have to be expanding thousands of items to make the list long enough to notice any difference. I don't think is polluting the model either, this kind of information is what the model should hold.
I think you want to put this all in your model. The css approach is perhaps a nice trick, but is not very scalable.
In particular you would end up putting state in the css file, and part of it even twice. Keep it all in your model, put the full content into the screen, and then just attach a class when contracted, which sets a max height and truncates the rest with elipsis

Using AngularJS, which is optimal with regards to ng-repeat

I have a potentially long repeating list with lots of data associated with each reapeated list element. There is also a hidden panel that contains more data and interactive tools that can be used on each repeated element (comments, tags, etc.).
My question is: Is it more efficient to include a duplicate of this panel within each ng-repeat, already filled with the appropriate data, or have one panel outside of the ng-repeat scope, who's data get's fill after clicking the 'panel toggle' button?
Extra details: This is a responsive site, with an emphasis on mobile use, so we are trying to minimize data sent, and make the amount of Javascript short and sweet (so far it hasn't been a problem at all).
After typing it out, I think the best option would be to have one tools panel, and populate it depending on which 'panel toggle' button is clicked. Fewer DOM elements the better, right?
It also leave it open for lazy-loading of the extra details in the future.

Load a XAML Layout dynamically based on User interaction

Good day, I am quite new to windows phone and so please bear with me. I have a requirement to load a XAML layout based on what the user chooses. For example, if i have 4 XAML layouts A, B, C, D, when the user chooses C, the respective XAML layout should be loaded and if A is choosen later, that should come up. I can create different XAML layouts and use the OnNavigateTo Method, but i think its not very efficient. Is there a way, i can group the XAML Layouts together so that it can switch between them easily?.. I have heard of using templates, but can't really find any concrete example of how it works. Any help or links will be greatly appreciated. Thank you.
From my understanding you do not need to use templates. Since there are four different actions that have four different views associated with them, there shouldn't really be a problem with having a separate page for each action.
The problem might also be this - how different are the layouts? If data is the only thing that changes across them, you might think about having a view model to bind to and simply change the bindable source.
Bottom line: just use pages, or a single page bound to dynamic data, depending on your scenario.
In my knowledge , I ask you to prefer the UserControls implementation in your UI. You can have A,B,C and D layouts as a separate UserControls and can have those UserControls in the same page. Just make the visibility changes based on the condition that recognize it in the code behind. I think it may help you.
You can solve this in many different ways. If you are not supposed to load the layout on the same page, create 4 separate pages for each view and navigate to correct page.
If you are required to update the current view, you can choose one of the following:
- Place all four layouts into each own Grid and set Visibility="Collapsed" for each one. Then, when you need to show a layout, simply change its Visibility to True.
- Same as above, but use Visual States to add some animations.
- Create 4 user controls and dynamically create the one you need and add it to the current page.
You need to account for several factors here:
- Clean code and clean design.
- Animations and transitions.
- What about Back key? If user is supposed to navigate back to selection screen once he is done, consider navigating to separate pages.
Don't forget the last point, it may be crucial when choosing the right solution.

WP7 Listbox how UI virtualization work

I'm using ListBox which has VirtualizingStackPanel, which is said to support UI virtualizing by default.
However, when I set my listStudent (of type ObservableCollection, and have 5 Students in it) as ItemsSource for my Listbox. Then whenever user scroll to the end, I add another 5 Students to my listStudent (and of course UI is notified). But I see that memory consumed keep increased. There's no different from StackPanel in term of memory
How UI virtualization work? How to keep memory low when adding new item to listStudent?
virtualization means list do not construct the list items which you have not scroll to yet.
so you can put your test code to item's loaded function or used converter code. you can see whether virtualization works
for example
you can bind a converter to student's name prop and you can log it .then you know when the item create indeed
Ensure that you don't modified ListBox ItemsPanel that destroys UI virtualization
Sheldon_Xiao on has pointed out some references on MSDN that helpfully explain UI virtualizartion

Dynamics AX 2009: How to sort an unbound form control's contents?

I was using a Listbox control on a form, and programmatically adding items to it. I thought that if I called the sort(SortOrder::Ascending) method on the Listbox it would do just that -- however, I was wrong.
Ultimately, I am unable to achieve these results. I don't have to use a Listbox, but I need two pieces of functionality:
Programmatically be able to add Strings to the control
Be able to run code when an item is clicked or selected
The list should be able to be sorted alphabetically
I couldn't get the listbox to sort either. Easiest might be to use a "ListView" control instead of a listbox. You can see how to use AND sort in (AOT>Forms\tutorial_Form_ListControl). Your requirements #1 & #2 are possible on almost anything you do. The issue is sorting I'd think.
Another option, keep a local variable that controls the sorting. I would use a collection class, either an Array or Map so you can control the sorting via key-value, then you could just re-load the listbox when the user added/removed something. Since it's client side and it doesn't sound like the listbox will have 1000+ controls, re-loading it probably won't be a significant performance hit. You can also use listbox.insert([value], [index]), to insert into the correct location if you are controlling properly.
Another option, hi-jack any simple table from the AOT (TmpABC is a good one), insert the values, then sort using a simple query or even better, set the TmpABC to the ListView control's datasource and just sort via datasource sort..

Resources