I've been doing a lot of reading into WPF drawing and performance and it's apparent that some methods of drawing are better than others. I have however gotten confused with different people's terminology of things and just want to clarify one issue.
The system I'm working on has lots of gauges on a screen (exactly like a speedometer in a car). The scale and range indicators can change and are different on each gauge. Is it best to draw these in the xaml or in the .cs file behind it. The reason I'm asking is that we are starting to see performance issues in the system when a lot of gauges are on display and I'm trying to isolate the cause.
Currently it's drawn behind with each individual segment added like children.add(UIElement).
I'm not sure if placing them in the xaml or the code behind makes a difference - at the end of the day these objects get pushed onto the visual layer one way or another.
Your issue is more likely because you're using fully blown UIElement instances.
For performance enhancements, try using more light-weight objects, i.e. DrawingVisual
These objects are not as powerful as UIElements, so you may lose some functionality that you want to use that you'll need to reimplement another way.
This documentation should put you on the right track.
Related
There is a 3D simulation I made with helixtoolkit.wpf, but it is not effective at all in terms of performance. How can I adapt this project to SharpDX? I could hardly find any information about it on the internet. Is there a resource or shortcut you can recommend?
That would be a total rewrite. HelixToolkit and SharpDX is in no way compatible in scope.
HelixTookit is a wrapper around Wpf and provides a bunch of convenient controls and functions to easily display viewports with navigation etc.
SharpDX is a wrapper around Direct3D, so provides a much lower level access to the hardware. But you would need to write a lot of components yourself to be able to provide anywhere near the level of functionality of Helix. SharpDX is also no longer maintained, so you would spend a lot of time porting to a effectively dead technology.
As always with performance you should start with profiling. Is it really Helix3D that is the bottleneck? Or are you using it in a way that is inefficient? Before doing a major rewrite you should be certain you have explored all other options for performance optimization.
One thing you might try is to export your model to a file and open it in the windows 3D viewer, I suspect that uses the same underlying wpf code to display 3D models, so it should give a fair estimation of the possible performance.
I am building a custom UI framework in WPF where I basically ditch as much of the built-in layout system and controls as I can. So far I have been branching off from UIElement directly, but since I am already doing the measure, arrange and rendering myself, I am thinking I could slice off more of the WPF legacy by getting even "closer to the metal" (especially when it comes to layout / rendering). How close is it possible to get while staying in managed code and not being afraid of doing the dirty work myself?
I am toying with a prototype concept on the side now where I only have one element inheriting from UIElement: a Root object, similar to a stripped down Canvas, that "hosts" the rest of my layout engine and channels relevant IInputElement benefits into it. From that point onward, all elements would be completely custom objects not inheriting from anything in WPF, but rendering directly into the DrawingContext of Root (in its OnRender method).
Now I'm wondering about the relative performance of having a WriteableBitmap root element and manually draw onto that instead, for example using WriteableBitmapEx for convenience. Not having anti-aliasing isn't an issue, neither is a custom hit testing system.
My thoughts are primarily that WriteableBitmap(Ex) does not have the privilege of any GPU acceleration gains and therefore will be [much] slower when large areas needs to be repainted / transformed.
I do have other needs for a "pixel-based-rendering-engine-in-the-engine", though, so I am still interested in some perspective on this.
Any insights?
Edit: And what about SharpDX in this context? Maybe once I'm at it I might as well go for a WinForms solution with a DirectX wrapper like SharpDX (..or.. I guess what I really should do is sign up for the whole C++ enchilada, but unfortunately I don't have time to start learning that in the midst of things)..
WriteableBitmapEx is quite fast, even when it just runs on the CPU. It's used in this high perf charting control: http://www.scichart.com
You should also checkout Direct3D indeed. You can get really good performance, but it really depends how it's used and that most draw operations are cached and the CPU-GPU communication is as lets as possible.
In general, I am wondering when to use custom controls vs integrating the control directly into your form.
In particular, I have a form that contains a tab page, with 6 tabs each containing a number of .net framework controls. Currently, I have in my project 6 user defined controls that I dock onto each of those tab pages.
I.e. there is no reuse of controls, I just use them to manage the complexity of a form that would otherwise contain 10 gridviews, 20 buttons, 6 date controls, etcetera. Would you consider this a good way to manage this complexity, or would other alternatives be better (in enabling the programmer to
understand what is going)?
I think this kind of division of page to custom/usercontrols may prove to be useful even without reusing the parts. This gives you:
Encapsulation - you can hide the boring plumbing and fragile internal state from higher level code, leaving you a much cleaner set of controls to work with and more business-oriented code on page level.
Separation of concerns - you can make pieces which are simple, yet logically whole.
Readiness for reuse - may never become useful but it does make you feel more powerful ;)
But be aware that this can backfire if your components are not properly named and grouped, badly designed, you use lots of dynamic loading, do not provide good API or nesting goes too deep. I have seen it happen in a legacy app and it wasn't helpful that way.
If done well, worth it. With inexperienced/sloppy team members, better don't.
What is complexity for you? If you ask me, you are making it more complex if you use usercontrols as the way you use. Usercontrols should be used to prevent code duplication. Basically what you are doing is moving your logic to your usercontrol and deviding your logic into multiple pages so you have less code on your main page. This shouldn't be your main concern if you ask me.
If you have complex logic in a view model or controller for the sections of screen, then this can be a beneficial approach. It is making your overall form more of a composite. You can develop the functionality behind the sections/controls in the view models and/or controllers separately and unit test them separately. As ImreP says, this is along the lines of separation of concerns.
However, if there's a lot of interaction between the separate controls on your form, then this might not be the right way. If you can find separate areas of behaviour/responsibility for different areas of the form, then the split may be a good idea, given your premise that there is quite a lot of UI happening.
If it's simply for the sake of having fewer basic controls in each package, and there's no chance of reuse of any of the components, then it might be muddying the waters somewhat.
A good test might be to show it to someone else on your team and see how long it takes to explain it to them. You'll get a good idea if it's intuitive or not by trying to show it to someone who hasn't come across it yet.
what are the best ways to manage code in a single-form app that has many different components? for example, think of a financial app that has a product picker for browsing/choosing a product to view; a handful of real-time tickers for prices, interest rates, or whatever; a scrolling news feed; various charts; a grid displaying locally calculated values; etc.
would you create a custom control for each distinct component, even if they're not going to be used outside of this app? or could you do it with classes that implement the logic for each component and somehow update that actual control in the gui? two components may need to interact with each other, e.g. you click a cell in a grid, and it brings up some chart (would the main form handle sending the message?)
I have a habit of letting form code get bloated as features are added and I really want to get familiar with a better way. I'm working with c# (not using WPF) but I guess basic design principles aren't necessarily language-specific.
You can try the MVP pattern.
See - Gui Architectures by Martin Fowler
It somewhat depends on how large the application scale is, and also the lifetime of the application.
In nearly any reasonably sized application, I'd recommend separating individual sections into separate UserComponents. That being said, there are many ways to move beyond that, including using plugins/DI, etc.
I'd recommend reading (or at least skimming) the Composite Client Application Guidance for ideas. The message passing questions as well as the questions on different approaches to tie together individual components are discussed in detail.
There are many gems that would be relevant in the Composite Client Appilcation Guidance, even though you're not using WPF or Silverlight. Many of the sections in the guidance are not technology specific - they relate more to how to bring together multiple pieces, promote reusability and flexibility in the design, etc. These apply no matter what technology you are using.
I tend to do everything as a custom control and them use panels for my placement. I then create a new instance of the control and add it to the panel.
This allows for me to do custom constructors, which I have been finding more useful as I am trying to use a DI/IOC framework on my current project.
I've created a workflow/flowchart style designer for something. At the moment it is using relatively simple Bezier curve lines to connect up the various end points of the "blocks" on the workflow.
However I would like something a bit more intuitive for the user. I want the lines to avoid obstacles like other blocks (rectangles) and possibly other lines too.
I prefer the bezier splines rather than polylines because they are prettier and seem to fit in better with the designer in general. But am willing to compromise if they are much harder to accomplish.
I know there is a whole load of science behind this. I've looked into things like Graphviz, Microsoft's GLEE and their commericial AGL (automatic graph layout) library.
GLEE seems to barely be production worthy. And their commercial alternative is, well, a commercial alternative... it's quite expensive.
Graphviz doesn't seem to have been ported to .NET in any way.
I have seen a polyline implementation used by Windows Workflow Foundation for its "freeform designer". And this works, just, but it is not really of production grade appearance.
I'm surprised there isn't some plug'n'play .NET library for this type of thing? Something like:
Point[] RoutePolyline(Point begin, Point end, Rectangle[] rectObstacles, Point[] lineObstacles);
I haven't tried it (although I'm a happy customer of their Gantt product), but ILOG have a similar tool here.
To quote:
The ILOG Diagram for .NET algorithms
share generic goals such as:
Minimizing the number of overlapping
nodes
Minimizing the number of link
crossing
Minimizing the total area
of the drawing
Minimizing the number
of bends (in orthogonal drawings)
Maximizing the smallest angle formed
by consecutive incident links
Maximizing the display of symmetries
Supporting incremental layout,
partial layout, subgraphs,
intergraph links and nested layouts
Perhaps worth a look, at least.
Diagram.NET is a free, open source diagramming library in C#. It hasn't been updated in quite some time, but it's certainly worth a look - there may something there which you can reuse.
http://www.dalssoft.com/diagram/
Are you limited to managed code only?
I did not have this restriction and the past and effectively integrated GraphViz with .Net. What we did was call an external process containing the natively compiled "dot" and parse the result in a .Net object model. It worked perfectly and was fast enough for our needs.
I'm sure you could do better and easier with C++/CLI today.