f# uwp uwp-xaml f#-interactive

UI de Windows(UWP u 8.1) en F#interactivo



uwp-xaml f#-interactive (2)

Al hacer referencia a los archivos DLL WPF predeterminados, es bastante fácil hacer cualquier cosa que pueda hacer mediante WPF de solo código:

#r "PresentationCore.dll" #r "PresentationFramework.dll" // ...other DLLs... #r "WindowsBase.dll" let window = System.Windows.Window() let panel = System.Windows.Controls.StackPanel() let button = System.Windows.Controls.Button() panel.Children.Add button button.Content <- "hi" window.Content <- panel window.Show()

... y puedes manipularlo mientras la ventana está abierta ...

button.Click.Add (fun _ -> button.Content <- button.Content :?> string |> fun x -> (x + "!") :> obj)

... y luego haz clic en el botón para ver cómo funciona. Parece una forma bastante poderosa de construir componentes UI.

¿Hay alguna manera de hacer lo mismo con el espacio de nombres / controles / marco de interfaz de usuario de Windows.UI? ¿Cargar algunos ensamblados en F # interactivos y crear instancias de los componentes de la interfaz de usuario sobre la marcha?

Intenté ingenuamente hacer referencia a los archivos que parecían relevantes:

#r @"C:/Program Files (x86)/Windows Kits/10/References/Windows.Foundation.UniversalApiContract/2.0.0.0/Windows.Foundation.UniversalApiContract.winmd" #r @"C:/Program Files (x86)/Windows Kits/10/References/Windows.Foundation.FoundationContract/2.0.0.0/Windows.Foundation.FoundationContract.winmd"

... y hacer eso me da inteligencia en los espacios de nombres de Windows.UI. Pero cuando intento crear una instancia de algo:

Windows.UI.Xaml.Application()

Yo obtengo:

error FS0193: Could not load file or assembly ''file:///C:/Program Files (x86)/Windows Kits/10/References/Windows.Foundation.UniversalApiContract/2.0.0.0/Windows.Foundation.UniversalApiContract.winmd'' or one of its dependencies. Operation is not supported. (Exception from HRESULT: 0x80131515)


No hay soporte del compilador para los ensamblajes de WinRT, por lo que no podrá hacer referencia a un ensamblaje como está intentando hacer y usar los tipos en ellos limpiamente.

Por otro lado ... dado que el tiempo de ejecución .NET tiene soporte nativo para tipos WinRT, puede usar el reflejo para cargar esos tipos y acceder a sus miembros. Con un gran esfuerzo, incluso podría crear un proveedor de tipos para proporcionar una fachada limpia sobre ese reflejo y hacer que parezca que puede usar los tipos directamente. Aquí hay un pequeño ejemplo de cómo llamar directamente a una API de WinRT desde F # a través de la reflexión:

open System.Reflection let (?) (o:obj) s : ''a = let rec build ty args = if Reflection.FSharpType.IsFunction ty then let dom, rng = Reflection.FSharpType.GetFunctionElements ty let mkArgs = if dom = typeof<unit> then if Reflection.FSharpType.IsFunction rng then failwith "Unit as non-final argument in curried definition?" fun _ -> args else fun arg -> arg::args Reflection.FSharpValue.MakeFunction(ty, fun o -> build rng (mkArgs o)) else let rcvr,ty,flags = match o with | :? System.Type as ty -> null,ty,BindingFlags.Static | _ -> o,o.GetType(),BindingFlags.Instance let flags = flags ||| BindingFlags.Public let meth = if Reflection.FSharpType.IsFunction typeof<''a> then query { for m in ty.GetMethods(flags) do where (m.Name = s) where (m.GetParameters().Length = args.Length) exactlyOne } else ty.GetProperty(s, flags).GetGetMethod() meth.Invoke(rcvr, args |> List.toArray) build typeof<''a> [] :?> ''a let Clipboard = System.Type.GetType(@"Windows.ApplicationModel.DataTransfer.Clipboard, Windows.ApplicationModel, Version=255.255.255.255, Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime") Clipboard?GetContent()?AvailableFormats |> Seq.iter (printfn "%s")


Tengo entendido que todavía no hay soporte F # para UWP.
Ver por ejemplo este nuevo tema abierto .