Why does moving controls between panels cause an exception in deferred render? - avaloniaui

I am trying re-parent controls from one panel to another like this:
oldPanel.Children.Remove(control);
newPanel.Children.Add(control);
Which works fine with every control until i try to do it with the LAST child of the oldPanel, where i get:
System.NullReferenceException
HResult=0x80004003
Message=Object reference not set to an instance of an object.
Source=Avalonia.Visuals
StackTrace:
at Avalonia.Rendering.DeferredRenderer.Render(IDrawingContextImpl context, VisualNode node, IVisual layer, Rect clipBounds)
The panels in question are 4 different StackPanels in a DockPanel and it only happens when moving controls between certain StackPanels.
If i only remove elements and don't add them to a new panel, the exception is never raised, this makes me think maybe i have to do something to fix the scenegraph before the next render? is there something like UIElement.UpdateLayout in wpf?
Some things I tried:
- setting oldPanel.IsVisible to false fixes this but i want these panels to still be visible because i have their minWidth set.
- calling InvalidateVisual InvalidateMeasure and InvalidateArrange on all the panels(including the dockpanel) and the control being moved.
- using ISetLogicalParent.SetParent.
Am I just doing this wrong? I couldn't find any examples online of re-parenting controls at all.

Related

Making a touch event bubble through an element in XAML

I have a canvas containing several smaller controls. If I drag my finger over them, they get selected. The ManipulationDelta or MouseMove events fire. All working fine.
But I want to display an image above these with a lower opacity. So I added a simple Image element.
My question is: Can I make it so that the image doesn't "steal" my events and that the element below the image gets all data. One image can cover several objects below so I cannot simply forward the event.
I can give you examples of where this is implemented on request, but avoid to publish it directly since it might be considered spam or advertisement.
Thanks
Set IsHitTestVisible property of the image to False.
From MSDN:
If this property is set to false, a UIElement will not report any
input events, such as MouseLeftButtonDown, and cannot receive focus. A
routed input event that was originated by a different object can still
route to or through an object in the object tree where
IsHitTestVisible is false. The object where IsHitTestVisible is false
can choose to handle that event, or can leave it unhandled so that it
routes further up the object tree.

Adding Stationary New Items/Shapes To UI - Windows Store App

I'm sure this issue must have a very straightforward answer but I can't seem to find it. Any help is much appreciated.
Whenever a new item is added to the UI, either at runtime or dynamically once the program is running, it slides into view to reach its position (with inertia). Only when it reaches that point are certain properties applied: like transform properties or opacity values. For example, if a rectangle set to 50% opacity is added when a button is tapped, it will slide onto the screen about 30 points from its actual position at 100% opacity, reach the correct position and then change to the correct 50% opacity.
I would like to be able to turn off this default behavior so the rectangle appears immediately at the correct position with all the properties set.
I've found that I'm asking two separate questions and that both have been answered on this site (links below).
Individual objects can be targeted using the Transitions property under Miscellaneous in Visual Studio 2012.
How to remove EntranceThemeTransition from object or container in Windows 8 Store Apps?
RenderTransform occurs after EntranceThemeTransition on a TextBlock

SL 4: ScrollViewer - RequestBringIntoView

