dotnet / dotnet/wpf

A binding error occurs in a nested UserControl if asynchronous processing is interposed before Show the Window

Open
#7,752 4 comments 0 reactions 0 assignees View on GitHub
Investigate
Dominant language
C#
Stars
7.7k
Forks
1.3k
Avg merge
1d 11h
Merged PRs (30d)
61

Description

I have a UserControl1 which has a UserControl in its Dependency Property.
This UserControl(InnerUserControl) is displayed with ContentPresenter inside UserControl1.

Place UserControl1 on the Window and place UserControl2 on its InnerUserControl.

Binding is performed from Window to DataContext of InnerUserControl, but in the following cases, a binding error occurs.

- After setting the DataContext and before showing the Window, inserting asynchronous processing (such as `await Task.Delay(1000)`) will result in a binding error.
- If you comment out this asynchronous process, the binding error will not occur
- Only InnerUserControl using ContentPresenter gives binding error

Error Message:
`UpdateCannot find element that provides DataContext. BindingExpression:Path=UserControl2ViewModel; DataItem=null; target element is 'UserControl2' (Name=''); target property is 'DataContext' (type 'Object')`

TargetFramework: net6.0-windows
Visual Studio 2022 Version 17.5.4

I'm not sure if the below is related.
https://github.com/dotnet/wpf/issues/3504

Whole project here
[MinimalExample.zip](https://github.com/dotnet/wpf/files/11302116/MinimalExample.zip)

Code example

UserControl1
```xml



```
```C#
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}

public static readonly DependencyProperty InnerUserControlProperty =
DependencyProperty.Register(nameof(InnerUserControl), typeof(UserControl), typeof(UserControl1));

public UserControl InnerUserControl
{
get { return (UserControl)GetValue(InnerUserControlProperty); }
set { SetValue(InnerUserControlProperty, value); }
}
}
```

UserControl2
```xml



```
```C#
public partial class UserControl2 : UserControl
{
public UserControl2()
{
InitializeComponent();
}
}
```

MainWindow
```xml








```
```C#
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
```

ViewModels
```C#
public class MainWindowViewModel
{
public string Message { get; set; } = "MainWindow";
public UserControl2ViewModel UserControl2ViewModel { get; set; } = new();
}
public class UserControl2ViewModel
{
public string Message { get; set; } = "UserControl2ViewModel";
}
```

App
```xml




```
```C#
public partial class App : Application
{
protected override async void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
var mainWindow = new MainWindow() { DataContext = new MainWindowViewModel() };
await Task.Delay(1000);
mainWindow.Show();
}
}
```

I get a binding error with the above code,
If I comment out `await Task.Delay(1000);` the binding error does not occur.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.