|
| 1 | +--- |
| 2 | +description: Use a progress bar inside your app notification to convey the status of long-running operations to the user. |
| 3 | +title: App notification progress bar and data binding |
| 4 | +label: App notification progress bar and data binding |
| 5 | +template: detail.hbs |
| 6 | +ms.date: 07/28/2025 |
| 7 | +ms.topic: how-to |
| 8 | +keywords: windows 11, windows app sdk, winappsdk, progress bar, notification, data binding |
| 9 | +ms.localizationpriority: medium |
| 10 | +--- |
| 11 | +# App notification progress bar and data binding |
| 12 | + |
| 13 | +Using a progress bar inside your app notification allows you to convey the status of long-running operations to the user, like downloads, video rendering, exercise goals, and more. |
| 14 | + |
| 15 | +A progress bar inside an app notification can either be "indeterminate" (no specific value, animated dots indicate an operation is occurring) or "determinate" (a specific percent of the bar is filled, like 60%). |
| 16 | + |
| 17 | +The image below shows a determinate progress bar with all of its corresponding properties labeled. |
| 18 | + |
| 19 | +For more information about app notifications, see [App notifications overview](index.md). |
| 20 | + |
| 21 | +<img alt="App notification with progress bar properties labeled" src="images/toast-progressbar-annotated.png" width="626"/> |
| 22 | + |
| 23 | +| Property | Type | Required | Description | |
| 24 | +|---|---|---|---| |
| 25 | +| **Title** | string or [BindableString](notification-schema.md#bindablestring) | false | Gets or sets an optional title string. Supports data binding. | |
| 26 | +| **Value** | double or [AdaptiveProgressBarValue](notification-schema.md#adaptiveprogressbarvalue) or [BindableProgressBarValue](notification-schema.md#bindableprogressbarvalue) | false | Gets or sets the value of the progress bar. Supports data binding. Defaults to 0. Can either be a double between 0.0 and 1.0, `AdaptiveProgressBarValue.Indeterminate`, or `new BindableProgressBarValue("myProgressValue")`. | |
| 27 | +| **ValueStringOverride** | string or [BindableString](notification-schema.md#bindablestring) | false | Gets or sets an optional string to be displayed instead of the default percentage string. If this isn't provided, something like "70%" will be displayed. | |
| 28 | +| **Status** | string or [BindableString](notification-schema.md#bindablestring) | true | Gets or sets a status string (required), which is displayed underneath the progress bar on the left. This string should reflect the status of the operation, like "Downloading..." or "Installing..." | |
| 29 | + |
| 30 | +Use [**AppNotificationBuilder.AddProgressBar**](/windows/windows-app-sdk/api/winrt/microsoft.windows.appnotifications.builder.appnotificationbuilder.addprogressbar) to add a progress bar to your notification. The following example generates the notification shown above. |
| 31 | + |
| 32 | +```csharp |
| 33 | +var builder = new AppNotificationBuilder() |
| 34 | + .AddText("Downloading your weekly playlist...") |
| 35 | + .AddProgressBar(new AppNotificationProgressBar() |
| 36 | + .SetTitle("Weekly playlist") |
| 37 | + .SetValue(0.6) |
| 38 | + .SetValueStringOverride("15/26 songs") |
| 39 | + .SetStatus("Downloading...")); |
| 40 | +``` |
| 41 | + |
| 42 | +To dynamically update the values of the progress bar, use data binding as described in the next section. |
| 43 | + |
| 44 | +## Update a progress bar with data binding |
| 45 | + |
| 46 | +To display a live progress bar, use data binding to update the notification values without re-sending the entire notification. |
| 47 | + |
| 48 | +1. Construct notification content with data-bound fields by calling the `Bind` methods on [**AppNotificationProgressBar**](/windows/windows-app-sdk/api/winrt/microsoft.windows.appnotifications.builder.appnotificationprogressbar). |
| 49 | +2. Assign a **Tag** (and optionally a **Group**) to identify the notification. |
| 50 | +3. Set the initial [**AppNotificationProgressData**](/windows/windows-app-sdk/api/winrt/microsoft.windows.appnotifications.appnotificationprogressdata) values. |
| 51 | +4. Show the notification by calling [**AppNotificationManager.Default.Show**](/windows/windows-app-sdk/api/winrt/microsoft.windows.appnotifications.appnotificationmanager.show). |
| 52 | + |
| 53 | +```csharp |
| 54 | +using Microsoft.Windows.AppNotifications; |
| 55 | +using Microsoft.Windows.AppNotifications.Builder; |
| 56 | + |
| 57 | +string tag = "weekly-playlist"; |
| 58 | +string group = "downloads"; |
| 59 | + |
| 60 | +var builder = new AppNotificationBuilder() |
| 61 | + .AddText("Downloading your weekly playlist...") |
| 62 | + .AddProgressBar(new AppNotificationProgressBar() |
| 63 | + .BindTitle() |
| 64 | + .BindValue() |
| 65 | + .BindValueStringOverride() |
| 66 | + .BindStatus()); |
| 67 | + |
| 68 | +var notification = builder.BuildNotification(); |
| 69 | +notification.Tag = tag; |
| 70 | +notification.Group = group; |
| 71 | + |
| 72 | +notification.Progress = new AppNotificationProgressData(1) |
| 73 | +{ |
| 74 | + Title = "Weekly playlist", |
| 75 | + Value = 0.6, |
| 76 | + ValueStringOverride = "15/26 songs", |
| 77 | + Status = "Downloading..." |
| 78 | +}; |
| 79 | + |
| 80 | +AppNotificationManager.Default.Show(notification); |
| 81 | +``` |
| 82 | + |
| 83 | +Then, update the progress values by calling [**AppNotificationManager.Default.UpdateAsync**](/windows/windows-app-sdk/api/winrt/microsoft.windows.appnotifications.appnotificationmanager.updateasync) with a new [**AppNotificationProgressData**](/windows/windows-app-sdk/api/winrt/microsoft.windows.appnotifications.appnotificationprogressdata) instance. Increment the sequence number so the platform knows this is a newer update. |
| 84 | + |
| 85 | +```csharp |
| 86 | +using Microsoft.Windows.AppNotifications; |
| 87 | + |
| 88 | +string tag = "weekly-playlist"; |
| 89 | +string group = "downloads"; |
| 90 | + |
| 91 | +var data = new AppNotificationProgressData(2) |
| 92 | +{ |
| 93 | + Value = 0.7, |
| 94 | + ValueStringOverride = "18/26 songs" |
| 95 | +}; |
| 96 | + |
| 97 | +await AppNotificationManager.Default.UpdateAsync(data, tag, group); |
| 98 | +``` |
| 99 | + |
| 100 | +Using **UpdateAsync** rather than replacing the entire notification ensures that the notification stays in the same position in Notification Center and doesn't move up or down. The method returns a [**NotificationUpdateResult**](/uwp/api/windows.ui.notifications.notificationupdateresult) that indicates whether the update succeeded or whether the notification couldn't be found (the user may have dismissed it). |
| 101 | + |
| 102 | +## Elements that support data binding |
| 103 | + |
| 104 | +The following elements in app notifications support data binding: |
| 105 | + |
| 106 | +- All properties on **AppNotificationProgressBar** |
| 107 | +- The **Text** property on the top-level text elements |
| 108 | + |
| 109 | +## Update or replace a notification |
| 110 | + |
| 111 | +You can **replace** a notification by sending a new notification with the same **Tag** and **Group**. The following table describes the difference between replacing and updating a notification. |
| 112 | + |
| 113 | +| | Replacing | Updating | |
| 114 | +| -- | -- | -- | |
| 115 | +| **Position in Notification Center** | Moves the notification to the top of Notification Center. | Leaves the notification in place within Notification Center. | |
| 116 | +| **Modifying content** | Can completely change all content and layout of the notification. | Can only change properties that support data binding (progress bar and top-level text). | |
| 117 | +| **Reappearing as popup** | Can reappear as a popup if **SuppressPopup** is `false` (or set to `true` to silently send it to Notification Center). | Won't reappear as a popup; the notification's data is silently updated within Notification Center. | |
| 118 | +| **User dismissed** | Replacement notification is always sent regardless of whether the user dismissed the previous notification. | If the user dismissed the notification, the update will fail. | |
| 119 | + |
| 120 | +In general, **updating** is useful for information that changes frequently and doesn't require the user's immediate attention, such as progress changing from 50% to 65%. |
| 121 | + |
| 122 | +After your sequence of updates has completed (for example, a file has finished downloading), consider **replacing** the notification for the final step because: |
| 123 | + |
| 124 | +- The final notification likely has different layout, such as removal of the progress bar or addition of new buttons. |
| 125 | +- The user may have dismissed the progress notification but still wants to see a popup when the operation completes. |
| 126 | + |
| 127 | +## See also |
| 128 | + |
| 129 | +- [App notifications overview](index.md) |
0 commit comments