How to get top level node in ASP Tree View - asp.net

I have a sorting function which accepts TreeVIew Node as argument and then sorts the node. How do I pass top node to this function?
Here's the code of my Tree View:
<asp:TreeView id="mytv" runat="server"></asp:TreeView>
Here's my sorting function code:
private void(TreeNode node)
{
rest of code here
}
I tried the following but it didn't work.
sort(mytv.TopNode)
And
sort(mytv.Nodes)

Try this:
TreeNode currentNode = treeView.SelectedNode;
while (currentNode.Parent != null)
{
currentNode = currentNode.Parent;
}
You are iterating from some node (does not matter which one) and go up the hierarchy until the Parent of the current node is null, that is, the current node is the Root.
Also, here is the class reference for the TreeView:
TreeView class reference
You will be able to figure out, from the class reference that
sort(mytv.Nodes)
did not work because Nodes is not a node but rather a collection of nodes.
Also, the TreeView does not have a TopNode attribute.

Related

Preselect items in a TreeView

I am implementing a category mapper. There are 2 TreeViews. Both contain categories from different sources. (Even they look like from the same source)
The user should be able to map ONE category from the left to multiple of the right treeview. This gets stored in a config file.
However, when the view is initially loaded and the user clicks on a category on the left, I want to preselect the mapped categories on the right, loaded from the config file.
I saw that I can do this with ONE selection, but I don't see an option to do this for multiple ones.
How can I achive this?
Here a ootb running demo implementation
I went through your gist and it seemed that the problem was binding selections right? I did some light digging and found that binding observable lists isn't easy. I don't think I even saw a solution that wasn't just adding listeners to mock a binding. However, wrapping that list in a SimpleListProperty seemed to do the trick. Here's a demo:
class TestView : View() {
// This mocks your target list in the ViewModel
val targetList = SimpleListProperty(listOf<String>().asObservable())
override val root = vbox(10) {
// Both table views and tree views use an Observable Selection list
listview(listOf("asefas", "asefasef", "asefasefasefase").asObservable()) {
// Wrap in SimpleListProperty, then bind
targetList.bind(SimpleListProperty(selectionModel.selectedItems))
selectionModel.selectionMode = SelectionMode.MULTIPLE
}
setPrefSize(300.0, 300.0)
}
init {
// Target list now reflects changes made to selection model
targetList.addListener { _, _, change ->
println("Selections changed to: $change")
}
}
}

Java FX looping through Anchor pane to get CheckBox name and if selected

I have an Anchorpane which will have up to 20+ check boxes on it. I want to write a loop to get the name of each check box and if it is selected.
I have this working code so far
import javafx.scene.layout.AnchorPane;
#FXML
private AnchorPane lootAnchorPane;
ObservableList<Node> children = lootAnchorPane.getChildren();
for (Node child : children) {
System.out.println(child.getId());
}
This prints the id's well enough but I am not able to use child.getText() or child.isSelected(). As far as i understand the Checkbox classes are returned. I think it has something to do with the #FXML annotation. But im not sure how to implement this inside a for loop?
The asker has indicated that this question has already been answered by the kind commenter Sedrick. To try and make it as clear as possible to anyone viewing this post afterwards, I am posting a formal answer with a code example.
To use CheckBox methods with Node objects you have to first make sure the Node is an instance of a CheckBox. Use if (child instanceOf Node) to do so. If they are, it is safe to cast them to CheckBox type, and you can then use CheckBox methods with them.
ObservableList<Node> children = lootAnchorPane.getChildren();
for (Node child : children) {
// check if Node is an instance of CheckBox.
if (child instanceOf CheckBox) {
// Cast child Node to CheckBox
CheckBox checkBox = (CheckBox) child;
// --- do stuff with the CheckBox object.
}
}

Rewiring actions of parent to a child viewmodel

