Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
    Josua Jäger
    @JaggerJo
    happy to help
    Mark Elston
    @melston
    On to the next thing. :) Are there any examples of Drag and Drop in FuncUI? I would like to be able to rearrange elements in the treeview if possible.
    Bruce Reif (Buswolley)
    @B-Reif
    Hey, just added a PR for 'keys' like in React
    Denis Proshutinskii
    @jl0pd
    I have a question about HostControl: If I create control and then replace it with something else, will this control live in memory? I'm not sure because every control have Program.run inside of it and it's an infinite loop, which doesn't listen to detaching from visual tree
    Jerry Wiltse
    @solvingj
    does FuncUI support hotreload?
    smolck
    @smolck
    Denis Proshutinskii
    @jl0pd
    @solvingj, also you may want to see https://github.com/fsprojects/Avalonia.FuncUI/issues/149, it have information on how you can save state across reloads. Live.Avalonia rebuilds project and recreates everything from scratch. Also there's dotnet/sdk#15825 in dotnet sdk repo about dotnet watch support for hot reload, it's going to be a part of net6-preview3 dotnet/sdk#15849. There's also LiveSharp but I didn't tried it and it's paid
    Emil Ahlbäck
    @mull
    Hi! Curious to hear whether there is a real world application built using FuncUI? I'm testing/evaluating (also new to F#) and would love to read some code & play with an existing project
    Martin Blackman
    @mpblackman
    Does anyone have a working example showing how to create a Menu on Windows? I get a compile error, expecting a '..IView list' but given a '..IView<MenuItem> list'.
    Martin Blackman
    @mpblackman
    Thanks to @AngelMunoz ..I found some code demonstrating how to create a simple menu
    let tmenu = 
                Menu.create [
                    Menu.viewItems [
                        yield MenuItem.create [MenuItem.header "File"]
                        yield MenuItem.create [MenuItem.header "Edit"]
                    ]
                ]
    Arto Lehisto
    @Lipastomies

    Hi all,

    I'm trying to implement a list of entries (e.g. list of notes) in an app, with the condition that each entry should be easily deletable by pressing a button. Everything has been going fine, except that the deletion part seems to work a bit wonkily - Whenever I press an entry deletion button, instead of sending a message to delete that entry, a removal message with the first entry in that list is sent. Would someone happen to know why this happens, and how to send the correct entry with a button press?

    My update function looks like this:

        type Entry = {uid:int}
        type State = { entries: Entry list; uid : int}
        let init = { entries = [];uid = 0 }
    
        type Msg = Add | Remove of Entry | Reset 
    
        let update (msg: Msg) (state: State) : State =
            match msg with
            | Add -> { state with entries = List.append [{uid=state.uid}] state.entries;uid = state.uid + 1 }
            | Remove id ->
                let entries = state.entries |> List.filter (fun x -> x <> id )
                { state with entries = entries }
            | Reset -> init

    And my view is quite simple as well:

        let emptyEntries =
            StackPanel.create[
                StackPanel.children[
                    TextBlock.create [
                        TextBlock.text "No expenses"
                    ]
                ]
            ]
    
        let singleEntry (entry:Entry) dispatch = 
            Button.create [
                Button.content (sprintf "Remove %A" entry.uid)
                Button.onClick (fun _ -> 
                    printfn "entry: %A" entry
                    dispatch (Remove entry))
            ]
    
        let existEntries (entries:Entry list) dispatch =
            StackPanel.create[
                StackPanel.children [
                    for entry in entries do
                        yield singleEntry entry dispatch
                ]
            ]
    
        let entryPanel state dispatch = 
            match state.entries with
                | [] -> emptyEntries :> IView
                | xs -> (existEntries xs dispatch) :> IView
    
        let view (state: State) (dispatch) =
            DockPanel.create [
                DockPanel.children [
                    Button.create [
                        Button.dock Dock.Bottom
                        Button.onClick (fun _ -> dispatch Reset)
                        Button.content "reset"
                    ]                
                    Button.create [
                        Button.dock Dock.Bottom
                        Button.onClick (fun _ -> dispatch Add)
                        Button.content "+"
                    ]
                    StackPanel.create [
                        StackPanel.dock Dock.Bottom
                        StackPanel.maxHeight 300.0
                        StackPanel.children [ 
                            entryPanel state dispatch
                        ]
                    ]
                    TextBlock.create [
                       TextBlock.dock Dock.Top
                       TextBlock.fontSize 48.0
                       TextBlock.verticalAlignment VerticalAlignment.Center
                       TextBlock.horizontalAlignment HorizontalAlignment.Center
                       TextBlock.text (string state.uid)
                    ]
                ]
            ]

    I have a minimal reproducing example here:
    https://github.com/Lipastomies/AvaFuncProblem

    I'm developing on Win 10, with .NET SDK (5.0.301)

    I unfortunately don't have a clue on what I'm doing wrong, so any and all help would be appreciated.

    Mark Elston
    @melston
    Not sure if this is the problem or not but you can try changing dispatch (Remove entry)) in singleEntry to dispatch (Remove entry.id)). entry is an Entry and Remove takes an id.
    Mark Elston
    @melston
    Oops. Sorry about that. Remove does take an Entry. However, it I would either have it take the int and compare against the id members or compare the id members directly.
    Thomas Waters
    @Evelios

    I'm trying to make something akin to a svg editor, and I'm having a really hard time trying to get the cursor position relative to the drawing canvas. I'm finding it difficult to be able to get mouse positions relative to objects I'm creating on the canvas.

    Canvas.create [
        Canvas.onPointerMoved
            (fun e ->
                e.GetPosition(e.Source :?> IVisual)
                |> Msg.MouseMove
                |> dispatch) ]

    This gets me the cursor position relative to the child object I'm hovering over. If I'm hovering over a child object, it resets the coordinates local to that child instead of being relative to the canvas object

    what I really want is something more like

    let canvas = Canvas.create [ ... ]
    
    DockPanel.create
    <| [ DockPanel.onPointerMoved
                        (fun e ->
                            e.GetPosition(canvas :?> IVisual)  // <-- this is a compilation error and doesn't work
                            |> Msg.MouseMove
                            |> dispatch) ]

    Has anyone had a similar issue or knows how to overcome this?

    Thomas Waters
    @Evelios
    I should have said runtime error instead of compilation error for canvas :? IVisual
    Arto Lehisto
    @Lipastomies
    @melston thank you for your comment. That wasn't the problem, but I managed to figure it out after looking at the excellent demos in the main project repository. I hadn't used SubpatchOptions.OnChangeOF in the button pressing event. I think it's time for me to dig into the concepts a bit more :D
    Mark Elston
    @melston
    Yeah. Once I noticed my mistake I realized I was probably heading down the wrong path.
    Thomas Waters
    @Evelios
    Alright, just in case any one else is having a similar problem. I was able to come up with a solution that I don't think is the best but is at least functional. I take the source that the event was triggered off of, go to the root of the visual tree and do a breadth first search down to find my control element that I'm looking for. I do the search based off of the element name. Don't know how scalable this solution is, but it gets me off and running
        /// Try to find a child control of a given name using breadth first search
        let findChildControl (name: string) (source: IControl) : IControl option =
            let rec findChildControlHelper (children: ILogical list) =
                match children with
                | first :: remaining ->
                    if (first :?> IControl).Name = name then
                        Some(first :?> IControl)
                    else
                        findChildControlHelper (remaining @ (List.ofSeq first.LogicalChildren))
    
                | [] -> None
    
            findChildControlHelper (List.ofSeq source.LogicalChildren)
    
        /// Traverse to the root of the tree and do a breadth first search for the element
        let findControl (name: String) (source: IControl) : IControl option =
            if source.Name = name then
                Some source
            else
                findChildControl name (source.VisualRoot :?> IControl)
    
        /// Given a pointer event, get the position relative to a particular control name
        /// Useful for triggering off of mouse movement events
        let positionRelativeTo (name: String) (event: PointerEventArgs) =
             let maybeVisual =
                 findControl name (event.Source :?> IControl)
    
             match maybeVisual with
             | Some visual -> event.GetPosition(visual)
             | None -> Point(infinity, infinity)
    mecusorin
    @mecusorin_twitter

    Using JaggerJo.Avalonia.FuncUI (0.5.0-beta) Avalonia.Desktop (>= 0.10.0-rc1)
    with the following code:

    let textBlock (text: string) =
        TextBlock.create [
                    TextBlock.fontSize 14.0
                    TextBlock.verticalAlignment VerticalAlignment.Center
                    TextBlock.horizontalAlignment HorizontalAlignment.Center
                    TextBlock.text text
                ] :> IView
    
    let view (state: StationOrchestrator.Model) (dispatch: StationOrchestrator.Msg Dispatch) =
    
    
        HeaderedContentControl.create [
                HeaderedContentControl.header "Hello"
                HeaderedContentControl.foreground "White"
                HeaderedContentControl.background "Blue"
                HeaderedContentControl.width 400.0
                HeaderedContentControl.height 400.0
                HeaderedContentControl.content (textBlock "Groupbox")
            ]

    Is not showing at all the expected Hello GroupBox (just black screen inside the window). Any idea what I am doing wrong?

    I was hoping to use the styling from https://github.com/AvaloniaUI/Avalonia/issues/823#issuecomment-692270581 on the HeaderedContentControl, but it seems that this primitive is not working at all for me.
    mecusorin
    @mecusorin_twitter
    Temporary solution was to use this:
    let groupBox title (content: IView) =
        let headBorder =
            Border.create [
                Border.zIndex 1
                Border.margin (Thickness(15.,0.,0.,0.))
                Border.padding (Thickness(5.,0.,5.,0.))
                Border.background background
                Border.child (
                    TextBlock.create [
                        TextBlock.foreground groupBoxHeaderColor
                        TextBlock.fontWeight FontWeight.Bold
                        TextBlock.text title
                    ])
            ]
        let contentBorder =
            Border.create [
                Border.child content
                Grid.rowSpan 2
                Grid.columnSpan 2
                Border.margin (Thickness(5.,10.,5.,5.))
                Border.padding 5.0 //(Thickness(4.0, 5.0, 4.0, 4.0))
                Border.borderBrush bordersColor
                Border.borderThickness 2.0
                Border.cornerRadius 3.0
            // BoxShadow.Parse "5 5 10 2 DarkGray" |> Border.boxShadow
            ]
    
        Grid.create [
            Grid.rowDefinitions "Auto,*"
            Grid.columnDefinitions "Auto,*"
            Grid.margin 0.
            Grid.children [
                headBorder
                contentBorder
            ]
        ] :> IView
    Fran González
    @sleepyfran
    Hey folks! What's the current status of the project? I just created a PR to upgrade to the latest version of Avalonia and I was wondering who takes care of accepting PRs/publishing new versions, would definitely love to help if new mantainers are needed :)
    Angel D. Munoz
    @AngelMunoz
    The project has been moved to the fsprojects org and some pople is looking after it there
    BD
    @ImaginaryDevelopment
    anyone know how I do this in FuncUI? <RowDefinition MinHeight="80" Height="80"/>
    How do I bind a TextBlock Property to another DependencyProperty? and how do I do FontStretch ?
    Ody Mbegbu
    @odytrice
    Just started using FuncUI and I have to say, this project is awesome
    I don't have much experience with WPF so there's a lot of knowledge that is missing but I'm working my way through them
    Josua Jäger
    @JaggerJo
    @odytrice nice to hear!
    Working on a big update that brings components and react like state management
    WhiteBlackGoose
    @WhiteBlackGoose
    Hey! How do I check if a component is already wrapped for FuncUI? E. g. I want this component: https://github.com/AvaloniaUI/AvaloniaEdit, but can't find about it for FuncUI
    WhiteBlackGoose
    @WhiteBlackGoose
    Question. Is it possible to add properties to components which don't exist in the components? E. g. AvaloniaEdit (a text editor component) sets the syntax highlighting by calling a method, https://github.com/AvaloniaUI/AvaloniaEdit/blob/master/src/AvaloniaEdit.Demo/MainWindow.xaml.cs#L75, which would be nice to be a property instead
    Josua Jäger
    @JaggerJo
    When this is merged, using components without bindings will be cake
    WhiteBlackGoose
    @WhiteBlackGoose
    I see, thanks. I see this is very important and influential PR XD. Nice
    stéén
    @xdsteen_pvp:matrix.org
    [m]
    When creating an IView, is there any way to manipulate the inner element? I wish to force the focus of a certain element by calling .focus on it
    Thomas Waters
    @Evelios
    I was wondering if anyone knew how to change the RoutingStrategy of event handling. From a snipit @JaggerJo did a while ago, he showed that the Tunnel event is triggered first then the Bubble event. I really only want the events to bubble up from bottom to top so I can handle the child elements first. I know that I can change the e.Route or e.RoutedEvent.RoutingStrategies where e is a routed event like PointerReleasedEventArgs. I would have to litter my code with checks for the Bubble event since the Tunnel is called first. Is there a way to set the routing strategy at app creation? Also, what use cases would people be using tunneling events?
    Thomas Waters
    @Evelios

    Not sure if anyone else has wondered about how to unit test update functions after adding saving or loading dialogues but I figured I'd pass that information forward

    open Moq
    let IWindowImpl = Mock<IWindowImpl>().Object
    let window = Mock<Window>(IWindowImpl).Object

    You can then just pass this window object to the update function and you can run the tests. If you are actually testing the code that calls the window functionality you will need to create a mock function return for these objects
    https://fsharpforfunandprofit.com/posts/low-risk-ways-to-use-fsharp-at-work-3/#15-use-f-to-create-mocks

    Heuro
    @Eeuro
    Hello folks, I am trying to deploy an app via dotnet publish CLI commands. The resulting folder and it´s exe will work on the host machine but only load for a short moment and then not show anything
    on the target machine. Any ideas what the problem might be?
    Heuro
    @Eeuro
    Ok I figured out what the problem was. My Asset path wasnt properly specified
    I am having trouble getting the index of the children within a Listitem. How can I make Listbox autoselect the row if a child is getting editted ?
    Paulmichael Blasucci
    @pblasucci
    Hello all, in the wake of the new release I am revisiting an old half-finished project. And I have to say I am really liking the new component model -- it's a perfect fit for what I'm trying to achieve.
    I have a bit of a question though: I'd ultimately like my app to make use of styles and be skinable. Is this worth doing purely in code, or should I keep to XAML for the styles/brushes/etc?
    P. de Bruin
    @P-Louw

    Hi, I am trying to use/learn funcUI by translating some wpf. Now I want to create a Popup to use as nofication system for login etc.

    But I get the error " No logical parent set" and 'PlacementTarget is null'

    I don't know where to go from here and can't find any info or repos using this.

    let toastPopup (state:State) dispatch =
        Border.create [
            ...
            Border.child(
            Popup.create [
                Popup.width 200.
                Popup.height 200.
                Popup.isOpen true
                Popup.child (TextBlock.create [ Textblock.text "Hi there" ])
            ])
        ]

    Based on:
    https://stackoverflow.com/questions/62194012/avalonia-ui-pop-up-overlay#62196079

    Thomas Waters
    @Evelios
    @pblasucci I have been trying to work on skinning in code since I'm using some auto generated colors. I'm getting the accent colors (lighter and darker) from my initial color palette. I had tried creating Styleobjects to swap in the program to achieve this skinning. From what I gathered, the XAML is turned into these Style objects but I haven't found an easy way to create them, let alone with any sort of DSL wrapper. If you make any progress on this one please let me know because I also would like to be able to do that in code! It should still work in XAML though if you are alright hard coding all the hex color codes in those files and then swapping them in the code. Good luck!
    Thomas Waters
    @Evelios

    @P-Louw I don't know how easy of a task that will be compared to avalonia. Creating multiple windows with FuncUI isn't the easiest. There is this example of showing how to link two windows. One will always maintain the focus, which is presumably what you want. There is this example of a multiwindow that you could take a look at
    https://github.com/AngelMunoz/MultiWindow

    You probably have to link that popup window to the host window which is this class that you create near the execution point of the program. This can be accessed within the class as this.
    When creating it through the DSL in a more functional style, you can pass this window into the view function through the following code. I'm not sure if you will need this data or not, but I'm assuming this is what your code is complaining about missing.

    type MainWindow() as this =
        inherit HostWindow()
    
        do
            base.Width <- 400
            base.Height <- 600
            let viewWithWindow (state: State) dispatch = view state dispatch this
    
            Program.mkProgram init update viewWithWindow
            |> Program.withHost this
            |> Program.run
    Werner M. Heigl
    @wmheigl
    Hi, I'm working on a small desktop app in F# using Avalonia.FuncUI. The main window should display a scatter plot. Does anyone know a good library for this?