FsXaml for UserControls
See original GitHub issueI’ve been attempting to find a way to use FsXaml to access a UserControl that’s defined in its own individual XAML file, but I’ve been unable to find a method that works.
For example when “ListBoxQuery.xaml” defines a UserControl
type ListBoxQueryXaml = XAML<"ListBoxQuery.xaml">
let queryUI = new ListBoxQueryXaml()
let usercontrol = ListBoxQueryXaml.Accessor(xamlui)
is the only way I’ve been able to access the elements defined in the XAML file, but this method fails because at runtime attempting to use the elements throws a null object exception.
When these types like ListBoxQueryXaml are compiled to a class library and that .dll is loaded into the XAML Designer by adding it to the toolbox it does create XAML elements that can be embedded into other windows and panels. Although this isn’t particularly useful as I haven’t been able to give them any functionality using F# code beyond the default behavior of their standard control subcomponents.
I’ve had great success using FsXaml for individual WPF GUI windows, but perhaps I have a fundamental misunderstanding of how it should be applied in the creation of custom controls?
Issue Analytics
- State:
- Created 9 years ago
- Comments:6 (6 by maintainers)
Top GitHub Comments
@cloudRoutine Just FYI - In general,
member val
will never work with INotifyPropertyChanged. The problem is thatx.Value
is a property, so if you writemember val Foo = x.Value
you end up making a member based on the current value of that property, but it doesn’t actually set the property itself. I tried to get the syntax as short as possible, but you pretty much have to get and set from property to make it work.In general, the thought was that the “normal” use case would be via an MVVM approach, in which case you very rarely (almost never) would use code behind, preferring usage via binding. As such, this is rarely needed.
That being said, your code, (almost) as written, should actually work. You do have a typo in the code, however - which may be causing the issue:
Other possible issues would potentially be when you call this in your project (the thread affinity of WPF in general causes can strange things to happen if this is written prior to the entry point).
That being said, the intended mechanism for getting “code behind” style access is actually through a custom
ViewController
. Since we can’t create a partial class ala-C#, we create a separate type that provides the implementation for “code behind” and reference that. The main difference in terms of funcitonality is that theIViewController.Attach
method runs when the control gets loaded, not on construction.I had a demo showing this off for a Window, but just added it to one of the custom UserControls in the demos. You can see this approach in action.
The first part is to add the definition to your code behind file. Bascially, when you defined your view, make a type that implements
IViewController
. The demo just demonstrates subscribing to MouseDoubleClick on a text box. You then add an attached property to the XAML for the UserControl to say to use this customIViewController
.For details, see controller implementation here: https://github.com/fsprojects/FsXaml/blob/master/demos/WpfSimpleMvvmApplication/MainView.xaml.fs#L16 And XAML usage here: https://github.com/fsprojects/FsXaml/blob/master/demos/WpfSimpleMvvmApplication/MainView.xaml#L8