So here's my screnario. I have a toolbar at the top (office style), with buttons. This is hosted in a shell. Some of those buttons are applicable only to certain child view models as they get loaded. Ideally what I would like to happen is have the buttons action.target repositioned to child view model as it gets created (I kind of got this working by settings Action.Target="ActiveItem" on them. This doesn't solve the problem fully though:
a) When the child viewmodel is closed and there is no active item, I want them to reposition to Shell as the target so they can be set to "default" state.
b) I noticed that when child viewmodel is closed and the shell being the conductor has it ActiveItem=null, the hooks from the action are still bound to the living instance of the last viewmodel, so doesn't looks like it got disposed of. Memory leak?
Any suggestions how to implement this scenario?
What about adding a property to your ShellViewModel which points to the action target and updating it when stuff gets activated/deactivated:
e.g.
public class ShellViewModel
{
public object ActionTarget
{
get { return _actionTarget; }
set
{
_actionTarget = value;
NotifyOfPropertyChange(() => ActionTarget);
}
}
// Then when the active item changes just update the target:
public override NotifyOfPropertyChange(string propertyName)
{
if(propertyName == "ActiveItem")
{
if(ActiveItem == null) ActionTarget = this;
else ActionTarget = ActiveItem;
}
}
}
Now bind to that:
<SomeMenu cal:Action.Target="{Binding ActionTarget}" />
Not sure if that will work or not but I'm sure I've done something similar in the past. (You may also have to explicitly call NPC on your actions before they will update after you have changed ActiveItem)

asp.net TreeView Expand question

hope you help me with I think a simple TreeView Expand problem.
I have a TreeView control in my MasterPage and my default depth is 2 and I see that when I click on the deeper node it keeps expanded.. But when I redirected into another page, the node collapsed.
I have a problem with my code which suppose to keep the node expanded.
TreeNode thisNode = tvCategories.FindNode(Session["SelectedCIDValPath"].ToString());
if (thisNode != null)
{
thisNode.Selected = true;
thisNode.Expand();
thisNode.Select();
thisNode.Expanded = true;
lbl.Text = "valupath: " + Session["SelectedCIDValPath"].ToString();
}
as you can see, I tried all the possible properties and methods to keep the deeper node expanded.. but it doesn't work.
Please help me? Thank you so much
It happens to be the case (and I find it just a bit frustrating) that expanding a node does not also cause parent nodes to expand. In order to ensure a node expands, it is necessary to also ensure that the parent nodes expand. I keep an extension method handy for this purpose:
public static void EnsureExpanded(this TreeNode node)
{
if (node != null)
{
EnsureExpanded(node.Parent);
node.Expand();
}
}
You can employ the extension like so:
TreeNode thisNode = tvCategories.FindNode(Session["SelectedCIDValPath"].ToString());
thisNode.EnsureExpanded();

Hierarchical Data In ASP.NET MVC

I am trying to come up with the best way to render some hierarchical data in to a nested unordered list using ASP.NET MVC. Does anyone have any tips on how to do this?
I suggest jquery tree view plugins for making it function like a tree, but as for render, just put it in a recursive lambda helper to do the nesting.
You mean... you want some sort of tree view?
You can actually get the treeview control to work... but you have to wrap it in server side form tag to function. You'll get the usual nastiness that that brings (like generated ids and viewstate) but it will work from a rendering perspective.
If you want to just create tags and nest them, it would be pretty easy to do with foreach() loops.
I believe currently there is no such control.... TreeViews are complex by nature. You can of course "draw" a hierarchy as much as you like using all sorts of repeaters and loops, but to achieve functionality of a tree view like the one in the Web forms toolbox... you have to wait !
Why don't you pass your model in the form of a tree to the view?
/// This is the model class
public class MyTreeNode<T>
{
public ICollection<MyTreeNode> ChildNodes {get;}
public T MyValue { get; set; }
bool HasChildren { get { return ChildNodes.Any(); } }
}
///This is the html helper:
public static string RenderTree<T>(this HtmlHelper html, MyTreeNode<T> root, Func<T, string> renderNode)
{
var sb = new StringBuilder();
sb.Append(renderNode(root.MyValue));
if (root.HasChildren)
{
foreach(var child in root.ChildNodes)
{
sb.Append(RenderTree<T>(html, child, renderNode));
}
}
return sb.ToString();
}
I didn't actually test this code, but it's about the idea. You can imagine creating your own recursive html helper to render a tree.
For that (rendering hierarchical menu, treeview, etc) i use recursive calls of custom component (ascx, or aspx in new preview5).
I give component first level of items (List of items), and component then check for each item in list if there's any child items and call itself with list of that child items.
You can build hierarchical graph of objects in controller, or just 1 dimensional list with ParentID property.

Resources