我正在为Windows和Mac平台创建一个多平台的毛伊应用程序.我最近将项目更新到了.NET8,现在我在按钮方面遇到了一些问题.没有用于控制按钮中的图像大小的属性.在.NET7中,我可以通过更改填充的值来控制图像的大小.但这已经行不通了.

在更新之前,我们看起来像这样;

before update

在更新到.NET 8后,所有带有图像的按钮现在都是这样的;

after update

这是我目前使用的XAML代码;

<Button Text="User" ImageSource="dotnet_bot.png" Padding="0,15,83,5" HeightRequest="35" HorizontalOptions="Start" WidthRequest="225"/>

Extra Info

  • 我try 创建自定义控件,但除了按钮控件外,我们无法定义点击或按下事件.所以,这个解决方案也不起作用.

  • 我已经研究了其他的解决方案,但它们都是在.NET 8之前得到回答的.下面是我看过的一些问题:thisthisthisthisthisthis个问题.

  • 所以,ContentLayout块钱也没什么用.它只是调整文本和图像之间的间距.

  • 较小的图像可能是一个解决方案,但更改此问题的所有assets资源 不是一个好方法.我们需要不同规模的这些assets资源 .

这个问题有什么解决办法吗?任何 idea 都很受欢迎,谢谢!

推荐答案

您的注释表明您的自定义控件try 的手势识别器出现了一些问题.我想提供一种替代使用点击手势识别器的方式,如我链接的答案中所示.我个人的 idea 是使用一个实际的按钮作为底层,这样你就可以同时拥有ClickedPressed个活动.然后,作为定制按钮的一部分,XAML只需在按钮顶部覆盖ImageLabel即可.

demo of clicked response

LabelImage控件可能对截取按钮手势不感兴趣,但出于谨慎考虑,我将InputTransparent="True"设置为两者.内部控件将绑定到Frame的两个标准属性(例如,按钮将跟踪Frame.CornerRadius),但我们也可以在后面的代码中引入自定义的可绑定属性,例如框架通常不会公开的ImageMarginImageSource.


ButtonEx

这段代码(分为两部分)将生成一个定制的扩展<controls:ButtonEx>,它可以(例如)替换为毛伊岛默认MainPage中的<Button>,具有ClickedPressed个事件,并展示了公开定制的可绑定属性(如ImageMargin)如何帮助"拨入"您想要的行为.

<?xml version="1.0" encoding="utf-8" ?>
<Frame 
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:controls="clr-namespace:net_8_image_buttons.Controls"
    x:Class="net_8_image_buttons.Controls.ButtonEx"
    Padding="0"
    CornerRadius="10">
    <Grid
        ColumnDefinitions="Auto,*">
        <!--Pull properties down from the wrapper for individual controls-->
        <Button         
            x:Name="GestureRecognizerEx"
            Grid.ColumnSpan="2"
            HorizontalOptions="Fill"
            VerticalOptions="Fill"
            BackgroundColor="Transparent"
            CornerRadius="{Binding Path=CornerRadius, Source={RelativeSource AncestorType={x:Type controls:ButtonEx}}}"
            BorderColor="{Binding Path=BorderColor, Source={RelativeSource AncestorType={x:Type controls:ButtonEx}}}"
            BorderWidth="{Binding Path=BorderWidth, Source={RelativeSource AncestorType={x:Type controls:ButtonEx}}}"/>
        <Image 
            WidthRequest="50"
            Source="{Binding Path=ImageSource, Source={RelativeSource AncestorType={x:Type controls:ButtonEx}}}"
            Margin="{Binding Path=ImageMargin, Source={RelativeSource AncestorType={x:Type controls:ButtonEx}}}"
            InputTransparent="True"/>   
        <Label         
            Grid.Column="0"
            Grid.ColumnSpan="2"
            Text="{Binding Path=Text, Source={RelativeSource AncestorType={x:Type controls:ButtonEx}}}"         
            TextColor="{Binding Path=TextColor, Source={RelativeSource AncestorType={x:Type controls:ButtonEx}}}"        
            VerticalOptions="Center" 
            HorizontalOptions="Center"
            InputTransparent="True"/>
    </Grid>
</Frame>

Custom Bindable Properties

您可以使ButtonEx的行为更像(或更少)Button,具体取决于您 Select 公开的自定义属性.

