Giter Site home page Giter Site logo

zzarchive-fsharp.desktop.ui's People

Contributors

dmitry-a-morozov avatar dnauck avatar forki avatar fsprojectsgit avatar sergey-tihon avatar teadrivendev avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

zzarchive-fsharp.desktop.ui's Issues

TypeInitializationException in Patterns

I have started a small application taking the general structure from the Calculator example (which I ported to FsXaml first). However, I am already stuck very early on.

This is the complete F# code:

open System
open System.Windows
open System.Windows.Data

open FSharp.Desktop.UI

type App = FsXaml.XAML<"App.xaml">

type OAuth = FsXaml.XAML<"OAuth.xaml", true>

[<AbstractClass>]
type OAuthModel() =
    inherit Model()

    abstract Pin : string with get, set

type OAuthEvents =
    | SubmitPin

type OAuthView(root : OAuth) as this =
    inherit View<OAuthEvents, OAuthModel, Window>(root.Root)

    override this.EventStreams =
        [
            let buttonClicks =
                [
                    root.SubmitPinButton, SubmitPin
                ]
                |> List.map (fun (button, event) -> button.Click |> Observable.mapTo event)

            yield! buttonClicks                
       ]

    override this.SetBindings model =
        let root = OAuth this.Root

        Binding.OfExpression
            <@
                root.PinTextBox.Text <- coerce model.Pin
            @>

type OAuthController() =
    interface IController<OAuthEvents, OAuthModel> with
        member this.InitModel model =
            model.Pin <- ""

        member this.Dispatcher = function
            | SubmitPin -> Sync this.SubmitPin

    member this.SubmitPin(model : OAuthModel) =
        MessageBox.Show "Da" |> ignore

[<EntryPoint; STAThread>]
let main args =
    let model, view, controller = OAuthModel.Create(), OAuthView(OAuth()), OAuthController()

    let mvc = Mvc(model, view, controller)
    use eventLoop = mvc.Start()
    let app = App().Root
    app.DispatcherUnhandledException.Add <| fun args ->
        if MessageBox.Show(args.Exception.ToString(), "Error! Ignore?", MessageBoxButton.YesNo, MessageBoxImage.Error, MessageBoxResult.Yes) = MessageBoxResult.Yes
        then args.Handled <- true
    app.Run(window = view.Root)

I am at this time just trying to get anything to work; however, when I run this, a TypeInitializationException occurs in the Binding.OfExpression call, telling me that the type initializer for Patterns has thrown an error, and I don't know what to make of it.

PinTextBox in OAuth.xaml is a simple text box, SubmitPin is a button.

Any ideas what I'm doing wrong?

Update NuGet package

When using the NuGet package, I get this exception when calling Model.Create():

Message: An unhandled exception of type 'System.TypeInitializationException' occurred in Prog.exe
Additional information: The type initializer for 'FSharp.Desktop.UI.Model' threw an exception.

If I upgrade Castle.Core to the latest version, Model.Create() works. So, it seems that the Castle.Core version referenced in the NuGet package doesn't work with the latest version of .NET or F# runtime.

Derived properties in WinForms

Even though this is a WPF framework, we're fitting it for WinForms. I know there's a [<DerivedProperty>] that Binding.OfExpression uses to do multi-way binding in the case of computed properties. In WinForms the Binding.OfExpression does not work because, I assume, WinForms is not compatible with the WPF binding framework.

I made a [<DerivedFrom(string array)>] attribute that lets you mark the direct dependencies of the computed properties on your model and hijacked the body of the Intercept method on the IIntercepter on the Model, so that when a setter is called, I check to see if there are any children pointing to me as a dependency.

I am still working on a couple nice-to-haves like transitive dependency resolution and memoizing reflection results, but it mostly works. Is this something that could be made into a pull request? I know it is a little strange thematically as this is a WPF framework.

Separate events instead of discriminated unions?

I know this is an old library by now, but it still appeared high up on the search results, so here I am.

I'm learning F# (so all of the below may be based on misunderstandings) and I want to use F# for a Xamarin app. Your MVC way of thinking as described in your series seems to have a lot of merit. However, I'm a bit fuzzy on why you have a single event stream per MVC-combo where all the different events are separate cases of a single discriminated union. As far as I can see, this precludes easy Rx manipulation of the different events.

For example, say you have two events for a view: MouseMoved and ButtonClicked. According to your architecture, these would then be two cases of a discriminated union. But if you want to e.g. throttle MouseMoved, or filter it based on coordinates, I can't see an elegant way of doing this. If the two events were instead two different IObservables, this would be trivial.

My two questions:

  1. Do you have any comment on this?

  2. Would you say your MVC solution is still relevant, or are there better ways of solving things nowadays?

Rx-Main package is unlisted

Description

This project depends on Rx-Main and the package is now unlisted. Should be changed to System.Reactive.*

Collection handling

Hi,

quick question, how would you handle collections ? Let's say, a list of ToDoItems. I can't find a nice solution.

Thanks !

Composition and Interoperability

I read your fsharp-wpf-mvc-series and you actually have got Mvc.Compose methods in this library as well, and all works fine for composition, but what about interoperability?

