Skip to content

Commit 649b234

Browse files
author
Corvin Szimion
committed
2 parents 550c20d + a8dde55 commit 649b234

File tree

7 files changed

+79
-189
lines changed

7 files changed

+79
-189
lines changed
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
[Home](..\README.md) > Optimizing WPF UI Animation and Rendering Performance
2+
3+
---
4+
5+
# Optimizing WPF UI Animation and Rendering Performance
6+
7+
## Background Information
8+
9+
WPF applications often have complex animations and UI interactions, which can lead to performance bottlenecks if not optimized. Understanding the techniques for efficient rendering and leveraging WPF's internal capabilities can significantly enhance the user experience by making the interface smoother and more responsive.
10+
11+
## Reducing Visual Complexity
12+
13+
One effective approach to improving rendering performance is reducing visual complexity. This involves:
14+
15+
- **Minimizing Visual Layers**: Each layer that a control or element has can add rendering overhead. Consider consolidating overlapping elements.
16+
- **Avoiding Overdraw**: Redundant drawing layers, where multiple visual elements overlap, increase rendering work for the GPU. Arrange visuals to reduce the overdraw effect.
17+
- **Limiting the Use of Effects**: Avoid heavy effects such as `DropShadowEffect` or `BlurEffect` where possible, as these can slow down rendering.
18+
19+
## Using the `RenderOptions` Property
20+
21+
The `RenderOptions` class in WPF provides properties for fine-tuning rendering options. The `BitmapScalingMode` property, for instance, helps adjust the scaling performance of images.
22+
23+
```xaml
24+
<Image Source="sample.png" RenderOptions.BitmapScalingMode="LowQuality" />
25+
```
26+
27+
Setting `BitmapScalingMode` to `LowQuality` helps improve performance when scaling images, especially useful for animations.
28+
29+
> [!TIP]
30+
> Use `HighQuality` scaling mode sparingly, as it increases GPU workload.
31+
32+
## Implementing Virtualization
33+
34+
For controls that display large data sets, such as `ListView` or `DataGrid`, enable virtualization to improve scrolling performance:
35+
36+
```xaml
37+
<ListView VirtualizingStackPanel.IsVirtualizing="True"
38+
VirtualizingStackPanel.VirtualizationMode="Recycling" />
39+
```
40+
41+
Virtualization helps reduce memory usage by creating only the items currently in view, thus speeding up scrolling and rendering.
42+
43+
## Optimize Animation with CompositionTarget
44+
45+
For custom animations, consider leveraging `CompositionTarget.Rendering`, which allows you to hook into the render loop directly:
46+
47+
```csharp
48+
CompositionTarget.Rendering += (s, e) =>
49+
{
50+
// Custom animation logic
51+
};
52+
```
53+
54+
This method provides more control over frame-by-frame updates, but should be used cautiously as it can impact performance if not handled efficiently.
55+
56+
## Example Comparison
57+
58+
| Method | Performance Impact |
59+
| ---------------------------------- | ---------------------------------------------------------------------------------------------------- |
60+
| Reducing Visual Layers | Lowers CPU and GPU workload by limiting the number of visual elements rendered |
61+
| Using `RenderOptions.BitmapScalingMode` | Improves image scaling performance, particularly during animation |
62+
| Enabling Virtualization | Optimizes scrolling in large data sets, leading to faster rendering times |
63+
| `CompositionTarget` for Animations | Provides smoother animations at the expense of higher complexity; best suited for high-priority elements |
64+
65+
## Further Reading
66+
67+
Additional resources for improving WPF performance:
68+
- [Optimizing WPF Application Performance](https://learn.microsoft.com/dotnet/desktop/wpf/advanced/optimizing-wpf-application-performance?view=netdesktop-7.0)
69+
- [Rendering Performance Best Practices](https://learn.microsoft.com/dotnet/desktop/wpf/graphics-multimedia/rendering-performance-best-practices?view=netdesktop-7.0)
70+

src/MainDemo.Wpf/Buttons.xaml.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
using System.Diagnostics;
2-
using MaterialDesignDemo.Domain;
2+
using MaterialDesignDemo.Shared.Domain;
33

44
namespace MaterialDesignDemo;
55

@@ -25,7 +25,7 @@ private void CountingButton_OnClick(object sender, RoutedEventArgs e)
2525
if (CountingBadge.Badge == null || Equals(CountingBadge.Badge, string.Empty))
2626
CountingBadge.Badge = 0;
2727

28-
var next = int.Parse(CountingBadge.Badge.ToString() ?? "0") + 1;
28+
int next = int.Parse(CountingBadge.Badge.ToString() ?? "0") + 1;
2929

3030
CountingBadge.Badge = next < 21 ? (object)next : null;
3131
}

src/MaterialDesign3.Demo.Wpf/Buttons.xaml.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
using System.Diagnostics;
2-
using MaterialDesign3Demo.Domain;
2+
using MaterialDesignDemo.Shared.Domain;
33

44
namespace MaterialDesign3Demo;
55

src/MaterialDesign3.Demo.Wpf/Domain/ButtonsViewModel.cs

Lines changed: 0 additions & 183 deletions
This file was deleted.

src/MaterialDesign3.Demo.Wpf/Domain/DocumentationLink.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ public static DocumentationLink DemoPageLink<TDemoPage>(string? label, string? @
7272

7373
return new DocumentationLink(
7474
DocumentationLinkType.DemoPageSource,
75-
$"{ConfigurationManager.AppSettings["GitHub"]}/blob/master/MaterialDesign3.Demo.Wpf/{(string.IsNullOrWhiteSpace(@namespace) ? "" : "/" + @namespace + "/")}{typeof(TDemoPage).Name}.{ext}",
75+
$"{ConfigurationManager.AppSettings["GitHub"]}/blob/master/src/MaterialDesign3.Demo.Wpf/{(string.IsNullOrWhiteSpace(@namespace) ? "" : "/" + @namespace + "/")}{typeof(TDemoPage).Name}.{ext}",
7676
label ?? typeof(TDemoPage).Name);
7777
}
7878

src/MainDemo.Wpf/Domain/ButtonsViewModel.cs renamed to src/MaterialDesignDemo.Shared/Domain/ButtonsViewModel.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@
22
using System.Windows.Threading;
33
using CommunityToolkit.Mvvm.ComponentModel;
44
using CommunityToolkit.Mvvm.Input;
5-
using MaterialDesignDemo.Shared.Domain;
65

7-
namespace MaterialDesignDemo.Domain;
6+
namespace MaterialDesignDemo.Shared.Domain;
87

98
public sealed partial class ButtonsViewModel : ObservableObject
109
{

src/MaterialDesignDemo.Shared/MaterialDesignDemo.Shared.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
<ImplicitUsings>enable</ImplicitUsings>
77
</PropertyGroup>
88

9+
<ItemGroup>
10+
<PackageReference Include="CommunityToolkit.Mvvm" />
11+
</ItemGroup>
12+
913
<ItemGroup>
1014
<ProjectReference Include="..\MaterialDesignColors.Wpf\MaterialDesignColors.Wpf.csproj" />
1115
<ProjectReference Include="..\MaterialDesignThemes.Wpf\MaterialDesignThemes.Wpf.csproj" />

0 commit comments

Comments
 (0)