How to programmatically ensure the visibility of TreeView's item
Hi,
Is there a way to programatically scroll to a TreeView's item so that it's visible?
I've tried using
but it doesn't seem to work if the TreeView items are generated by hierarchical templates.
Note that WPF's TreeView implements its own BringIntoView which seems to be missing in Noesis GUI.
Is there a way to programatically scroll to a TreeView's item so that it's visible?
I've tried using
Code: Select all
ItemsControl::BringIntoView(BaseComponent* item)
Note that WPF's TreeView implements its own BringIntoView which seems to be missing in Noesis GUI.
-
sfernandez
Site Admin
- Posts: 2991
- Joined:
Re: How to programmatically ensure the visibility of TreeView's item
Hi,
Are you sure WPF's TreeView implements its own version of BringIntoView, I'm not sure about that, look in their public code:
https://referencesource.microsoft.com/# ... reeView.cs
Do you have a way to get the TreeViewItem container of the item you want to bring into view?
If that is the case you can simply call treeViewItem->BringIntoView();
Are you sure WPF's TreeView implements its own version of BringIntoView, I'm not sure about that, look in their public code:
https://referencesource.microsoft.com/# ... reeView.cs
Do you have a way to get the TreeViewItem container of the item you want to bring into view?
If that is the case you can simply call treeViewItem->BringIntoView();
Re: How to programmatically ensure the visibility of TreeView's item
I'm not sure about their actual implementation. I just guessed so because WPF TreeViewItem::BringIntoView seems to work, while in Noesis GUI, the method is unavailable in the first place (protected). Is there a reason for the FrameworkElement::BringIntoView being overridden as protected?
Casting TreeViewItem into FrameworkElement and calling FrameworkElement::BringIntoView works, but with slight differences from WPF. It only works if the item is already expanded, while in WPF it will expand and scroll to the item if it's collapsed.
Also as I stated in my previous post, for items generated using hierarchical data templates (as in my case) it seems that only containers (TreeViewItems) of the topmost items can be retrieved using ItemContainerGenerator::ContainerFromItem. Is there a way to retrieve the subtree items too?
Thank you.
Casting TreeViewItem into FrameworkElement and calling FrameworkElement::BringIntoView works, but with slight differences from WPF. It only works if the item is already expanded, while in WPF it will expand and scroll to the item if it's collapsed.
Also as I stated in my previous post, for items generated using hierarchical data templates (as in my case) it seems that only containers (TreeViewItems) of the topmost items can be retrieved using ItemContainerGenerator::ContainerFromItem. Is there a way to retrieve the subtree items too?
Thank you.
-
sfernandez
Site Admin
- Posts: 2991
- Joined:
Re: How to programmatically ensure the visibility of TreeView's item
BringIntoView(BaseComponent* item) is an internal method of ItemsControl only available for inheritors as it occurs in WPF just with another name: OnBringItemIntoView(object arg)). It is different from the one exposed by FrameworkElement that accepts no parameter or a Rect.I'm not sure about their actual implementation. I just guessed so because WPF TreeViewItem::BringIntoView seems to work, while in Noesis GUI, the method is unavailable in the first place (protected). Is there a reason for the FrameworkElement::BringIntoView being overridden as protected?
This seems to be a bug. Could you please create a ticket in our bugtracker?but with slight differences from WPF. It only works if the item is already expanded, while in WPF it will expand and scroll to the item if it's collapsed.
This is a problem in WPF too because of how ItemContainerGenerator is designed:Also as I stated in my previous post, for items generated using hierarchical data templates (as in my case) it seems that only containers (TreeViewItems) of the topmost items can be retrieved using ItemContainerGenerator::ContainerFromItem. Is there a way to retrieve the subtree items too?
https://stackoverflow.com/questions/394 ... witem-only
https://social.msdn.microsoft.com/Forum ... erlightnet
The only way right now to do this would be to manually search for the item. But this will be a very costly process as you'll need to expand each TreeViewItem, and do a tv->UpdateLayout() before continuing looking in its children. To know if a TreeViewItem corresponds to the specified item you can compare against its Header.
-
sfernandez
Site Admin
- Posts: 2991
- Joined:
Re: How to programmatically ensure the visibility of TreeView's item
Looking into this article http://alookonthecode.blogspot.com.es/2 ... n-wpf.html (see SelectItem function at the end).
The process I explained before can be speed up a lot if your data items know about their parent data items, as you can search down only the branch of TreeViews corresponding to the specified item.
The process I explained before can be speed up a lot if your data items know about their parent data items, as you can search down only the branch of TreeViews corresponding to the specified item.
Re: How to programmatically ensure the visibility of TreeView's item
Hi Sergio,
My concern is BringIntoView() being hidden from TreeViewItem because of the protected overload in ItemsControl, so we need to cast TreeViewItem* to FrameworkElement* to call the method. In WPF the BringIntoVIew() method is visible from TreeViewItem instance. I think it's better if you can reintroduce the method on ItemsControl interface (maybe by "using" declaration).BringIntoView(BaseComponent* item) is an internal method of ItemsControl only available for inheritors as it occurs in WPF just with another name: OnBringItemIntoView(object arg)). It is different from the one exposed by FrameworkElement that accepts no parameter or a Rect.
I will register the issue to your bugtracker.This seems to be a bug. Could you please create a ticket in our bugtracker?
The only way right now to do this would be to manually search for the item. But this will be a very costly process as you'll need to expand each TreeViewItem, and do a tv->UpdateLayout() before continuing looking in its children. To know if a TreeViewItem corresponds to the specified item you can compare against its Header.
Thank you. I've missed the fact that each TreeViewItem has their own container generator, and they need to be realized (expanded) first. Indeed our data item knows about their parent, so I've implemented the feature as you suggested, searching from topmost parent down after expansion, and it works.Looking into this article http://alookonthecode.blogspot.com.es/2 ... n-wpf.html (see SelectItem function at the end).
The process I explained before can be speed up a lot if your data items know about their parent data items, as you can search down only the branch of TreeViews corresponding to the specified item.
-
sfernandez
Site Admin
- Posts: 2991
- Joined:
Re: How to programmatically ensure the visibility of TreeView's item
I understand your concern now, we should rename the internal function to avoid hiding the FrameworkElement public function.My concern is BringIntoView() being hidden from TreeViewItem because of the protected overload in ItemsControl, so we need to cast TreeViewItem* to FrameworkElement* to call the method.
Sorry for the misunderstanding.
Re: How to programmatically ensure the visibility of TreeView's item
By the way, I'm now working on a small project of creating a tool for visualizing Noesis GUI visual tree. Can you suggest the best way to monitor a change in visual tree (e.g. visual child added or removed)? Is there any change event I can hook to from outside the Visual class? I've tried using SubtreeDrawingCommandsChanged event, but it seems to be raised on too many occasions.
-
sfernandez
Site Admin
- Posts: 2991
- Joined:
Re: How to programmatically ensure the visibility of TreeView's item
There is no generic way to detect that kind of changes in the tree.
The only way would be to detect changes in the specific properties of the container elements: Decorator.Child, ContentPresenter.Content, etc.
And Panel.Children collection provides a INotifyCollectionChanged interface that you can use to detect changes there.
Hope this helps.
The only way would be to detect changes in the specific properties of the container elements: Decorator.Child, ContentPresenter.Content, etc.
And Panel.Children collection provides a INotifyCollectionChanged interface that you can use to detect changes there.
Hope this helps.
Re: How to programmatically ensure the visibility of TreeView's item
Thank you. We will also consider that option.
Who is online
Users browsing this forum: Ahrefs [Bot] and 8 guests