Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How can I make a TextBox input mask? #80

Closed
kevinha opened this issue Mar 8, 2020 · 4 comments
Closed

How can I make a TextBox input mask? #80

kevinha opened this issue Mar 8, 2020 · 4 comments

Comments

@kevinha
Copy link

kevinha commented Mar 8, 2020

Hi, can you suggest a way I can provide an input mask for TextBox, e.g. so that it only accepts numeric input? I've tried modifying the input data in the OnTextInput and OnKeyUp event handlers and also by simply setting the text property as part of the msg/model/view process but none of that works. This is on .Net Core/Windows. Also I am new to Avalonia.

Thanks for bringing Elmish to Avalonia btw!

@JaggerJo
Copy link
Member

JaggerJo commented Mar 9, 2020

Hey, this is a good question! This is currently not a built in feature of Avalonia, but shouldn’t be too hard to implement ourselves.

I’m currently a bit busy, but would like to build a small snippet. There are a few ways to do this and I’m not sure whats the best one.

  • Build small custom control
  • Tapping into the tunneled event (might not be that easy until FuncUI has something like ‘useEffect’ to access the view reference)

Are you depending on this/ is it urgent?

Thanks, it’s becoming a nice little community :)

@kevinha
Copy link
Author

kevinha commented Mar 10, 2020

Hi, I made progress of sorts in the obvious way with somethinglike this

module TextBoxExt =
    open Avalonia.FuncUI.Builder
    type TextBox() =
        inherit Avalonia.Controls.TextBox()
        override __.OnTextInput(e:TextInputEventArgs) =
            e.Text <- "1111111"
            base.OnTextInput(e)
            
    let create (attrs: IAttr<TextBox> list): IView<TextBox> =
        ViewBuilder.Create<TextBox>(attrs)

though the result is practically invisible as the control does not appear have inherited the styles from the stock TextBox which I thought it should. At this point my Avalonia noobiness prevents any further progress. I can tab to the control and text input/event modification appears to work I just can't see it.

I'm not in a rush for this, however if there is stuff you want me to try in the meantime just say.

@JaggerJo
Copy link
Member

Hey,

If you inherit from another control and want to use its template you need to implement IStylable.StyleKey like this:

interface IStyleable with
    member this.StyleKey = typeof<TextBox>

I just threw together a small working MaskedTextBox (note that it's far from a good implementation, but it should work in your case.)

type MaskedTextBox() =
    inherit Avalonia.Controls.TextBox()

    member val FilterFunc : string -> string = fun a -> a with get, set

    override this.OnTextInput(e:TextInputEventArgs) =
        e.Text <- this.FilterFunc e.Text
        base.OnTextInput(e)

    interface IStyleable with
        member this.StyleKey = typeof<TextBox>

module MaskedTextBox =
    open Avalonia.FuncUI.Types

    let create (attrs: IAttr<MaskedTextBox> list): IView<MaskedTextBox> =
        ViewBuilder.Create<MaskedTextBox>(attrs)

type MaskedTextBox with
    static member filterFunc<'t when 't :> MaskedTextBox>(filterFunc: string -> string) =
        let getter : 't -> (string -> string) = (fun c -> c.FilterFunc)
        let setter : 't * (string -> string) -> unit = (fun (c, v) -> c.FilterFunc <- v)

        AttrBuilder<'t>.CreateProperty<string -> string>("FilterFunc", filterFunc, ValueSome getter, ValueSome setter, ValueNone)

Example:

MaskedTextBox.create [
    ...
    MaskedTextBox.filterFunc (fun text ->
        // or check if regex matches, whatever
        let isNumber, _ = Int32.TryParse text
           match isNumber with
               | true -> text
               | false -> String.Empty
    )
]

Let me know it this helps or if there are further issues :)

@kevinha
Copy link
Author

kevinha commented Mar 12, 2020

Thanks, just what I wanted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants