V1.3, C#: screen bounds of Visual, LayoutUpdated event ?
Posted: 12 Feb 2017, 15:53
We have two render systems in our application, Noesis and our own 2D CSG engine that uses Monogame. We use C#.
We render all our CSG elements to one big Monogame render-target "atlas".
All our UI elements are rendered using Noesis. Some of these Noesis UI elements display the CSG shapes from the atlas using an ImageBrush.
However, we only want to render those CSG elements for which the corresponding Noesis UI element is visible on the screen (when using a scrollviewer of lists of elements many elements can be off the screen).
To check if something is on screen, I need to get the Visual screen bounds.
To get the screen bounds (actually a parallelogram) in WPF, I can use a combination of TransformToAncestor and RenderSize (or 3 calls to PointToScreen), and I guess that would also work for Noesis. But it seems NoesisGUI does not have the LayoutUpdated event, so I don't know when to call this. I could call it every frame of course.
Also I would like to use an MVVM architecture, and the VM should not know about Noesis if possible.
Currently I have something like this:
The converters simply convert a to a Noesis texture and rectangle.
The CsgViewModel provides the CsgAtlas (a Monogame render-texture atlas of rendered CSG elements) , and texture coordinates within that atlas.
The CsgViewModel should also get Matrix and Size properties that must receive the Noesis element-to-screen matrix and local-space element-size.
I was hoping to achieve this by using a OneWayToSource binding, but again, I am missing a property that will be fired when the layout changes.
I could use attached properties, are these supported in C#? I can't get them working, my property-changed callback is never called.
On the other hand, all these bindings and converters feel like overhead; in WPF I would write a custom-control in C# for doing this, but I have no idea how to write such a custom control with C# bindings for Noesis.
Another solution would be to just use the Noesis virtualizing panel system somehow.
I'm a bit stuck here. For now, I'll just ignore this issue, but it will need to be fixed of course since otherwise I'm rendering way too many CSG shapes that are not visible.
We render all our CSG elements to one big Monogame render-target "atlas".
All our UI elements are rendered using Noesis. Some of these Noesis UI elements display the CSG shapes from the atlas using an ImageBrush.
However, we only want to render those CSG elements for which the corresponding Noesis UI element is visible on the screen (when using a scrollviewer of lists of elements many elements can be off the screen).
To check if something is on screen, I need to get the Visual screen bounds.
To get the screen bounds (actually a parallelogram) in WPF, I can use a combination of TransformToAncestor and RenderSize (or 3 calls to PointToScreen), and I guess that would also work for Noesis. But it seems NoesisGUI does not have the LayoutUpdated event, so I don't know when to call this. I could call it every frame of course.
Also I would like to use an MVVM architecture, and the VM should not know about Noesis if possible.
Currently I have something like this:
Code: Select all
<my:NoesisRectConverter x:Key="NoesisRectConverter"/>
<my:NoesisTextureConverter x:Key="NoesisTextureConverter"/>
<DataTemplate DataType="{x:Type my:CsgViewModel}">
<Rectangle Width="256" Height="256">
<Rectangle.Fill>
<ImageBrush ImageSource="{Binding CsgAtlas, Converter={StaticResource NoesisTextureConverter}}" ViewboxUnits="RelativeToBoundingBox">
<ImageBrush.Viewbox>
<Binding Path="TexCoord" Converter="{StaticResource NoesisRectConverter}" />
</ImageBrush.Viewbox>
</ImageBrush>
</Rectangle.Fill>
</Rectangle>
</DataTemplate>
The CsgViewModel provides the CsgAtlas (a Monogame render-texture atlas of rendered CSG elements) , and texture coordinates within that atlas.
The CsgViewModel should also get Matrix and Size properties that must receive the Noesis element-to-screen matrix and local-space element-size.
I was hoping to achieve this by using a OneWayToSource binding, but again, I am missing a property that will be fired when the layout changes.
I could use attached properties, are these supported in C#? I can't get them working, my property-changed callback is never called.
On the other hand, all these bindings and converters feel like overhead; in WPF I would write a custom-control in C# for doing this, but I have no idea how to write such a custom control with C# bindings for Noesis.
Another solution would be to just use the Noesis virtualizing panel system somehow.
I'm a bit stuck here. For now, I'll just ignore this issue, but it will need to be fixed of course since otherwise I'm rendering way too many CSG shapes that are not visible.