I am using Avalonia UI to develop a rather large single-window application using a Carousel control to switch between pages. As to be expected my MainWindow.xaml file is getting pretty large. It's currently at about 600 lines of code with only a fraction of the UI finished and I figured it's time to refactor. I have already used UserControls where ever redundant code was present.
So I was wondering: What would be the best way to shrink the size of my main window xaml file?
As I am using the MVVM version of Avalonia (I think there is another project template, correct me if I am wrong) I also have to worry about how to deal with all the bindings to my MainWindowViewModel.cs (which I cleaned up by making the class partial and splitting it into several files, each holding the code for one of my Carousel tabs).
My current plan is to outsource every Carousel page into a separate UserControl and then somehow pass references to the parent Carousel via bindings and Avalonia properties to be able to switch between pages from my backend and hopefully find a way to do this while complying to the principles of MVVM and without messing up all the bindings.
I am sure this will create new problems on it's own though and would be rather painful to rewrite so I figured I am probably not the first person to use Avalonia in a somewhat big project. So is there a better alternative to my approach?
I heard of StyleInclude but was unable to find comprehensive documentation of what it does, how it works and when it should be used.
Related
I have started using WPF and started with some games and visual apps.
In my first App I started a blank project then made a class that inherited from a window which had a canvas that I added and removed images from Dynamically, like follows:
class MainWindow : Window
{
public Canvas canvas=new Canvas();
public MainWindow()
{
this.addChild(canvas);
}
//add an image every second move it and remove it
}
This would be impossible with static XML but someone told me it is a bad idea to do controls dynamically, is it true?
Is it a performance loss?
And is there a simple and efficient method to draw, lets say, 100 images at a 30 fps without lag?
There is no performance loss / the performance loss is negligible compared to the HUGE productivity / code cleanliness gained by doing things the RIGHT way.
And XAML is not static.
There is DataBinding, and if you need to add / remove items dynamically there is the ItemsControl.
There is also the concept of DataTemplates that dynamically render specific UI depending on what Model / ViewModel objects are passed to it.
Do not manipulate nor create UI elements in procedural code. WPF is not winforms.
None of the controls are reallystatic. There is no any runtime difference.
Most likely, by using XML you meant XAML. XAML merely serves as a data source use to actually generate C# code (or the code in VB.NET or other .NET language) to compile is and to use exactly in the same was as you would do it programmatically.
You can use this fact in your work. If you know how to do certain things with XAML but don't know how to do similar thing in C# code, do the following: develop XAML-based project and build it. Then perform the search for *.cs files under the directory where your project file is located. You will find some *.cs files which was not in your source code. Those files were auto-generated with the use of XAML. Look at them.
You will be able to learn how it works behind the hood.
Good luck,
As part of a school project, a group and I will develop a Windows application using C#.
We are not very experienced in C# but has some basic understanding for it. We do however have experience from other languages and platforms.
We would like to build an application in which the layout is split into two primary parts: the menu, which will reside to the left and the content which will be to the right.
The menu will be more or less static and when an entry in the menu is chosen, the content will be changed.
We have not been able to figure out the best way for achieving this nor have we been able to find good material on this. The idea is to have one window and add a view (as far as I can understand, this should be a UserControl?) to this window. This control will be the menu.
Now, our question is if anyone can point us in the right direction to achieve the navigation in the program. Say, when a menu entry is clicked, how will we change the content of the window and how will we manage which view is active? I suppose that every view (in the "content area") will have a controller.
We are interested in the "best practices" for this when using WinForms and the MVC pattern.
We hope that someone can help us further in this project.
If I were you I would seriously consider using WPF instead of winforms.
It, and the use of the MVVM pattern, allows you to do some pretty impressive stuff with far less code than if you are using winforms. If you don't already know winforms then it might also be a slightly less steep learning curve as WPF is a better thought out framework (at least in my opinion).
If you go the WPF route spend some time getting to understand how bindings work and how to bind your ViewModel to the UI. Once you have a good understanding of proper UI separation you are able to do far more than you could with the old WinForms framework.
I found this link quite useful when I first started looking at WPF. Especially the RelayCommand.
If you are using Winforms the options that you have got is:
-dynamically clearing forms and generating content on menu navigation
-using mdi container form, which can be parent to a number of child forms
If you are using for WPF you could use Pages in a Frame control loaded based on used menu selection. You could also use MVVM pattern to build your app.
I want to use same xaml files for silverlight and wpf version of applications.
Only difference that i need is in styling. I have used styles in xaml. But for silverlight i dont want to use any styling in my xaml files, as styling is defined a application level in the form of themes.
Is there any other way to use same xaml file for silvelight and wpf versions? Otherwise I am forced to maintain separate xaml files.
you can reuse quite a bit of xaml for both, I have projects where I'm linking all the same files, xaml and code behind and it works decently.
A couple of things to be weary of is certain things don't always match up well, for example wpf has a template selector for a itemscontrol and silverlight doesn't.
Using SizeToContent tends to produce different behaviours in the two, I recommend avoiding it, I don't think it buys you anything.
I recommend having a seperate 'base' resource where you can keep your difference in the two files. things like event triggers for example aren't nearly as filled out in silverlight. you would have a base class for each version and they would abstract their differences, you could then mark the keys the same and use them as a static resource in your linked files.
Another big gotcha is you want to watch out for the order events happen for uielements, loaded,layout and apply template events get applied in different orders so if you were to make a templated control you have to be careful there, its not a deal breaker you can work around it, just be aware.
other things to be aware of
-silverlight commands take a little more effort, you have to implement ICommand, this isn't always the case in wpf, I use my implementation to help with sharing the code though.
-wpf is the superset, it has a lot of functions that silverlight doesn't have, Usually they are convienient ways of doing things, you just want to avoid those. Good Examples would be Preview events, not there for silverlight but you can usually find an event to match the behaviour.
I have a WPF application, and it's slow.
It is NOT the rendering. Firstly, the rendering is quite simple, and secondly, I looked at it with WPF Performance Toolkit - nothing.
It is NOT in my own code. Firstly, the unit tests work fast, and secondly, if I replace all DataTemplates with blank ones, everything works fast.
So far, it looks like the slow part is template instantiation. That is, when you start the application, and open some complicated screen, it takes a lot of time. And by "a lot" I mean "a lot". Sometimes can be as much as 3-5 seconds - for example, when there's a datagrid with 100 rows. But when you go to another tab, and then go back to that same screen, it opens fast (as long as its viewmodel stays put).
This is very annoying not just because it's slow, but because I can't do anything about it. If I had some control over the slowness, I could, maybe, display some "opening, please wait" message or something...
Besides, when I look at some other WPF applications (most notably, ILSpy), they seem to work reasonably fast, despite the large amounts of data. This makes me believe that I'm probably doing something wrong. But I have no idea where to start.
Any ideas? Any classic mistakes? Any tips?
My exerience comes from working on the WPF mind mapping application NovaMind
A couple of months ago we completely rewrote our intermediate layer to solve the performance issues we had experienced. In a nutshell, creating our user controls seemed to be way to slow. Unfortunately I couldn't find a great way to profile the performance as neither the WPF Performance Suite nor commercial applications such as ANTS Profiler give you any detailed information on this part of the WPF process. (I asked this question back then)
We resorted to manually test our application by trial and error and removed parts of our user controls to see what exactly is the culprit.
In the end we solved the performance issues by completely rewriting our controls. We also cut down on the complexity of our visual tree dramatically. Before the rewrite, one of our most used user controls, when inspected with Snoop, consisted out of 61 different things, now there are only 3. Wherever possible we only added things to the visual tree on demand. (As you know in XAML even when you set things to Collapsed, they need to be created first).
Finally we were forced to write our own rich text rendering control as the built in RichtextBox is ridiculously slow and the visual tree of the RichtextBox is quite complex.
I don't know if this will apply to your situation but I would recommend that you investigate your user controls and see if they are complex. Maybe you have things that you could trim.
Low hanging fruits would be parts that are only rarely visible or can be created in a lazy manner. You could create these parts from code behind when necessary rather than having them in XAML. This should help you a lot.
Otherwise virtualization is your friend, if possible. In our case we couldn't do that unfortunately.
This sounds similar to a problem i was having. I posted the fix here: WPF UI Automation issue . Just posting for the benefit of searchers, as it took ages to resolve.
Following comment on link only answer, here is the crux of that post:
I did the following:
Downloaded Hotfix - - http://archive.msdn.microsoft.com/KB978520 (may not be required)
Downloaded Hotfix - - http://archive.msdn.microsoft.com/KB2484841 (definitely required even if you have Windows 7 / .NET 4)
Improved the code further (the validation was causing an excess of objects) - Why does WPF Style to show validation errors in ToolTip work for a TextBox but fails for a ComboBox?
It may be that only Number 3 was required, but it worked. Just posting here so people dont lose the days I lost in memory profilers etc.
User Control in your data template, is not completely bad idea but if you crave for performance then you should consider switching to lighter control. For example, having a UserControl just hosting a TextBox is very bad idea, as UserControl is made up of ContentControl, ContentControl hosts ContentPresenter and ContentPresenter will host TextBox so if you notice your Visual Tree, it has three new layer of UI Elements. Reducing Visual Tree will certainly improve the performance.
Most likely, I would suggest creating Custom Controls that may be a completely a new control having few dependency properties that can relate to data you want to present and you can have its own custom template in generic.xaml. Second, you can just simply derive a control from existing controls and redefine its default template in generic.xaml.
This approach will certainly work better as you will be reducing your Visual Tree, thus reducing Visual State Manager's job.
Changing theme or template will be slower then changing the element that hosts content. And let the element have the default template in its own generic resource dictionary.
Try moving all the resources up as
far as they'll go, preferably into
app.xaml
Check if you could use StaticResource
instead of dynamic ones, static ones
are alot faster
If possible, try using depedency
properties in your VMs, especially if
you have alot of them at once or if
they have alot of properties. That will keep wpf from having to do a bunch of reflection.
You mention you are using a DataGrid with, say, 100 rows. A likely culprit of your perf problems is that whatever datagrid you are using isn't doing virtualization, and so your visual tree is gigantic.
Normally, long startup time in WPF screens points to a large visual tree.
I'm not sure if you're using a datatemplate per row, or some 3rd party grid that binds columns, or what - but lets say you have 8 columns with controls. Depending on your grid/validation/etc, this could be a visual tree of 20-60 items per row. If you have a combobox, then each item in the dropdown may be created per row as well.
To fix this just takes watching the details, and taking measures as you go:
Use a virtualizing control as much as possible. This means using a virtualizingstackpanel inside list controls, and making sure your 3rd party controls do as well (many stock WPF controls do now by default)
Do not overuse UserControls, composite controls, etc. Adding depth adds time, and putting in extra visual tree depth in a datatemplate or other repeated area adds up fast.
If all else fails, show a simple screen and add controls through code to improve perceived performance
I hope I am able to illustrate the problem using a lot of images. First of all, I was no real fan of XAML (Silverlight issues, crashes in Preview, and so on...)
Now, with VS2010 the situation has become better. There are still a lot of things I like better in code, but I also want a preview in my VS.
So, take a look at the following control: It is really simple, a todo details list. The first screenshot shows the code of the control, pretty straighforward:
CodebasedControl http://img28.imageshack.us/img28/2263/invoicea49.png
There is no XAML, so obviously no preview. Of course, I could encapsulate it in another control, like shown in the next screenshot:
CodebasedControl http://img11.imageshack.us/img11/9515/invoicea48.png
But, in that case I have an additional file I do not want or need.
So I had the idea to move the init stuff inside the contructor of a XAML control. For simplicity, I used simple elements. But they do not show up in the preview...
CodebasedControl http://img99.imageshack.us/img99/5547/invoicea47.png
CodebasedControl http://img512.imageshack.us/img512/9625/invoicea46.png
Finally, I know I could use the controls in other parts of my app when creating UIs. But I am using layout manager, PRISM and a lot of other stuff, so I just want an easy preview of some specific control I created (without having to have a XAML wrapper file for each control)
Thanks for help, and sorry for the post structure, but I though with images it is better to understand...
Chris
Ok,
I found a way. Basically I am tricking VS by changing the XAML, but keeping the code-behind linked to the file. It the same like the wrapper solution, but without having a dedicated extra class or file. I am using the "xaml-infront" file for preview.
This solution only works with pure code controls, I have to do more research for mixed controls (at least I think so.. but it is enough for me for now).
Please be aware, the code behind is NOT partial anymore. It could be placed anywhere else, what I am doing here is basically only related to file-names and visual studio "readability"..
See screenshots for explanation:
alt text http://img15.imageshack.us/img15/5456/invoicea50.png
Some space for easier reading
alt text http://img186.imageshack.us/img186/1545/invoicea51.png