How can I find the component in a ScrollViewer that handles the RequestBringIntoView event?
It isn't exposed on the two ScrollBar parts (not directly, anyway).
Thanks for any pointers...
UPDATE: Related: Can I get the ScrollContentPresenter part of the ScrollViewer? How?
Thanks --
Bigger picture:
We have a large Canvas contained in a ScrollViewer. At runtime, an arbitrary number of UserControls (I'll call them 'Blobs') are added to the canvas from the db. Their position and content come from the db. A user can 'select' a blob by clicking on it, and its appearance changes to indicate it is selected.
If the user uses a scrollbar to move the selected blob out of view, then clicks on another blob, the Canvas is scrolled so the previously-out-of-view blob is in view again. I assume this is due to some object raising the RequestBringIntoView, and the ScrollViewer is handling it.
Hope this makes sense...
Yet more info:
Added a handler (sb_ValueChanged) to the Scrollviewer's scrollbar ValueChanged event. Here's the stack from the mouse click that precipitates the scrolling:
OurControl.sb_ValueChanged() System.Windows.dll!System.Windows.Controls.Primitives.RangeBase.OnValueChanged() System.Windows.dll!System.Windows.Controls.Primitives.ScrollBar.OnValueChanged() System.Windows.dll!System.Windows.Controls.Primitives.RangeBase.OnValuePropertyChanged()
System.Windows.dll!System.Windows.DependencyObject.RaisePropertyChangeNotifications()
System.Windows.dll!System.Windows.DependencyObject.UpdateEffectiveValue()
System.Windows.dll!System.Windows.DependencyObject.SetValueInternal()
System.Windows.dll!System.Windows.DependencyObject.SetValue()
System.Windows.dll!System.Windows.Controls.ScrollViewer.InvalidateScrollInfo() System.Windows.dll!System.Windows.Controls.ScrollContentPresenter.VerifyScrollData()
System.Windows.dll!System.Windows.Controls.ScrollContentPresenter.ArrangeOverride()
System.Windows.dll!System.Windows.FrameworkElement.ArrangeOverride()
If only I could find out what the FrameworkElement that starts the mischief actually is...
Sorry... it doesn't seems to exist like it does in WPF. Check this link for a handy solution.
Update: Ok... for this you might need to walk the visual tree and some sort of recursive search need to be done. However, assuming you are using the default template for the scrollviewer as seen here, you can directly ask for the ScrollContentPresenter with something like this:
var BorderChild = VisualTreeHelper.GetChild(MyScrollViewer, 0);
var GridChild = VisualTreeHelper.GetChild(BorderChild, 0);
var ScrollContentPresenterChild = VisualTreeHelper.GetChild(GridChild, 0);

winforms - usercontrol with dockstyle fill not correct size during form load

My main form has two panels, left docked and right docked. The right side panel has two child panels with top dock and bottom dock settings. The usercontrol is added to the right side top panel.
My usercontrol has a panel and a label. The panel is anchored on all 4 sides, the label is anchored on all except the bottom. At runtime I create this usercontrol and set it to dockstyle=fill and then I add it to my top right panel.
With everything set to "fill" I expect that when I add my usercontrol to the panel it will take on the appropriate width and height and pass that info to the child controls (labels) inside of my usercontrol.
My problem is that this stretching of the size does not happen when I create my objects during the Load event on my usercontrol. Even though initializecomponent has ran for the usercontrol the panel inside of it (4 corners anchored) has not taken the x/y values of the available space. As a result my usercontrol shows up about 50% of the width I want.
Lets say that instead of creating objects during usercontrol load that I instead start a timer and have the timer call my create routine when it raises the tick event. When I do things like this my objects are created with the full width/height that I expect. The only issue here is that this causes a delay in my interface.
Can someone help explain this behavior? My mainform is calling a "load gui" routine which is instantiating usercontrols, setting panel sizes, and then adding usercontrols to those panels. This particular user control is the last to load into the panels from that load gui routine so it does not make sense that the parent panel width/height would not be known yet. This is one of my first apps where I am purposely trying to use dockstyle=fill to keep things consistent across different main form sizes without writing all the extra size_changed code handlers. I'm sure this one is easy to work around once I know where the problem lies.
Thanks for any help provided!
this turned out to be a padding issue on the parent usercontrol. I also had to allow a bit of wiggle room to make sure that the controls didn't overflow the panel so I did a parent.width - 15 and that along with the padding made everything work much better.

Adding visible elements to a custom Panel in Silverlight 3

As I understand it, a Panel isn't meant to have any visible "chrome." The StackPanel, Grid and Canvas don't have any visible elements (with the exception of the gridlines, which they say are only for debugging layout.)
In my example, I am going to create a Custom Panel that uses Attached Properties to lay out its children controls. However, I want my Custom Panel to present a visible "grid" of sorts in the background. The look of the grid (sizing and positioning) will depend on the size and position of the child elements.
What are some of the ways to achieve this? Being very new to Silverlight and XAML in general, my first guess was to create a Custom Control which includes my custom panel for layout.
I think I'll be able to figure out the specific code, but I need to be pointed in the right direction in terms of what building blocks are appropriate for this scenario.
You are correct that custom Panels cannot show any extra chrome; they can only display their Children (Grid being an exception).
To do what you want to do, you could create a custom Panel which just adds extra Children to display the chrome. This would not be a good design though (since users of the Panel would see these extra items in the Children collection).
The best idea is to do what you said: create a custom Control that exposes a Children property. This control could internally use a private custom Panel to lay out these elements (e.g. TabControl uses a special TabPanel for laying out the tabs). In the Controls default template, you might want to use TemplateBinding on the Panels' Children property to your Control's Children property.
Panel can add Adorners to its children, read this article about adorners: http://msdn.microsoft.com/en-us/library/ms743737.aspx