Closed mbergin closed 8 years ago
@mbergin I've managed to duplicate this - and am not sure what's causing it to occur.
Note that it's not simply ElementName bindings that fail - most do work (I have quite a few in the samples), but rather ElementName (and potentially other?) bindings directly on loaded user controls.
For example, the 2nd text box works fine:
<TextBox x:Name="Foo" Grid.Row="3" Grid.Column="0" Text="Foo"/>
<local:UC Grid.Row="3" Grid.Column="1" DataContext="{Binding ElementName=Foo, Path=Text}"/>
<TextBox Grid.Row="4" Grid.Column="0" Text="{Binding ElementName=Foo, Path=Text}"/>
Still investigating, and seeing what can be done. Will keep you posted if I figure something out.
@mbergin I'm not sure how to fix this right now - but I do have a workaround.
You can work around this by changing your XAML. Instead of writing:
<StackPanel>
<TextBox Name="Foo"/>
<local:TestControl DataContext="{Binding ElementName=Foo, Path=Text}"/>
</StackPanel>
You can use:
<StackPanel>
<TextBox Name="Foo"/>
<ContentPresenter Content="{Binding ElementName=Foo, Path=Text}">
<ContentPresenter.ContentTemplate>
<DataTemplate>
<local:TestControl />
</DataTemplate>
</ContentPresenter.ContentTemplate>
</ContentPresenter>
</StackPanel>
I know this isn't ideal - but at least it acts as a temporary workaround.
You can also move the template into a resource, in which case the usage becomes much shorter.
Thanks for checking it out. Some googling revealed another workaround.
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:local="clr-namespace:ViewModels;assembly=FsEmptyWindowsApp1">
<StackPanel>
<TextBox Name="Foo"/>
<local:TestControl DataContext="{Binding Source={x:Reference Foo}, Path=Text}"/>
</StackPanel>
</Window>
This is from ElementName Binding is failing -- some of the comments mention the logical tree might be disconnected, leading to Why does binding fail when binding a child element to another element when the parent succeeds?
Since you mentioned this in the release notes:
UserControl types no longer are wrapped within a ContentControl when loaded from XAML.
I'm not that familiar with the way the WPF logical tree works but I thought perhaps this could be related.
@mbergin Yes, I think there's a namescope issue -and I'm not 100% sure that there's a good workaround, either. I do think using x:Reference
is a "good enough" workaround I may not worry about it too much, though.
@ReedCopsey I found that System.Windows.Markup.IComponentConnector
plays an important role here (but I don't know exactly how).
By implementing our UI class with this interface and the binding will work.
Example (sorry, haven't tried the new library yet):
open RZ.Wpf.CodeBehind
type TestControl() as me =
inherit UserControl()
let mutable content_loaded = false
do (me :> IComponentConnector).InitializeComponent()
interface IComponentConnector with
member x.InitializeComponent() =
if not content_loaded then
me.InitializeCodeBehind "testcontrol.xaml"
content_loaded <- true
member x.Connect(connection_id, target) = content_loaded <- true
(In case you might wonder, this I copied from C# WPF generated code :D )
@ruxo Thanks - This definitely seems to correct it. I'm not sure why, since it's not doing anything - there must be code that uses IComponentConnector
normally and just skips important steps if it doesn't exist.
I'm implementing this for FsXaml 2.1, in progress now. I'm actually doing the code slightly differently than you did above (so it's a bit more inline with what C# gives you), but it appears to be working correctly. Thanks for tracking this down!
@mbergin : This will be corrected in FsXaml 2.1. I hope to release shortly, but the generated type is changing significantly, so I'm trying to do some thorough testing.
This has now been solved in 2.1. @mbergin please try https://www.nuget.org/packages/FsXaml.Wpf/2.1.0
It should now work with the ElementName bindings (as well as your x:Reference
workaround).
Perfect, this works for us now without the workaround. Thanks @ReedCopsey @ruxo for fixing it so quickly!
Description
Binding the DataContext of a UserControl using an ElementName binding worked in 0.9.9, does not work in 2.0.0
Repro steps
MainWindow.xaml
TestControl.xaml
Expected behavior
Typing into the TextBox Foo results in the same text in the TestControl.
Actual behavior
TestControl is blank. Binding error in Debug Output is
None.
Related information