The traditional way to build your own view seems to be deriving a new class from View and then supplying it with renderers for specific platforms. In renderers you create the visual tree of elements that are displayed for that view. However, layout classes don't seem to have renderers and yet they are capable of drawing any visual structure of elements on their surface.
I wonder, is there a way to reproduce this behavior using only the Element class? Theoretically, it should have the means to establish proper parent-child relationships, but when I try to set the Parent property, child elements don't get displayed on the parent's surface. The parent itself is displayed.
So how do I get child elements to appear on the screen?
There is a property called LogicalChildrenInternal that is responsible for enumerating each element's children. Unfortunately, it is internal virtual and returns a static empty collection, so the Element class is not suitable for direct use. In classes like ViewCell and Layout, where this property is overridden, you can substitute the original collection via reflection and see that a new set children gets displayed on the layout.
Related
I wrote a molecular display component in WPF. I used an MVVM architecture data binding to bind atom and bond shapes to an underlying hierarchical data model.
The model can sometimes consist of nested Molecule objects, each of which contains Atom and Bond objects. It works well, but I have to flatten the hierarchy of molecules, and the collections of Atoms and Bonds, to data bind the View to them. In this display you are looking at a three-level deep hierarchy. The top level is one Molecule, which contains two nested Molecules, each of which contain two separate Molecules
This is very difficult to program against and hits performance. As I have used a generic ItemsControl and simply replaced the ItemsPanelTemplate with a Canvas, I was wondering if it is possible to customize a TreeView by replacing its ItemsPanelTemplate with a Canvas, and then using a HierarchicalDataTemplate to place each Atom and Bond on the Canvas.
My question is therefore: will this create a separate Canvas for each level of nesting? I don't want this. I want all objects to be positioned on the same Canvas and for the user to be unaware of the nesting unless I want them to be.
I have TreeList that is displaying my business object hierarchy, all of its parts implementing IVirtualTreeListData. However, at some point I want to make changes: remove some data, maybe add some data or move a leaf to another containing node. I can make the changes to underlying business objects, but displayed tree is not affected.
I presume the reason lies in the fact TreeList walks down the hierarchy of IVirtualTreeListData once, (it corresponds to first time expansion of the nodes), and then just uses he data stored in nodes retrieved on the way. How, then, can change in data source be propagated into view?
To enable automatical synchronization of the XtraTreeList nodes hierarchy with the underlying business objects, please implement an IBindingList interface for child objects collection which you provided as the VirtualTreeGetChildNodesInfo.Children property.
The simplest way to accomplish this task is to create a BindingList<YourBusinessObject>() instance within your BusinessObject to store all child object and assign it to the info.Children property within theIVirtualTreeListData.VirtualTreeGetChildNodes() method implementation.
In this case, the TreeList will automatically refresh the corresponding node when a your object is changed or deleted.
We use the ContentControl and other containers stuff in WPF. I need the notification with the new child control is added to the container. What is the best way to get the newly created control within parent?
The ContentControl only contains a single child which is attached via the ContentControl.Content property. You can hook the ContentControl.OnContentChanged to discover when the value of this property is updated.
The cleanest way is to derive from those control and override the methods that report the changes you are interested in. For example derive from ContentControl and implement OnContentChanged. This approach may not appeal to you.
If you want to detect changes in the child or children of controls without deriving from them, you can observe that such changes will affect the layout and so you can hook the LayoutUpdated event. The problem with this approach is that you need to keep track of the children that were previously added yourself by inspecting Child or Children looking for changes. You also have to be careful not to hang onto references to former children lest you create a memory leak. But it can be done.
Normally wpf objects inherits their parent's data context, so if you set a binding and theres no data context set, the binding engine it will automatically look for it in the parents. How can I make a custom class(that is not an UI element) to produce the same behavior when set as the child of another element?
Make it a subclass of Freezable
I have written a custom Silverlight control based on Control. I have two DependencyProperties called Top and Bottom which both hold child controls for a specific layout display. I then use a ControlTemplate to arrange these two controls into a grid, placing one on the 0 row and the other on the 1 row. The problem I have is that I cannot seem to figure out how to get each child control's Parent property to point to my custom control. When I inspect each control at run-time, the Parent property of each is null.
This is a simple example, but I think you can see the general problem. I have a number of more complex controls that all share this problem. I know there is some magic I am missing. If a ContentControl's Content property is set to some child it is somehow setting that child's parent to itself.
Edit: A little more info
In WPF, one might use functions like AddVisualChild(), RemoveVisualChild(), AddLogicalChild(), RemoveLogicChild() to manage parent/child relationships, but these functions are not available in Silverlight.
After quite a bit of research I believe that this is not possible. I was able to recurse through the Visual Tree instead of the Logic Tree using the VisualTreeHelper to accomplish my ultimate goal.
The Parent property cannot be arbitrary, it reflects the real parent of the control for use when rendering.
From MSDN:
Parent may be a null reference (Nothing in Visual Basic) in cases where an element was instantiated, but is not attached to any logical tree that eventually connects to the page level root element, or the application object.
...
Changing an element's parent is typically only done through manipulation of collections, by using dedicated add or remove methods, or through setting content properties of elements.