Related
I have a complex control that is taking a very long to Initialize. Whilst I am able to use the WPF performance kit to profile the controls Layout time, I haven't found a way to analyze initialization time.
Im wondering if there is any way I can analyze where the hot spot is in initializing the controls hierarchy, styles, resources etc.
I don't know any tool which will allow debugging or profiling the Initialization process.
you can use snoop to see the visual tree.
you can use pistachio to profile unused resources.
eventually you'll have to remove all UI elements from the control and start adding them one by one while counting the initialization time that way you'll be able to figure out the hot spot.
of course you have to take in account the binding in the specific use case which result in the performance hit
When I first learned about Microsoft's then-new framework for developing desktop applications, WPF, I thought that one of the biggest benefits of it would be its efficiency. After all, I already know what the GUI controls and elements were that I wanted to use--I just have to slap them all on the page and then wire up all my bindings right, and I'll be done. After that, I learned about the MVVM pattern, which promised clean separation of concern within my WPF app.
I thought this was going to be great! I got into creating several different admin and data entry WPF apps with my team at work, and thus I began to crank out working software with robust but simple GUIs, right?
Not so fast, there, cowboy coder. My experience is that writing WPF is S-L-O-W.
Well, at least the way I do it. You see, after I have a picture of my GUI on a whiteboard, I code up the XAML with the controls that I want. This part, as expected, is fast--laying out the whole of a window is pretty quick. After that, its all the little stuff you want these elements to do takes awhile. I always seem to want to make this text bold in some cases; show a red error box in these other cases.
Then things unravel: this binding isn't working right over here--I have to write a converter and adjust the layout for the right values. Whoops, I forgot that extra NotifyPropertyChanged there. Oh, and I want to use a different template in this state vs. that, so I have to figure out what I can use to swap the templates in certain situation. This data is coming in asynchronously, so I need to make sure the right thing is happening on the right thread and that Property gets NotifyChanged as well. Crap, when I maximize my window, it doesn't stretch like I thought it would--must be because its container height isn't defined, but I don't want to define that, so I have to make it stretch in its parent. Oh, now I really want to make a user control out of this stuff over here, so I better implement some dependency properties...
On and on I go, spending hours and days on stuff that just feels so small and minor. I soon resort to cutting usability features and look-and-feel enhancements because this is taking just too darn long.
Does anyone have any tips or principles I need to try in order to write WPF efficiently?
A couple of things that have saved a lot of time for me:
Use DockPanel as your default panel for layout unless you have a good reason not to.
Keep a folder full of useful classes: a ViewModelBase class that implements INotifyPropertyChanged, a RelayCommand class, etc. There's no need to get fancy and try to make this a separate assembly that you build into your project; just write reasonably good implementations and copy/paste them into your new projects.
Get Resharper and use it. Use templates for creating dependency properties, properties that do change notification, and commands.
Find or build a good library for asynchronous task management.
I find that even for very simple applications I get more done faster with WPF than I did with Windows Forms. For applications that aren't very simple, there's absolutely no comparison.
For the most part, WPF applications are a lot of work to develop because it's harder to make the case for cutting out UI features. You can't just say, "Oh, that's not possible," because it probably is possible (whatever "it" is).
Write your own library, or find an existing one.
WPF is great, but out of the box it is missing some things that would make coding faster. I got tired of writing the same things repeatedly, so I ended up creating my own library full of things like converters, visual tree helpers, attached properties, custom controls, etc., and since then, my development time has sped up considerably.
In addition to my own library, I've also started using Microsoft's Prism and Galasoft's MVVM Light Toolkit. Both contain useful objects that I use all the time and are better than what I could code on my own. (Most used are NotificationObject from Prism, RelayCommand from MVVM Light Toolkit, and EventAggregator or Messenger from either one depending on the project, etc.)
Another thing I've done to speed up coding time is to take advantage of Visual Studio's macros. For example, to create a property with Change notification, I write the private property, hit Ctrl+E, Ctrl+R which generates the public version, then run a macro which automatically sets up the PropertyChanged notification in the setter method.
I almost never change the setter methods from the default macro'd one, and instead use the PropertyChanged event to handle any changes that should occur on the setter. This not only makes it easier to track application flow, but also greatly reduces the time I used to waste browsing through my public properties to alter a setter method.
I believe the right answer isn't for WPF at all, but it can fit what you're looking for.
Most of the times, when you want to leverage a new technology there's a time while you're not efficient, productive and your solutions aren't that impressive, innovative or just doesn't look like others.
What will give you more efficiency is working with WPF itself.
It's more about project management topics than programming. After finishing some project, your team and you should go to some room and discuss:
Success stories.
Problems during development.
Pros and cons.
Fails in the application architecture.
Communication problems within the team and customer.
... and so on.
If everyone shares their knowledge, project manager or team leader does a good job documenting each project story, finally everyone will have a "know-how".
In addition, it's important that you won't need to reinvent the wheel for every new project: if some pattern worked fine, do the same way next time, even if it's not the best way of doing it. And try to enhance it, if possible.
Design patterns, technologies, paradigms, languages, companies, colleagues and nothing are a silver bullet: Microsoft said WPF is a step-forward in Windows client developments, and it is that: a more modern approach to provide shinny user interfaces and a programming paradigm that fits nowadays' desired approaches, easing the relation between coders and designers, as WPF has XAML, which allows not only separation of concerns, but separation of professionals by area (designers, UI programmers, business programmers, ...).
Finally, as I said above, WPF won't be your silver bullet: learn from your own success and read a lot, see sample applications, download open source solutions, listen your colleagues, drink a coffee and, after all, after some headaches, some day in the near future, you'll leverage these technologies (and many others).
EDIT
I'd like to add that a good way of using the know-how is creating a Visual Studio guidance pack, so you can automate a lot of tasks like creating managers, views, models and other things just in the way your team would do by hand.
For example, you can create a guidance pack for a WPF CRM-like application and you can automate module creation. When you want to add a new module, guidance pack starts a process which adds all the necessary classes to start development this new module, and it can create a sample form already associated with a navigation manager, controller or whatever (it's just an example).
Guidance pack and T4 would be both good tools for automating tedious or repetitive tasks in everyday's tasks:
http://msdn.microsoft.com/en-us/library/ff631854.aspx
http://msdn.microsoft.com/en-us/library/bb126445.aspx
I have been using WPF since 2008 and can honestly say to do it right and clean does take more time than the same thing in WinForms would take to develop. I have written a lot more WPF than Winforms. That being said - if I need a simple internal utility - it is ALWAYS Winforms. If I have something forward facing to a client - it is always WPF. Why? Winforms are cheap and dirty and you get a lot for free. What you don't get is the fit and polish that WPF can provide. The flexibility with WPF does come at a cost - but in the longer run it's worth it for public facing software.
Yes WPF is a hurdle but it also has rewards. You are on the right track with a design pattern such as MVVM. Sounds like you have not even gotten to the "rewards" of dependency properties or event bubbling. But the control over the UI is great. Almost everything is a content control. In forms I was always writing custom controls to get the UI I wanted. In WFP I have never had to write a custom control for UI and doubt I ever will. The syntax is new but it is compact - I rewrote a Form app in WPF and the WPF has 1/3 the lines and more features. Read a whole book on WPF just to get grounded - I like PRO WPF in C# 2010. You could also say LINQ is complex but man does it do a lot in just a few key strokes. WPF is not something you just pick up on the fly as you next application.
I'm very much new to Test Automation kind of thing. Recently I've been assigned to a project where I have to write an application (or, a script may be, I'm not sure) that will automate the UI testing of a CAD-like WPF application which misses lots of AutomationIds.
After doing a little searching on MSDN and other sources I'm a bit confused about whether I should use the Microsoft UI Automation Library or the new Coded UI Test feature included in VS2010. I'm not getting the clear picture of which one of these two applies in which scenarios, what advantages one has over the other and which one suits my purpose.
Please shade some light if you have experience/knowledge on the matter. Thanks in advance.
Basically Microsoft UIA is the new accesibility library in .Net 4.0. WPF applications and controls have built-in support for UIA through the AutomationPeer class.
Coded-UI test is a Record & Play automation tool which uses the Microsoft UIA Library underneath. Since being a tool compared to writing code in C# it improves QA productivity for recording more test cases.
For applications with automation support planned into it, Coded-Ui should be sufficient. If the AutomationIDs are missing make sure the controls have some unique property like Name. Use UIVerify or Inspect to check for this.
If NO unique property is avialble, there are the other below mentioned techniques you can use in combination with Coded-UI.
From an Event
When your application receives a UI Automation event, the source object passed to your event handler is an AutomationElement. For example, if you have subscribed to focus-changed events, the source passed to your AutomationFocusChangedEventHandler is the element that received the focus. For more information, see Subscribe to UI Automation Events.
From a Point:
If you have screen coordinates (for example, a cursor position), you can retrieve an AutomationElement by using the static FromPoint method.
From a Window Handle:
To retrieve an AutomationElement from an HWND, use the static FromHandle method.
From the Focused Control:
You can retrieve an AutomationElement that represents the focused control from the static FocusedElement property.
If you can leverage and use the Coded UI Test then go that route. Make sure to verify that your given configuration is supported.
The UI Automation Library resolves everything in the code behind. This then forces you to use a tool like UISpy to gain access to the controls internals so that you can then build out your test.
A Coded UI Test on the other hand still has code behind however it allows for the recording of steps through the given application which you are testing which will greatly increase the number of tests you can create.
UI Automation library is a low-level library. Usually, you don't want to write tests against it directly as it requires a pretty decent amount of work.
I would recommend looking at more high-level libraries. You mentioned one of them - Coded UI; another good choice would be White from TestStack. They both suits different kinds of projects. Coded UI is good when you don't want to invest a lot of efforts into your test suite. At the same time, it doesn't scale much so if you are going to write a lot of tests, you are better of choosing White.
Here I compare the two frameworks in more detail: Coded UI vs White
To complement the above responses, please look at CUITE that helps quite a bit and may be an appropriate approach for you.
I began 'rolling-my-own' 'semi-framework' using the CodedUITest library and devised a paradigm for separating the details of automation from the (C#) code.
Basically, I am creating a driver that reads what needs to be done from spreadsheet(s) where each line in it is a test step (or a pointer to a scenario in a different worksheet).
At present, incomplete, but promising, I have it working against a WPF application with partial success.
One of the main problems is that the developers neglected to identify controls uniquely and consistently.
Bey
When hosting WPF user controls within a WinForms MDI app there is a drawing issue when you have multiple forms that overlap each other that causes very distinct visual artifacts. These artifacts are mostly visible after dragging one child form over another one that also hosts WPF content or by allowing the edges of the child form to be clipped by the main MDI parent when dragging it around. After the drag and drop of the child form is completed the artifacts stay around generally but I've found that setting focus to a different application's window and then refocusing back on to my application window that it is redrawn and all is good again until the child forms are moved once again. Please see the image below which demonstrates the problem.
Those at Microsoft insist that the WinForms MDI is already a sufficient solution for MDI and doesn't need reinventing in WPF although I find it hard to believe they tried creating a WPF app this way because of the obvious shortcomings.
UPDATE: A few extra notes that I left out is that if I create these Forms without setting the MdiParent they are created as regular forms and this issue doesn't happen. This issue seems unique to the WinForms MDI scenario. Also I've currently running on Windows 7 Enterprise and I'm aware the results may be quite different on Windows XP but I haven't been able to test this.
UPDATE: I've found a few other related resources on this issue that I thought I should share.
elementHost repaint problem in MDI
application
elementHost repaint problem in MDI application on Tech Archive
It appears that another workaround is to revert to software rendering as opposed to taking advantage of hardware acceleration. This was the suggestion by Marco Zhou on the MSDN Forums.
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
this.Loaded += delegate
{
var source = PresentationSource.FromVisual(this);
var hwndTarget = source.CompositionTarget as HwndTarget;
if (hwndTarget != null)
{
hwndTarget.RenderMode = RenderMode.SoftwareOnly;
}
};
}
}
I've tested this and this solution seems to work very well and so far is the only solution that I've found for solving this problem within a FoxPro interop scenario which is very similar to the WinForms one I posted about originally. For now I'm planning to use my original Refresh on the MDI Parent solution for my WinForms project but then for my other native interop applications such as when my WPF controls are hosted in Visual FoxPro I'll use this solution. That is unless of course if a more elegant solution is discovered for either of the cases.
Also it's important to note that from what I'm aware software rendering is the only option on XP systems and normally Visual FoxPro nore WinForms normally take advantage of the same type of hardware acceleration that native WPF apps do on Vista OS and up. So using this option may not be as bad as it sounds when you do have to deal with interop. Currently I'm not aware of any related side effects when using this solution but if there are any those would have to be taken into serious consideration.
Well, I may have found a solution although it feels like a bit of a hack. It appears that if you call the Refresh method on the MDI parent whenver a child MDI Form is moved that the noted artifacts go away. Visually things appear a bit jittery when dragging a window but it seems much more acceptable than the example I showed in my original post.
private void Form1_Move(object sender, EventArgs e)
{
this.ParentForm.Refresh();
System.Diagnostics.Debug.WriteLine(string.Format("Form Moved to: ({0},{1})", this.Left, this.Top));
}
I've tried many combinations in the same vein such as refreshing just the child window that was being moved by calling methods such as Update(), Invalidate(), Refresh() and also I've tried these same methods on the MDI parent as well as Dispatcher.Invoke(DispatcherPriority.Render, ...) and InvalidateVisual() on my hosted WPF control but none of those other methods worked accept for calling Refresh() specifically on the MDI parent.
I realize that this probably isn't the optimal solution since I'm forcing the whole main application window to refresh every time a child window moves a few pixels but as for right now it's the only reasonable solution that I found that works. If anybody else has any alternative solutions or any improvements upon this I will gladly accept your answer instead.
Check video drivers and try disabling hardware acceleration. Most artifacts are caused by bad drivers, failing video card, or insufficient time to complete the refresh.
First troubleshooting step: Update video drivers. Obvious, I know.
I had similar issue, checking my video card settings (NVidia Control Panel) showed global setting set very high causing a longer refresh interval which may be aborted if taking too long. Setting my settings back to defaults resolved most of the issue. But I also run hashing programs which use the GPU intensely so this is likely the cause of my remaing artifact issue which is very seldom now and mostly shows its ugly face in Visual Studio.
Another troubleshooting step I ran across is to disable hardware acceleration for WPF, this can be done in 'HKEY_CURRENT_USER/SOFTWARE/Microsoft/Avalon.Graphics', or maybe an application can do it BUT this is only for troubleshooting; never set these within an application because it will disable for ALL WPF applications. I do not have this registry setting nor did I add it so I am not sure of the success with it, but many say this resolved their issue. Also note some applications have this option available, try disabling it if available.
Another troubleshooting step is to make sure the video card is a proper tier level for rendering. Any card that supports DX9 or greater should be sufficient, but other factors are involved (as is my case) so just because it is on the list does not mean it is adequate for your purpose.
Finally, you can use the Visual Profiler (part of Windows SDK), and other tools, to help determine what is going on more precisely with WPF lacking performance in relation to graphics ability.
Rendering Tier level notes and WPF Performance information --> http://msdn.microsoft.com/en-us/library/vstudio/ms742196(v=vs.90).aspx
Hope this helps someone.
--Ryan Strassburg
Your usercontrol or window loaded event ;
this.WindowState = System.Windows.WindowState.Minimized;
this.WindowState = System.Windows.WindowState.Normal;
it may seem bad solution. no need to hit your head against the wall.
A Turkish proverb says: the best code is the code is running :)
I also have a desktop application written in Windows Forms that is a middling size (a couple dozen major forms backed by 46 tables in the database). I'm thinking about rewriting the UI in WPF, but before I go there I was curious if there were any war stories about doing such a conversion.
I use LLBLGen to generate my low level data access objects, and I have a business logic layer above that. The forms are databound to the business logic objects, although the main form uses caching objects to minimize round trips on the more common navigation routes. The UI never speaks directly to the database: always through the UI -> business logic -> low level -> datastore path.
One control that I use heavily is the TreeView, which acts as a visual guide and short range navigation tool. The tree has been heavily customized with icons, highlight colors and it is the control I worry most about porting.
Is there a story that might convince me to go ahead and convert (or conversely, wait until Microsoft is closer to pulling the rug out from under Windows Forms)?
EDIT: I was asked in a comment what motivation for conversion I have. I have some concern about future proofing: I have 500,000 lines of code that were originally ASP and VBScript. We have been porting the functionality over time to ASP.NET and C#, but only as we make changes to the code. The upside is we have kept costs minimized, the downside is half the code remains ASP and VBScript. I'm concerned about a similar situation arising with Windows Forms applications.
Am I worried today about Windows Forms going away? Not even close to it... but the application is moving from ASP and VBScript to ASP.NET and C#, has nine years of history behind it, and probably won't be replaced this decade (instead, simply it will evolve). The desktop application is likewise a long term project with years of history.
For me, the WinForms vs. WPF decision is a simple one - if normal people are going to use it, the user interface can make the difference between a winner and a loser.
It is definitely a steep learning curve. But I have NEVER gotten done with a nice looking WPF application and said "Man, I should have used WinForms".
I'd say invest in the effort to make your UI better whenever possible for your customers, so yes to WPF if that's the case.
WPF has a ridiculously large learning curve. It will most likely require you to rewrite a lot more than you think for just changing the UI. Also, a lot of features that would make WPF nicer to use just aren't implemented or included in WPF yet. Unlike routeNpingme, I have written nice looking WPF applications and have said, "What a waste of time, I should have used Windows Forms and completed in 70% less time".
EDIT:
Also, unless Microsoft figures out a way to make WPF easier to learn, I don't see it catching on to the masses at all. WPF can do some very cool things, but a little effort to make it easy to understand instead of throwing stuff over the wall would have gone a long way. It would not surprise me in the slightest to see Microsoft drop WPF for something easier to work with in the not too distant future. So don't go changing your Windows Forms application just for the sake of changing it.
Pros:
Ridiculously easy data-binding (most of the time)
Ridiculously easy customization of look and feel
Cons:
Very steep learning curve
Some obvious bugs or issues. Similar to .NET 1.0 Windows Forms
Little or no tool support
In my opinion, WPF will definitely replace Windows Forms at some point. However, right now the tools are the main thing keeping it back. I disagree with Dunk that Microsoft will drop it for something else. Change it yes, but I think it's here to stay.
Should you change your application to use WPF now? No. Feel free to learn WPF but if your application works fine currently, then WPF won't give you anything extra. It just makes doing what is possible in Windows Forms much easier.
WPF is great. It is particularly good for extending controls like TreeView with customisations. You can add a string as an item in a TreeControl. You can also add a small panel containing an image and some text in various fonts and colours. Or you can add buttons, or anything you like. It has a completely general composability system. Same goes for ListBox, ComboBox, Button, etc. All their content or child items can be as simple as a string or as complex as a multipage document viewer with zoom buttons (if you want).
But the only way to find out is to try porting one of your forms. It shouldn't be too hard to make a WPF Window open from within your existing app. I started using WPF by making new GUI panels that were hosted inside a C++ Win32 application. Eventually it was so obvious that WPF was the way to go that we switched it around and made the outer shell WPF, with some ancient dialog boxes still implemented by the old C++ code where we couldn't be bothered to rewrite them (probably exactly what will happen with Visual Studio 2010).
Porting is a tough decision. So just some thoughts to help you decide.
WinForms is OK while you work by the rules and keep everything drawn as is. But even redrawing a border on some controls may require complex and precise work and skill, as you already know from tree customization. The same tasks can be done in a very elegant way in WPF.
Also, the data-binding in WPF saves me a lot of time. In the long term, you end up thinking about data-binding scenarios that could not be remotely possible in WinForms without special-case coding.
I do not even consider WinForms for new development -- there is no excuse for customization costs.
I have started introducing WPF elements within my WinForms application and so far have had a lot of success.
The application's main component is a grid control and I haven't yet found the text rendering of WPF sharp enough to present a table of important textual data.
But the application has several additional panels, and the majority of these are implemented using WPF. So, I'm going for a hybrid of WinForms and WPF via the ElementHost control.
I have found the flexibility of WPF to allow for a much more attractive and usable UI, and my users seem very happy with it. In my case, it's also been politically easier to introduce WPF one panel at a time.
WPF's main value to me is in the binding, not in the cooler UI. The worst WPF I've ever seen is when people use WPF just because it's newer, and put all the work in the code-behind, including not using binding. What you get is WinForms data management. So be sure you're going to use the wonderful binding when you do WPF.
I would port the OP's business logic to a business layer for ease of maintenance and conversion. I wouldn't port the WinForms to Xaml at all unless new Xaml functionality was needed, and preferably not until after the functionality was ported.