MAUI .NET 8 图像不再适合按钮

问题描述 投票:0回答:1

我正在为 Windows 和 Mac 平台创建一个多平台 MAUI 应用程序。我最近已将项目更新到 .NET 8,但现在按钮遇到了一些问题。按钮中没有用于控制图像大小的属性。在 .NET 7 中,我能够通过更改填充值来控制图像大小。但这不再起作用了。

更新前按钮看起来像这样;

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

这是我当前使用的

XAML
代码;

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

额外信息

  • 我尝试创建自定义控件,但除了按钮控件之外,我们无法定义单击或按下事件。所以,这个解决方案也行不通。

  • 我研究过其他解决方案,但它们都在.NET 8之前得到了解答。以下是我看过的一些问题; 这个这个这个这个这个这个问题。

  • 此外,

    ContentLayout
    属性也没有帮助。它只是调整文本和图像之间的间距。

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

这个问题有什么解决办法吗?任何想法表示赞赏,谢谢!

c# button maui .net-8.0
1个回答
0
投票

您的评论表明您的自定义控件尝试的手势识别器存在一些问题。我想提供使用

TapGestureRecognizer
的替代方案,如我链接的答案所示。我个人的想法是使用实际的按钮作为底层,这样您就可以同时拥有
Clicked
Pressed
事件。然后只需在按钮顶部叠加一个
Image
Label
即可。

Label
Image
控件可能对拦截按钮手势不感兴趣,但出于谨慎考虑,我设置了
InputTransparent="True"
。内部控件将绑定到
Frame
的两个标准属性(例如,按钮将跟踪
Frame.CornerRadius
),但我们也可以在后面的代码中引入自定义可绑定属性,例如框架不会的
ImageMargin
ImageSource
一般都会暴露。

<?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>

自定义可绑定属性

您可以使

ButtonEx
的行为更像(或更少)像
Button
,具体取决于您选择公开的自定义属性。

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;
}
© www.soinside.com 2019 - 2024. All rights reserved.