F#交互式中的Windows UI(UWP或8.1) [英] Windows UI (UWP or 8.1) in F# interactive

查看:140
本文介绍了F#交互式中的Windows UI(UWP或8.1)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通过引用默认的WPF DLL,使用纯代码WPF可以做任何事情,都是很容易的:

By referencing the default WPF DLLs, it's pretty easy to do anything you could do using code-only WPF:

#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()

...,您可以在窗口仍处于打开状态时对其进行操作...

... and you can manipulate it while the window is still open...

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

...,然后单击按钮以查看其工作.这似乎是构建UI组件的一种非常强大的方法.

...and then click the button to see it work. It seems like a pretty powerful way to build up UI components.

是否可以使用Windows.UI命名空间/控件/UI框架执行相同的操作-在F#交互式中加载某些程序集并即时实例化UI组件?

我天真地尝试引用了似乎相关的文件:

I've naively tried referencing the files that seemed relevant:

#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"

...并且这样做使我对Windows.UI命名空间有了智能.但是当我尝试实例化某些东西时:

...and doing that gets me intellisense into the Windows.UI namespaces. But when I try to instantiate something:

Windows.UI.Xaml.Application()

我得到:

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)

推荐答案

WinRT程序集不支持编译器,因此您在尝试使用和使用类型时将无法引用程序集干净地放在其中.

There is no compiler support for WinRT assemblies, so you're not going to be able to reference an assembly as you're attempting to do and use the types in them cleanly.

另一方面,由于.NET运行时对WinRT类型具有本机支持,因此您可以使用反射来加载这些类型并访问其成员.通过大量的努力,您甚至可以构建类型提供程序以在该反射上提供清晰的外观,并使它看起来好像您可以直接使用类型一样.这是一个如何通过反射直接从F#调用WinRT API的小例子:

On the other hand... since the .NET runtime has native support for WinRT types, you can use reflection to load those types and access their members. With a lot of effort, you could even build a type provider to provide a clean façade over that reflection and make it appear as though you can use the types directly. Here's a small example of how to directly call a WinRT API from F# via reflection:

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")

这篇关于F#交互式中的Windows UI(UWP或8.1)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