fsprojects / FsXaml

F# Tools for working with XAML Projects
http://fsprojects.github.io/FsXaml/
MIT License
172 stars 48 forks source link

Object reference not set to instance of object assigning Name for UserControl #61

Closed j-alexander closed 7 years ago

j-alexander commented 7 years ago

Description

Object reference not set to instance of object when assigning Name or x:Name to a UserControl used from a separate Window.

If I can provide any further information, please let me know! I'm happy to help.

Repro steps

  1. Edit demos/WpfSimpleMvvmApplication/MainWindow.xaml line 12 to read as follows:

    <local:MainView Grid.Row="1" IsTabStop="False" x:Name="MyMainView" /> or <local:MainView Grid.Row="1" IsTabStop="False" Name="MyMainView" />

  2. Compile

Expected behavior

Assignment of a name+property for the UserControl so that it can be referenced from code. This does appears to work for tbFullName and FirstName in MainView.xaml.

Actual behavior

error FS3033: The type provider 'FsXaml.XamlTypeProvider' reported an error: Object reference not set to an instance of an object.

Related information

FsXaml (3.1.2) and head of master (commit 9fc1da34fa6acf9f28db86c927ddc1163e18c0d1)

ReedCopsey commented 7 years ago

@j-alexander So I've been digging into this - the problem appears to be referencing a locally defined object (within the same project). The issue is that the xaml parser can't determine the type, since it hasn't been compiled yet. When I try to make the member in the type provider, the underlying type doesn't exist, and I'm getting null trying to fetch the type. (In C#, this is typically resolved in the 2nd pass of the baml compilation, but that's not an option in a type provider...)

I'm trying to think of a good option as a workaround - but right now, my only idea is to just have this typed as obj instead of MainView, which should still allow ElementName bindings to work, but would make the named property in the type less useful, as it'd lose the type information.

Do you think this is a reasonable workaround?

ReedCopsey commented 7 years ago

So - as a follow up - I have the above idea working. Using this:

    <local:MainView Grid.Row="1" IsTabStop="False" x:Name="Test" />
        <TextBlock Text="{Binding ElementName=Test, Path=tbFullName.Text}" FontSize="16" Grid.Row="2" />

Allows it to work:

image

In code, however, you lose the type info:

image

I'm not sure the 2nd is avoidable, though - at least, right now, I don't see a way to avoid it.

I'd love to know if this would work for you - if so, I can push out a bug fix to NuGet.

j-alexander commented 7 years ago

Honestly, I think that gets us the majority of the way to the goal! In particular, it eliminates the error compiling (especially when bringing in Xaml from a C# project), and the property is available from the F# code (albeit as obj).

Thanks for the quick response!

ReedCopsey commented 7 years ago

@j-alexander This is now released in 3.1.3 - https://www.nuget.org/packages/FsXaml.Wpf/ Please let me know if you have any more issues with it.