我正在为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相关问答推荐

PredicateBuilder不是循环工作,而是手动工作

CS0103 dlibdotnet和www.example.com facerect不在上下文中

在. net毛伊岛窗口的深度链接已经创建""

一种安全的方式来存储SSH凭证(MAUI/C#应用程序)

为什么将鼠标悬停在DateTimeOffset上只显示Hour值?

将轮询与超时同步

MongoDB.NET-将数据绑定到模型类,但无法读取整数值

如何在Windows 11任务调度程序中每1分钟重复一次任务?

我的MRG32k3a算法实现返回的数字超出了预期的[0,1]范围

.NET 8 DI GetServices<;对象&>不工作

如何防止Visual Studio断点以红色突出显示到整行?

WinUI 3中DoubleCollection崩溃应用程序类型的依赖属性

Visual Studio,Docker容器-容器调用:连接被拒绝

仅在ASP.NETCore应用程序中的附加单独端口上公开一组终结点

读取测试项目中的应用程序设置

反编译源代码时出现奇怪的字符

我如何为我的Blazor应用程序构建一个动态教程标注?

无法创建工具窗口(用于VBIDE、VBA的COM加载项扩展)

带有类约束的C#泛型

如何提高C#中比较大 struct 的性能?