Maybe I am wrong but in your samples I could not find any example of such interoperability. In C# projects we use Event Aggregators, how could I achieve similar feature in FSharp.Desktop.UI?

Controllers encapsulate operations pipelined by events associated with views. In interoperability among different modules/views basically controllers already implement operations which are required in interoperability operation.

What are your thoughts? Some kind of EventAggregator or similar like in your controller approach some kind of event translator and controller/model selector?

External async updates to the model?

Sorry this is more a question than an issue.

I am trying to use this library for a project where I react also need to react to midi events which are coming from my controller. For this purpose, I have created an agent with MailboxProcessor from which I would like the model to update depending on different messages.

I saw in your wolfram example how to do async calls. My question is where would be the best place to introduce messages coming from the agent? I assume they should come in the controller but not sure how to plug this. Would using the Dispatcher member with an Async event handler which contains a recursive loop waiting on messages be okay?

Thank you.

SetBindings and DataContext

DataContext should be set before SetBindings otherwise in initial binding there is a lot of errors:

System.Windows.Data Error: 40 : BindingExpression path error: 'ToDate' property not found on 'object' ''MainModelProxy' (HashCode=10737664)'. BindingExpression:Path=ToDate; DataItem='MainModelProxy' (HashCode=10737664); target element is 'DateEdit' (Name='deToDate'); target property is 'EditValue' (type 'Object')

    member this.SetBindings model = 
        root.DataContext <- model
        this.SetBindings model

[<DerivedProperty>] problem

I noticed quite strange behavior for derived properties. In my model I have got:

[<DerivedProperty>]
member this.MarketName
    with get() = if this.OpenBetEvent.IsSome then this.Market.MarketInfo.ToString() else "No market selected"

[<DerivedProperty>]
member this.CanCloseMarket
    with get() = this.IsAuthorized && this.OpenBetEvent.IsSome

In the first initial data binding for my view CanCloseMarket is evaluated, but not MarketName.
Market is abstract property. When OpenBetEvent changes correct values are set in bind controls on my view, but not on the first initial state.

My workaround is to not use DerivedProperty
for MarketName and to call this.NotifyPropertyChanged "MarketName" whenever OpenBetEvent changes.

In my project I have got quite a lot of such models with this problem. In all such models one of properties is option value, so that could be maybe clue for you to solve this issue. I really do not know because as you can see in CanCloseMarket, the OpenBetEvent is option value and here the DerivedProperty works fine.

No errors or warnings are reported when bindings are set for those properties.

Calculator Sample - unexpected red highlight on error

When I run the calculator sample and give the value "-1" to "Y", and then click on the "+" button, the box containing -1 is highlighted with a red border, which makes sense (since we don't allow addition with values of "Y" less than 0).

I don't understand why the "/" button is also highlighted.

When I comment out the "divide.IsEnabled <- model.Y <> 0." binding, the red border does not appear on the "/" button using the above sequence of events.

My guess is that an error in the "Y" box causes some confusion with the divide by zero constraint.

Is there a problem here, or have I missed something?

I'm enjoying the great work being done in F# Deep Dives.

Regards,

g.

Questions

I am currently trying to create some projects using your MVC framework and it seems some of the code you are using in fsharp-wpf-mvc-series are now missing or have changed.

What is the current recommended way to use an existing converter (for example a BoolToVisibility converter)? It seems the only correct way (based on my understanding of your code) is to provide a function that acts as converter and not to use a converter class (IValueConverter).

I am also wondering how you would handle displaying a message (for example message box but I assume the behavior would be the same) at the end of an operation? For now, I am passing a method (string -> string -> unit) as an argument of my controller and I call this method when needed. Doing so I am able to keep my unit tests quite simple as I can fake my methods. But I am wondering if the problem should not be inverted, meaning that the XamlView implementation should not subscribe to a result of the controller's method to trigger the message box.

Adding tests that mimic eventstreams

I'd like to test the GUI I have built by writing scripts that generate the EventStreams that your mvc controllers dispatch on.

If I have a mousewheel event defined as:

w.MouseWheel |> Observable.map (fun args -> if args.Delta > 0 then Next else Previous)

I'd like to be generating the "Next" or "Previous" events in my integration tests rather than using the real MouseWheel (but still exercising the rest of the real GUI).

I haven't a good idea how to plumb that in; I've tried a few things that didn't really work.

Please would you give a few pointers on how to get started?

Thanks,

George.

Model Reset/Clear

I think you should consider to add model reset or clear method for abstract properties. In your implementation, abstract properties are held in dictionary:

and internal AbstractProperties() =
    let data = Dictionary()

So if model needs to refresh those properties, mainly those which content is set by wpf data binding, those properties remain with old data, if wpf control did not reset them directly.

Of course for most of properties when model context changes,there is possible to set those properties directly by model setter, but really not for all of them in my case.

FrameworkContentElement binding

Some UI libraries use FrameworkContentElement so to bind such UI elements I added TargetContent partial active patterns and extended Expr ToBinding method. Is there a way to make it a more general?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.