我正在为 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
属性也没有帮助。它只是调整文本和图像之间的间距。
较小的图像可能是一个解决方案,但更改此问题的所有资产并不是一个好方法。我们需要这些不同规模的资产。
这个问题有什么解决办法吗?任何想法表示赞赏,谢谢!
您的评论表明您的自定义控件尝试的手势识别器存在一些问题。我想提供使用
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;
}