fsprojects / FsXaml

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

Allow events to be handled from xaml #55

Closed ReedCopsey closed 7 years ago

ReedCopsey commented 7 years ago

Right now, if you put in an event handler, you get a runtime error parsing the xaml.

We could, in theory, handle this. I think I could make the type provider handle everything, but I'm not sure how to get the proper event info out of the xaml schema context while parsing the sample.

For example, given <Button Click="HandleClick" />, I'm not sure how to determine during the xml parsing that Click is an event, and know it's specific type. If somebody wanted to try to figure that out, I think we could get the type provider to route that into a virtual method, allowing for xaml-defined, type safe event handlers to be written.

ReedCopsey commented 7 years ago

I've made some progress on this front. By rewriting the xaml parser, I'm able to get info about events.

My plan is to allow it to be written into the base class as a virtual method.

With a xaml file containing:

   <Button Click="OnMyClick" />

This should become possible:

type MyWinBase = XAML<"Window.xaml">

type MyWin =
    inherit MyWinBase()

    override this.OnMyClick (o,e) =
        MessageBox.Show("Clicked my button!") |> ignore
ReedCopsey commented 7 years ago

@isaacabraham Given that you were curious about how this would work - I'd love to know if you have any feedback. I'm thinking I can have this implemented in the next couple of days.

ReedCopsey commented 7 years ago

Supported in 3.0

isaacabraham commented 7 years ago

Doh. Didn't even see your earlier message. Great it's in though :-)

ReedCopsey commented 7 years ago

@isaacabraham and @foggyfinder - do you think the base class and methods should be abstract? I just thought about it, but it'd force you at compile time to implement the handler correctly. (right now, they're virtual with empty defaults)

ReedCopsey commented 7 years ago

Changing this for 3.1 - After experimenting, it seems that making these abstract is much nicer. It allows the compiler to make sure you put the handlers in properly.

BentTranberg commented 6 years ago

Minor bug report: It works, but only if the Click assignment is not placed at the end of the following.

This works:

<MenuItem Click="MnExitClick" Header="{Binding Source={x:Static lang:Resources.Exit}}"/>

This doesn't work:

<MenuItem Header="{Binding Source={x:Static lang:Resources.Exit}}" Click="MnExitClick"/>

If it is moved to the end, then I get the following compile time error message: No abstract or interface member was found that corresponds to this override.