-
Notifications
You must be signed in to change notification settings - Fork 0
Preview Flyout Settings
A widget can offer three surfaces. Only the preview is really essential — a widget with no preview has nothing to put on the taskbar — but most widgets use at least the preview and the flyout.
CreatePreviewContent() returns whatever you want sitting in that little slot on
the taskbar. The catch, and it's the one thing people trip over, is that the
preview is rasterised: the SDK snapshots your XAML into a bitmap and WidBar
paints that. So shapes, text, images, borders, gradients — all fine. Anything
backed by a swap chain — Win2D's CanvasControl, MediaPlayerElement,
SwapChainPanel — comes out blank, because there's no live surface to capture.
If you need that kind of content, put it in the flyout instead.
Design for the size you ask for in PreviewLogicalWidth, and remember it's
re-read after settings change, so a "compact mode" toggle can genuinely shrink
the slot:
public override int PreviewLogicalWidth => _settings.Compact ? 120 : 188;
public override bool IsPreviewVisible => !_settings.HideWhenIdle || _isActive;
public override UIElement? CreatePreviewContent() => _preview = new MyPreview(_settings);WidBar owns the slot itself — placement, sizing, hover, the click that opens the
flyout. You just draw. When your data changes, call
Context.RequestPreviewRefresh(); it's coalesced to around 20 fps, so you don't
need to be precious about how often you call it. And if there's nothing worth
showing, set IsPreviewVisible to false rather than rendering an empty box — the
instance stays alive and configurable, it just disappears from the taskbar until
you flip it back (call RequestPreviewRefresh() after).
CreateFlyoutContent() is the popup that opens when someone clicks the preview.
Return null if your widget doesn't need one. Unlike the preview, this is a real
window with real input, so anything goes here — animations, media, swap chains,
the lot.
Size it with FlyoutWidth/FlyoutHeight and pick a backdrop. The backdrop is
just the window material behind your content; you still bring your own padding
and colours.
public override int FlyoutWidth => 360;
public override int FlyoutHeight => 420;
public override WidgetFlyoutBackdrop FlyoutBackdrop => WidgetFlyoutBackdrop.Acrylic;
public override UIElement? CreateFlyoutContent() => new MyFlyoutView(_settings);The SDK keeps the flyout warm after the first open so it reappears instantly. If
your flyout does ongoing work, implement IWidgetFlyoutLifecycle (see
the plugin contract) and pause it in OnFlyoutHidden.
Implement IConfigurableWidgetPlugin.CreateSettingsContent and WidBar hosts your
UI in a tidy Mica window with Save and Cancel buttons (it localises those labels
for you). The same window opens from the flyout's gear button and from
Configure in WidBar.
public UIElement? CreateSettingsContent(IWidgetSettingsContext ctx)
{
var view = new MySettingsView(MySettings.FromJson(ctx.SettingsJson));
view.Changed += s => ctx.SaveSettings(s.ToJson()); // persisted when the user hits Save
return view;
}The schema is yours; WidBar only ever sees a JSON string and hands it back on the
next init. The nice part is live preview: OnSettingsDraftChanged(json) fires on
every edit, so the taskbar updates as the user drags a slider. It's also called
once with the original JSON if they cancel, which means re-applying it naturally
undoes the draft:
public override void OnSettingsDraftChanged(string json)
{
_settings = MySettings.FromJson(json);
MyPreview.Apply(_preview, _settings);
}Some XAML control libraries need their resource dictionary merged in. Do it in
App.xaml the usual way, or call MergeResourceDictionaryFromFile(relativePath)
from your App to load a loose dictionary shipped alongside the executable.
Building a WidBar widget
- Home
- Getting started
- The plugin contract
- Preview, flyout & settings
- Packaging & publishing
- Debugging
- FAQ