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.
Related
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.
I have two ObservableCollections in my ViewModel. Both of same generic type.
Window has two ItemsControls each with ItemsSource bound on its own ObservableCollection from ViewModel.
Both use same same ItemTemplate. This ItemTemplate is very complex user control.
It's all done by the book.
In some cases, I move item from one collection to another. UI updates correctly. However, as control is complex, it needs about 1-2sec to render when it is recreated in new ItemsControl. And since this happens on drag and drop operation, it is not user friendly.
What I would like to do is to somehow preserve existing instance of ItemTemplate from source ItemsControl and reuse it in destination. I don't know if it is even possible, I couldn't find anything about it online.
I believe setup is fairly simple, but if needed I'll write some simplified version of code (I can't share the real code).
Thanks for any help.
What I would like to do is to somehow preserve existing instance of ItemTemplate from source ItemsControl and reuse it in destination. I don't know if it is even possible, I couldn't find anything about it online.
I am afraid it is not. When you disconnect an element from the visual tree and then add it back to a different parent element at a later stage, all elements that make up the control will be re-rendered.
I'm using WPF TreeView bound to my classes though MVVM to display a large array of multilevel data. Because of this, when I expand TreeNode, it takes some time and a lot of memory.
I think, that the memory requirement comes from TreeView scouting out nodes down the line, not just the first generation of the children, forcing those nodes to load data.
Is there any way to limit this "scouting" behavior to only the first generation of child nodes?
WPF generates TreeViewItem(s) only when they are displayed, i.e. no item is generated until its Parent expanded. So, I think the problem is not a "scouting".
Anyway, you may try to implement dynamic loading in your ViewModel by adding synchronization with TreeViewItem.IsExpanded using TwoWay Binding. Take a look at this. You may use the same solution for IsExpanded property. Don't forget to add fake item to tell TreeViewItem that it is expandable.
Check if TreeView is using VirtualizingStackPanel. I believe that it is used by default in .NET 4.0, but you must set it explicitly in previous .NET versions.
For more information, see How to: Improve the Performance of a TreeView.
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.
I've got a xaml of a window with an unnamed border control somewhere inside. The border control uses an attached property that I wrote and the attached property basically sets the border control's Name property to a known value, like "placeholder". After the window is loaded, it tries to find that border control through the name that attached property gave it.
The problem is that it doesn't seem to work. Window.FindName returns null. Any ideas?
Edit: The border control does get named before the Window.FindName gets called, so it's not that it hasn't been named in time.
As an alternate solution, I was thinking of just going through the window's children and find the one that uses my attached property. How would I do that?
Thanks!
To verify that the border is getting named correctly, you can run Snoop. This will show you the visual tree of your application, and all of the properties of every control.
If you want to enumerate the visual tree yourself, you can use the VisualTreeHelper class. Specifically, the GetChildrenCount() and GetChild() methods can be called to traverse the visual tree.