MicrosoftEdge / WebView2Feedback

Feedback and discussions about Microsoft Edge WebView2
https://aka.ms/webview2
444 stars 53 forks source link

How to use multiple instances of WebView2 and WPF TabControl with TemplateSelector #1139

Closed darbid closed 1 year ago

darbid commented 3 years ago

I hope that I am raising issues with WebView2 and not showing my lack of WPF C# knowledge.

Following on from this question #1136 I have now created a new project which includes a DataTemplateSelector and 2 templates. Currently the UserControls are identical but my intention is to have a single main UserControl and then if from this a new window is requested then open a different UserControl also with a webview2 on it.

This repro with a DataTemplate Selector loads 2 different templates when started. As soon as you change tabs the app errors with "System.NotImplementedException: 'The Source property cannot be set to null.'"

Also if you right click on the initial tab on a link and choose to open in a new window this also errors with a "System.NotImplementedException: 'The Source property cannot be set to null.'"

Both of these errors seem to be because WebView2 Source property is bound (mode=TwoWay) to a property in the BaseViewModel of the same name.

darbid commented 3 years ago

After doing a fair bit of reading on #1136 I am fairly sure that the issue in this case is again that the Source dependency property will throw an error if it is null. The repercussion of this is that WebView2 cannot be put into a WPF TabControl or any control with virtualization. It is well known that a WPF TabControl throws away a selected tabitem's visual tree / destroys its children after a selection change.

I did not find a reference to WPF controls throwing an error when the TabControl does such a thing. My guess is that no control that is regularly used in a TabControl throws an exception when the DP is set to null, except for the WebView2. You will find many references where people wish to stop the TabControl from doing this because re-creating the TabItem is a time consuming / costly task.

Here are a few examples with either subclassing TabControl or creating an attached property.

Stop TabControl from recreating its children How to preserve the full state of the View when navigating between Views in an MVVM application? How to preserve control state within tab items in a TabControl WPF TabControl: Turning Off Tab Virtualization

The effect of all of these is to stop the UI virtualization and thus keep many more things in memory.

Given that any opportunity for Chrome based browsers to go on a memory diet should be taken I would be suggesting that you have a look at fixing DP's like Source which throw this kind of exception in these circumstances.

I also don't get the Source exception from WebView2 if I implement a TabControl with virtualization turned off.

champnic commented 1 year ago

Closing old questions - let me know if you think this should stay open. Thanks!

darbid commented 1 year ago

Please fix #1136 and I can then tell if this is fixed.