MAUI Blazor如何隐藏滚动条

Posted Yu-Core

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MAUI Blazor如何隐藏滚动条相关的知识,希望对你有一定的参考价值。

MAUI Blazor如何隐藏滚动条

Windows

在Windows上是最简单的,改css就可以了,把下面这段添加到app.css中

::-webkit-scrollbar 
    display: none; 

安卓

安卓和iOS有点复杂,需要通过webview

  1. 修改csproj文件,添加以下内容
<ItemGroup Condition="$(TargetFramework.StartsWith(\'net7.0-android\')) != true">
		<Compile Remove="**\\**\\*.Android.cs" />
		<None Include="**\\**\\*.Android.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
	</ItemGroup>

	<ItemGroup Condition="$(TargetFramework.StartsWith(\'net7.0-ios\')) != true AND $(TargetFramework.StartsWith(\'net7.0-maccatalyst\')) != true">
		<Compile Remove="**\\**\\*.iOS.cs" />
		<None Include="**\\**\\*.iOS.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
	</ItemGroup>

	<ItemGroup Condition="$(TargetFramework.Contains(\'-windows\')) != true ">
		<Compile Remove="**\\*.Windows.cs" />
		<None Include="**\\*.Windows.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
	</ItemGroup>
  1. 修改MainPage.xaml
  2. 修改MainPage.xaml.cs
public partial class MainPage : ContentPage
    
        public MainPage()
        
            InitializeComponent();

            _blazorWebView.BlazorWebViewInitializing += BlazorWebViewInitializing;
            _blazorWebView.BlazorWebViewInitialized += BlazorWebViewInitialized;
        

        private partial void BlazorWebViewInitializing(object? sender, BlazorWebViewInitializingEventArgs e);
        private partial void BlazorWebViewInitialized(object? sender, BlazorWebViewInitializedEventArgs e);
    
  1. 添加MainPage.xaml.Android.cs文件
public partial class MainPage
    
        private partial void BlazorWebViewInitializing(object? sender, BlazorWebViewInitializingEventArgs e)
        
        

        private partial void BlazorWebViewInitialized(object? sender, BlazorWebViewInitializedEventArgs e)
        
            e.WebView.VerticalScrollBarEnabled = false;
        
    

iOS

与安卓一致
添加MainPage.xaml.iOS.cs文件

public partial class MainPage
    
        private partial void BlazorWebViewInitializing(object? sender, BlazorWebViewInitializingEventArgs e)
        
            e.Configuration.AllowsInlineMediaPlayback = true;
            e.Configuration.MediaTypesRequiringUserActionForPlayback = WebKit.WKAudiovisualMediaTypes.None;
        

        private partial void BlazorWebViewInitialized(object? sender, BlazorWebViewInitializedEventArgs e)
        
            e.WebView.ScrollView.ShowsVerticalScrollIndicator = false;
        
    

下面这段最好也加上
添加MainPage.xaml.Windows.cs文件

public partial class MainPage
    
        private partial void BlazorWebViewInitializing(object? sender, BlazorWebViewInitializingEventArgs e)
        
        

        private partial void BlazorWebViewInitialized(object? sender, BlazorWebViewInitializedEventArgs e)
        
        
    

MAUI Blazor 加载本地图片的解决方案

为了解决MAUI Blazor无法加载本地图片,https://github.com/dotnet/maui/issues/2907,所以写了这篇文章。

前言

为了解决MAUI Blazor无法加载本地图片,https://github.com/dotnet/maui/issues/2907,所以写了这篇文章。

有token大佬珠玉在前,https://www.cnblogs.com/hejiale010426/p/17073079.html ,以及微软文档的补充,https://learn.microsoft.com/zh-cn/aspnet/core/blazor/images?view=aspnetcore-7.0#stream-image-data,才能写出这篇文章,特此感谢。

解决的思路是判断路径是本机路径,如果是,调用js为它生成blob,将本机路径与blob的url对应上通过字典存储起来,主动释放时从字典移除。
原理上与有token大佬的文章没有什么太大区别,最主要的是增加了缓存机制

