dotnet / dotnet/maui

[BlazorWebView][WPF] Support XAML data binding on RootComponent.Selector/ComponentType/Parameters

Open
#34,941 0 comments 0 reactions 0 assignees View on GitHub
proposal/open
Dominant language
C#
Stars
23.3k
Forks
2k
Avg merge
1d 14h
Merged PRs (30d)
296

Description

### Description

We can do xaml binding for `BlazorWebView` and it's shown in the current examples:
https://github.com/dotnet/maui/blob/ec43ab03f66bb10e03013ca10f9fdb79bc252ed3/src/BlazorWebView/samples/BlazorWpfApp/MainWindow.xaml#L19
and in docs: https://learn.microsoft.com/en-us/aspnet/core/blazor/hybrid/tutorials/wpf?view=aspnetcore-10.0

However you can't do the same with `RootComponent`, aka you can't do:
```xml
System.Collections.IEnumerator!
+static readonly Microsoft.AspNetCore.Components.WebView.Wpf.RootComponent.ComponentTypeProperty -> System.Windows.DependencyProperty!
+static readonly Microsoft.AspNetCore.Components.WebView.Wpf.RootComponent.ParametersProperty -> System.Windows.DependencyProperty!
+static readonly Microsoft.AspNetCore.Components.WebView.Wpf.RootComponent.SelectorProperty -> System.Windows.DependencyProperty!
```

```C#
public class BlazorWebView : Control, IAsyncDisposable
{
///
protected override IEnumerator LogicalChildren
{
get
{
foreach (var rootComponent in RootComponents)
{
yield return rootComponent;
}
}
}
}
```

```C#
public class RootComponent : FrameworkElement
{
public static readonly DependencyProperty SelectorProperty = DependencyProperty.Register(
nameof(Selector),
typeof(string),
typeof(RootComponent),
new PropertyMetadata(null));

public static readonly DependencyProperty ComponentTypeProperty = DependencyProperty.Register(
nameof(ComponentType),
typeof(Type),
typeof(RootComponent),
new PropertyMetadata(null));

public static readonly DependencyProperty ParametersProperty = DependencyProperty.Register(
nameof(Parameters),
typeof(IDictionary),
typeof(RootComponent),
new PropertyMetadata(null, OnParametersChanged));

public string Selector
{
get => (string)GetValue(SelectorProperty);
set => SetValue(SelectorProperty, value);
}

public Type ComponentType
{
get => (Type)GetValue(ComponentTypeProperty);
set => SetValue(ComponentTypeProperty, value);
}

public IDictionary? Parameters
{
get => (IDictionary?)GetValue(ParametersProperty);
set => SetValue(ParametersProperty, value);
}

... rest
}
```

Working prototype: https://github.com/ScarletKuro/Scarlet.AspNetCore.Components.WebView/tree/1.1.0/Wpf
### Intended Use-Case

1. In WPF applications using MVVM, the view is described entirely in XAML and all wiring flows through bindings to the view-model. `BlazorWebView.RootComponents` is currently the one XAML-hosted collection where bindings don't work, every property (Selector, ComponentType, Parameters) has to be assigned as a literal, which forces code-behind or static configuration for scenarios that would otherwise be pure MVVM.
2. Consistency with other WPF controls. Every other WPF content property accepts bindings
3. The underlying `BlazorWebView` already supports this pattern.

### Potential impact on existing apps
- new `RootComponent` is a WPF object, read and write should be in the UI thread.

The rest should behave the same.

Contributor guide

Open the contributing guide

Research direction

Start with the WPF BlazorWebView and RootComponent implementations, then compare them with the linked MainWindow.xaml example and the working prototype. Verify how RootComponents are exposed as logical children and how Selector, ComponentType, and Parameters participate in WPF binding; done means all three properties can be assigned through XAML bindings without changing existing behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
desktop
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
65/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.