Closed ruxo closed 8 years ago
@ruxo Thanks for this - I'll try to carve out some time to look into it in detail.
It looks like you figured out how to get the xaml loader to load directly into the root object, as well. That's something I'll definitely consider stealing - it'd make FsXaml's type provider better...
As for adding the ability to subclass, it's definitely something I'll look into - I think that may make a lot of sense for integrating in some manner. I need to spend some time with your library in detail to figure out how it's all working.
That being said, would you be willing to relicense or dual license under Apache 2, so I can include the code directly? Most of the core F# projects are apache licensed, so I followed suit with this library.
Thank you. Glad my idea can help :)
For the license, I'll make change later. But here is a code snippet that I think you can just used to do the trick.
let private loadStreamInternal(reader: XamlXmlReader, rootObject: obj option) =
let writerSettings = XamlObjectWriterSettings()
match rootObject with
| Some root -> writerSettings.RootObjectInstance <- root
| None -> ()
use writer = new XamlObjectWriter(reader.SchemaContext, writerSettings)
while reader.Read() do
writer.WriteNode(reader)
writer.Result
let private loadWpfInternal (xamlContent: string) (rootObject: obj option) :obj =
let stream = new StringReader(xamlContent)
use reader = new XamlXmlReader(stream, XamlReader.GetWpfSchemaContext())
loadStreamInternal(reader, rootObject)
If we can load XAML string from resource and we have the root object, we can apply XAML to the root object by calling loadWpfInternal xamlContent (Some ourWpfObject)
, which is essentially what InitializeCodeBehind
method finally calls.
@ruxo Just wanted to follow up - I've been working on this, and have a prototype that now allows for:
type MainViewBase = XAML<"MainView.xaml", true>
type MainView() as self =
inherit MainViewBase()
do
let showMessage _ =
System.Windows.MessageBox.Show "You double clicked on Full Name!"
|> ignore
self.Loaded.Subscribe (fun _ -> self.tbFullName.MouseDoubleClick.Subscribe showMessage |> ignore) |> ignore
The nice thing here is you still get the advantages of the type provider (automatic handling of named elements - see tbFullname
above), but a way to write "code behind" more naturally. This will likely eliminate the need for the ViewController "hack" in FsXaml today, as well.
I'm hoping to clean this up and get it posted here soon - will likely work on FsXaml 2.0 pre using this technique, since it's not backwards compatible with the current library.
Thank you for head up. This looks awesome :D. If there's anything I can help please say so.
@ReedCopsey share the prototype before cleaning it up?
@JohanLarsson Pushing code in a minute - planning a prerelease nuget package shortly.
@JohanLarsson Nuget has a prerelease with this - please feel free to test and give feedback.
@ruxo Can you look at #38 ?
Does that happen with your approach, as well? I'm using the technique you spelled out in FsXaml 2.0, and it's now causing this to occur. I'm not sure how to work around it.
I've developed my own XAML wrapper in F#. It makes implementing User Control in F# more easier (is there a way to do it with
FsXaml
type provider?). My wrapper looks like this:(For full example, see https://github.com/ruxo/WpfFs/blob/master/README.md )
Is this feature interested enough to put in FsXaml library?
(Sorry if this style has been discussed before, I'm new to FsXaml library)