你如何将文件交给用户?

How do you hand over files to the user?

在#WASM / #UNO-platform 项目中,如何将文件交给用户?

在我的例子中,我在本地生成一个 PDF,必须下载它或在浏览器中显示它。

有线索吗?
问候, 迈克尔

还没有 API 可以直接这样做。但是您可以在锚点 (a) HTML 元素上创建 data: url。

为此,您需要创建一些 JavaScript。方法如下:

IMPORTANT: following code will only work with very recent version of Uno.UI. Version starting with v3.0.0-dev.949+

<a> 标签创建一个 ContentControl

[HtmlElement("a")]
public partial class WasmDownload : ContentControl
{
    public static readonly DependencyProperty MimeTypeProperty = DependencyProperty.Register(
        "MimeType", typeof(string), typeof(WasmDownload), new PropertyMetadata("application/octet-stream", OnChanged));

    public string MimeType
    {
        get => (string) GetValue(MimeTypeProperty);
        set => SetValue(MimeTypeProperty, value);
    }

    public static readonly DependencyProperty FileNameProperty = DependencyProperty.Register(
        "FileName", typeof(string), typeof(WasmDownload), new PropertyMetadata("filename.bin", OnChanged));

    public string FileName
    {
        get => (string) GetValue(FileNameProperty);
        set => SetValue(FileNameProperty, value);
    }

    private Memory<byte> _content;

    public void SetContent(Memory<byte> content)
    {
        _content = content;
        Update();
    }

    private static void OnChanged(DependencyObject dependencyobject, DependencyPropertyChangedEventArgs args)
    {
        if (dependencyobject is WasmDownload wd)
        {
            wd.Update();
        }
    }

    private void Update()
    {
        if (_content.Length == 0)
        {
            this.ClearHtmlAttribute("href");
        }
        else
        {
            var base64 = Convert.ToBase64String(_content.ToArray());
            var dataUrl = $"data:{MimeType};base64,{base64}";
            this.SetHtmlAttribute("href", dataUrl);
            this.SetHtmlAttribute("download", FileName);
        }
    }
}

在您的 XAML 页面中使用它

<myControls:WasmDownload FileName="test.txt" x:Name="download">
    Click here to download
</myControls:WasmDownload>

请注意,您可以像任何其他 XAML ContentControl 一样将任何内容放入控件的内容中。

在代码隐藏中设置文件内容

Loaded += (sender, e) =>
{
    download.MimeType = "text/plain";

    var bytes = Encoding.UTF8.GetBytes("this is the content");
    download.SetContent(bytes);
};

结果

Uno 的直接支持

有一个 PR #3380 可以将此功能添加到所有平台的 Uno 中。您也可以等待它而不是自定义方式。

FileSavePicker 的 PR 已合并,该功能现在在包 Uno.UI 中可用,版本为 3.0.0-dev.1353