Tuesday, 15 November 2011

WPF Troubleshooting

During my time as a consultant I noticed, that there were typical traps in WPF, where developers can loose a lot of time. So I decided to make a hitlist of the most common mistakes and solutions how to resolve them. I hope this helps.

Layout

  • Scrollbar is not active or visible
    • If your control is within a vertical stackpanel, it gives the control infinite height to layout. Consider replacing the stackpanel by a dockpanel.

  • I created a data template and set HorizontalAlignment to Stretch but the item is not stretched
    • Set the HorizontalContentAlignment on the list to Stretch

DataBinding

  • I changed a value, but the binding is not reflecting my changes
    • Check the output window in VisualStudio, if there are any binding errors.
    • Does your data support INotifyPropertyChanged?
    • Just firing a PropertyChanged event without changing the data does not work. Because the binding checks if oldvalue!=newvalue

Performance

  • My list of items takes too long to render
    • Your list is not virtualized. This means, all items will be generated, even if they are not visible. To avoid this check the following points:
      • ScrollViewer.CanContentScrol must be set to False
      • Grouping must be disabled
      • You replaced the ItemsPanel by one that does not support virtualization
    • You are using a too complex data template.

  • Animations cause a high CPU load.
    • WPF cannot use hardware acceleration and does software rendering. This can be because of the following points:
      • You have set AllowTransparency to True on your window.
      • You are using legacy BitmapEffects instead of fast pixel shaders (Effects).
      • Your graphics adapter or driver does not support DirectX

Custom Controls

  • I created a custom control, but the template it not showing
    • Check if you have overriden the metadata of the DefaultStyleKeyProperty and set it to your type.
    • Check if your template is surrounded by a style and both have the right TargetType
    • Check if the resource dictionary that contains the default style is loaded

  • I use {TemplateBinding} in my ControlTemplate, but is not working
    • In most cases you have to replace {TemplateBinding Property} by {Binding Property RelativeSource={RelativeSource TemplatedParent}}
    • You can only use TemplateBinding within the content of your control template. It will not work anywhere else!
    • If you want to access a parent property in the trigger, you have to use a normal binding, with relative source Self.
    • TemplateBinding works only within the VisualTree of the template. You cannot use it on items that are only in the logical tree. Neighter on Freezables or to do two-way binding.

No comments:

Post a Comment