正文

添加所需代码

  1. 添加接口ILocalImageService
//https://github.com/dotnet/maui/issues/2907
    public interface ILocalImageService
    
        // 为本地路径的图片创建blob,并返回blob的url,若不是本地路径会直接返回
        Task<string> ToUrl(string path);
        // 调用js,释放图片的blob
        Task RevokeUrl(string path);
    
  1. 添加实现类
public class LocalImageService : ILocalImageService
    
        private readonly IJSRuntime JS;
        private IJSObjectReference module = default!;
        //存储已生成的图片,将图片本机路径与图片blob的url联系起来
        private static readonly ConcurrentDictionary<string, string> urls = new();
        //控制访问单个图片资源的线程数量,若图片blob在生成中,将等待
        private static readonly ConcurrentDictionary<string, SemaphoreSlim> semaphores = new();

        public LocalImageService(IJSRuntime jS)
        
            JS = jS;
        

        //为本地路径的图片创建blob,并返回blob的url,若不是本地路径会直接返回
        public async Task<string> ToUrl(string path)
        
            await InitModule();
            if (!File.Exists(path))
            
                return path;
            

            SemaphoreSlim semaphore = semaphores.GetOrAdd(path, _ => new SemaphoreSlim(1));
            await semaphore.WaitAsync();

            try
            
                if (urls.TryGetValue(path, out string? url))
                
                    return url;
                
                else
                
                    string newUrl = await GenerateImageUrl(path);
                    urls.TryAdd(path, newUrl);

                    return newUrl;
                
            
            finally
            
                semaphore.Release();
            
        
        //调用js,生成图片的blob
        private async Task<string> GenerateImageUrl(string path)
        
            using var imageStream = File.OpenRead(path);
            var dotnetImageStream = new DotNetStreamReference(imageStream);
            var url = await module.InvokeAsync<string>("streamToUrl", new object[1]  dotnetImageStream );
            return url;
        
        //调用js,释放图片的blob
        public async Task RevokeUrl(string path)
        
            await InitModule();

            if(string.IsNullOrWhiteSpace(path))
            
                return;
            

            if (urls.ContainsKey(path))
            
                urls.TryRemove(path, out string? url);
                await module.InvokeVoidAsync("revokeUrl", new object[1]  url! );
            
        

        //初始化JS模块
        private async Task InitModule()
        
            module ??= await JS!.InvokeAsync<IJSObjectReference>("import", "./js/getLocalImage.js");
        
    
  1. 在wwwroot/js中添加getLocalImage.js
/*出自 https://www.cnblogs.com/hejiale010426/p/17073079.html,有修改*/
/** 将stream转url对象 */
export async function streamToUrl(imageStream) 
    // 适配webview和web 
    const arrayBuffer = await imageStream.arrayBuffer();
    const blob = new Blob([arrayBuffer]);
    return (window.URL || window.webkitURL || window || ).createObjectURL(blob);

/**
* 释放url对象,因为createObjectURL创建的对象一直会存在可能会占用过多的内存,请注意释放
*/
export function revokeUrl(url) 
    (window.URL || window.webkitURL || window || ).revokeObjectURL(url);

  1. 在MauiProgram.cs中添加以下代码
builder.Services.AddScoped<ILocalImageService, LocalImageService>();

注意事项

使用时一定要注意释放,当你不需要这个图片时主动释放它。如果它需要经常显示,那么不必释放,因为生成比较大的图片在安卓上是比较慢的。

最终效果

源码

源码放在GitHub上了,https://github.com/Yu-Core/MAUIBlazorLoadLocalImage

以上是关于MAUI Blazor如何隐藏滚动条的主要内容,如果未能解决你的问题,请参考以下文章

在MAUI中使用Masa Blazor

在MAUI中使用Masa Blazor

Blazor Hybrid / MAUI 简介和实战

MAUI Blazor 加载本地图片的解决方案

MAUI + Masa Blazor 开发带自动更新功能的安卓App

Blazor MAUI - 相机和麦克风 Android 权限