public partial class ButtonEx : Frame
{
    public ButtonEx()
    {
        InitializeComponent();
        GestureRecognizerEx.Clicked += (sender, e) => Clicked?.Invoke(this, e);
        GestureRecognizerEx.Pressed += (sender, e) => Pressed?.Invoke(this, e);
    }
    public static readonly BindableProperty TextProperty =
        BindableProperty.Create(nameof(Text), typeof(string), typeof(ButtonEx), default(string));

    public string Text
    {
        get => (string)GetValue(TextProperty);
        set => SetValue(TextProperty, value);
    }

    public static readonly BindableProperty ImageSourceProperty =
        BindableProperty.Create(nameof(ImageSource), typeof(ImageSource), typeof(ButtonEx), default(ImageSource)); 
    
    public static readonly BindableProperty TextColorProperty =
        BindableProperty.Create(nameof(TextColor), typeof(Color), typeof(ButtonEx), default(Color));

    public Color TextColor
    {
        get => (Color)GetValue(TextColorProperty);
        set => SetValue(TextColorProperty, value);
    }

    public static readonly BindableProperty BorderWidthProperty =
        BindableProperty.Create(nameof(BorderWidth), typeof(double), typeof(ButtonEx), default(double));

    public double BorderWidth
    {
        get => (double)GetValue(BorderWidthProperty);
        set => SetValue(BorderWidthProperty, value);
    }

    public ImageSource ImageSource
    {
        get => (ImageSource)GetValue(ImageSourceProperty);
        set => SetValue(ImageSourceProperty, value);
    }
    public static readonly BindableProperty ImageMarginProperty =
        BindableProperty.Create(nameof(ImageMargin), typeof(Thickness), typeof(ButtonEx), default(Thickness));

    public Thickness ImageMargin
    {
        get => (Thickness)GetValue(ImageMarginProperty);
        set => SetValue(ImageMarginProperty, value);
    }
    public event EventHandler? Clicked;
    public event EventHandler? Pressed;
}

MAUI MainPage

<VerticalStackLayout
    Padding="30,0"
    Spacing="25">
    <Image
        Source="dotnet_bot.png"
        HeightRequest="185"
        Aspect="AspectFit"
        SemanticProperties.Description="dot net bot in a race car number eight" />

    <Label
        Text="Hello, World!"
        Style="{StaticResource Headline}"
        SemanticProperties.HeadingLevel="Level1" />

    <Label
        Text="Welcome to &#10;.NET Multi-platform App UI"
        Style="{StaticResource SubHeadline}"
        SemanticProperties.HeadingLevel="Level2"
        SemanticProperties.Description="Welcome to dot net Multi platform App U I" />

    <controls:ButtonEx
        x:Name="CounterBtn"
        SemanticProperties.Hint="Counts the number of times you click"
        HorizontalOptions="Fill"
        Text="Click me" 
        TextColor="{StaticResource Primary}"
        BackgroundColor="{StaticResource Secondary}"
        Clicked="OnCounterClicked"
        ImageSource="dotnet_bot.png"
        ImageMargin="10,0,0,0"
        BorderColor="Fuchsia"
        BorderWidth="1"/>
</VerticalStackLayout>

Csharp相关问答推荐

如何捕获对ASP.NET核心应用程序的所有请求并将其发送到一个页面

Automapper 12.x将GUID映射到字符串

我如何让我的秒表保持运行场景而不重置

NET8 Maui&;iOS:AppCenter崩溃错误

KeyDown从我的文本框中删除输入,如何停止?

如何在使用Google.Drive.apis.V3下载文件/文件夹之前压缩?

WPF如何获取有关从一个视图模型更改另一个视图模型的信息

仅在Blazor Web App中覆盖生产的基本路径(.NET8中的_Hosts.cshtml文件功能?)

在C#和HttpClient中使用REST API

身份验证中间件如何处理多个方案

我应该使用IMhemyCache来存储承载令牌,还是应该为Azure函数中的401个错误实施Polly重试策略?

在Word Open OpenXML c#上应用葡萄牙语字符Times New Roman时出错

在素数排序数组中,arr找到arr中最小数的索引i,使得arr[i]除以给定的数

序列化和反序列化ASP.NETCore.NET 6 C#App中的泛型对象

Windows Forms(.NET)中文件对话框中的深色模式差异

未调用Blazor MudForm验证函数,因为最初未显示MudTextField

最小API BindAsync没有';不工作.Net 6

为什么ItemsControl中的所有文本框都使用最后一个动态添加的ValidationRule?

如何在执行同步操作时不阻塞 WinForms 应用程序中的 UI 线程

如何在不使用暴力方法的情况下找到具有哈希冲突的三个不同字符串?