Open AndreasReitberger opened 2 years ago
it is not needed as you can use GestureRecognizers to achieve command and clicks
it is not needed as you can use GestureRecognizers to achieve command and clicks
Which is much more complicated plus the GestureRecognizer does not work properly, for example #7403 the above proposal already exist in WPF and makes the developer's work much easier. Then it also wouldn't need an extra ImageButton
which is also buggy at the moment.
it is not needed as you can use GestureRecognizers to achieve command and clicks
How should this work out? Just add the GestureRecognizer to a label and make it Button like in style?
I rather prefer to do it like above. This makes it more easier and it also does work like this in WPF.
I do not know how much effort this is, but in my opinion this is the "cleanest" way.
Best, Andreas
it is not needed as you can use GestureRecognizers to achieve command and clicks
It's very limited if other base controls are used - the TapGestureRecognizer only fires an event after the press is complete (finger taken off control). In the App I'm currently working on (where I have custom Templated button control) inherited from a Border class I really need visual/haptic feedback (and command to be executed) on the press action not the release action.
Also it makes total sense to allow for much more powerful customization of buttons OOB too - I think what Syncfusion have done in their Xamarin control set is more along the lines of what devs would regularly need.
Also, GestureRecognizers don't do the pressing and releasing animation of a button
I 100% support this. We need a content button.
Yes please! We need that. Does anyone have a workaround for now ?
@Stratosf Please upvote the post so that it gains priority because .NET GitHub is built on this system.
We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.
I totally agree with @yairp03 and @Symbai, using GestureRecognizers
which was proposed by @VladislavAntonyuk is awful and pretty much a very bad way for archiving this. There're multiple issues, like overlapping other Tap gestures (like scrolling), uncommanded clicks by the user, no feedback for the user (i.e. the animations), and many visual issues.
I mean, you can implement that with some workarounds on Maui side, like putting a BoxView with alpha and making it visible on press and invisible on release, but that is so ugly, specially if buttons like from Android have nice animations.
So, I made a new Control using Handlers. It's not bullet proof nor it works like you could expect, but at least it's a starting point (and a better workaround for now). I didn't implement Windows nor Tizen as I don't work on those platforms, but you should make it work by looking the code and implement it on those sides.
To make it work, just download the zip below (at the end of my comment) and add its content to your solution, then add this lines on MauiProgram.cs
.ConfigureMauiHandlers(handlers =>
{
handlers.AddHandler(typeof(ContentButton), typeof(ContentButtonHandler));
});
(You will need to add the respective namespace, but just use intellisense for that)
Then, add this namespace to the XAML where you'll use the ContentButton:
xmlns:nm="clr-namespace:NotMaui.Controls"
And then, just use the ContentButton like a mix between a ContentView and a Button. E.g.:
<nm:ContentButton BorderColor="Transparent"
BorderWidth="7"
Command="{Binding ButtonClickCommand}">
<nm:ContentButton.Triggers>
<DataTrigger TargetType="nm:ContentButton" Binding="{Binding IsReadyToSubmit}" Value="True">
<Setter Property="BorderColor" Value="{StaticResource Primary}"/>
</DataTrigger>
</nm:ContentButton.Triggers>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0"
VerticalOptions="Center"
Source="{AppThemeBinding Light=add_item.png, Dark=add_item_dark.png}"/>
<VerticalStackLayout Grid.Column="1"
VerticalOptions="Center">
<Label Text="Add Item"/>
<Label Text="{Binding ParentName}"
Style={StaticResource Subtitle}/>
</VerticalStackLayout>
</Grid>
</nm:ContentButton>
You may want to add an default Style, as it'll not consume the default one for the original Button:
<Style TargetType="nm:ContentButton">
<Setter Property="BackgroundColor" Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}" />
<Setter Property="CornerRadius" Value="8"/>
<Setter Property="Padding" Value="14,10"/>
<Setter Property="MinimumHeightRequest" Value="44"/>
<Setter Property="MinimumWidthRequest" Value="44"/>
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray600}}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
I hope my Workaround helps you, and I totally hope that Microsoft use part of my work (which is based on ImageButton, Button, and ContentView, with some resources from the Internet) to implement an official ContentButton. Again, this should be a Must feature 🙏
My reason for wanting this: I need small buttons 25x25 with text in it and MAUI won't display text (of any font size) when button size is 32 or lower. Having a content button would surely have been an easier way to tailor a custom-made button to my needs.
In case anyone wonder why small buttons, let me reassure you it's not for day to day operation by end users. It's meant for a customization mode that allows run-time changes of any text displayed within the app (combined with responsive UI that adjust itself).
MAUI won't display text (of any font size) when button size is 32 or lower
Check if your button have any padding and/or margin larger than zero. You may want this:
<ContentButton Text="hi" WithRequest="25" HeightRequest="25" Padding="0" FontSize="27"/>
It did solve my issue thanks @JPZV but I implemented your solution and works like a charm. I did have to implement a Windows handler to make it work though. Even though I may not have been in need for it this time, I still believe it truly make sense to have a content button.
Also 100% Support this
@VladislavAntonyuk Unfortunately, the way how the button and gesture recognizer work is probably different. Currently, I have a bug that is not present if I use buttons, but using the gesture recognizer the bug appears. As expected, I have to use a gesture recognizer because that only way how can I have content, but I can't, and I am officially screwed. 🐖😬 https://github.com/dotnet/maui/issues/15147
I'm trying to replicate a phone keypad, with the 0
button when long pressed adds a +
,
but with the current state of <Button>
component there's no way to render that +
on the 0
text
Also, Gesture Recognizers don't do the pressing and releasing animation of a button
Totally agree, a button needs a proper press and release animation on all supported platforms. I wonder why this is not an high priority issue, since this is one of the first issues you run into when start to develop UI's.
+1 The Button should definitely have a Content property.
This seems to do the job https://github.com/IeuanWalker/Maui.StateButton
To use a GestureRecognizer with any Panel/Border will also create issues when doing UI Automation tests cause the tools like Appium etc. will not be able to identify the button control easily or in the way it should work. Often also because of that a XPath approach is needed to be used which will slow down UI Test performance drasticly. They will not find the UIButton or android.widget.Button as its supposed to be via the OS Automation Interface and this will result in a lot of work. Creating custom AutomationInterface/Properties for each plattform etc.
Any easy alternative with MAUI would be to create a custom control without handlers where a Button is placed within a custom control and in z-Order a ContentView (with InputTransparent) is above the Maui-Button. Create custom properties in the code behind and bind to it in your pages as needed.
I managed to do a simple custom button with layout, that can use "pressed" and "released" events.
I simply put my button on top of my layout with a transparent background, then add an animation to make it look like a real button, not perfect but very simple.
xaml: `<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Inexpack.Controls.AppButton" x:Name="self">
<Border BackgroundColor="FloralWhite" Margin="2, 5, 2, 0">
<Border.Shadow>
<Shadow Radius="5" Offset="2, 2" Opacity="0.3"/>
</Border.Shadow>
<Grid Padding="5" Margin="0">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Grid.Row="0" Grid.Column="0" Grid.RowSpan="2" Source="{Binding Source={x:Reference self}, Path=ActivityImage}" HeightRequest="50" WidthRequest="50" Margin="0, 0, 0, 0"/>
<Label Grid.Column="1" Grid.Row="0" Text="{Binding Source={x:Reference self}, Path=ActivityName}" FontSize="18" Margin="15, 0, 0, 0"/>
<Label Grid.Column="1" Grid.Row="1" Text="{Binding Source={x:Reference self}, Path=ActivityDescription}" FontAttributes="Italic" FontSize="12" Margin="15, 0, 0, 0"/>
<Button Pressed="Button_Pressed" Released="Button_Released" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Grid.RowSpan="2" BackgroundColor="Transparent" Margin="-10,-10,-10,-10" Clicked="Button_Clicked"/>
</Grid>
</Border>
`
and code behind:
`public partial class AppButton : ContentView {
public delegate void OnAppButtonClicked(string activityName);
public static event OnAppButtonClicked OnAppButtonPressed;
#endregion Public events
#region Properties
public string ActivityName
{
get => (string)GetValue(ActivityNameProperty);
set => SetValue(ActivityNameProperty, value);
}
public ImageSource ActivityImage
{
get => (string)GetValue(ActivityImageProperty);
set => SetValue(ActivityImageProperty, value);
}
public string ActivityDescription
{
get => (string)GetValue(ActivityDescriptionProperty);
set => SetValue(ActivityDescriptionProperty, value);
}
public static readonly BindableProperty ActivityNameProperty = BindableProperty.Create(nameof(ActivityName), typeof(string), typeof(AppButton));
public static readonly BindableProperty ActivityImageProperty = BindableProperty.Create(nameof(ActivityImage), typeof(string), typeof(AppButton));
public static readonly BindableProperty ActivityDescriptionProperty = BindableProperty.Create(nameof(ActivityDescription), typeof(string), typeof(AppButton));
#endregion Properties
public AppButton()
{
InitializeComponent();
}
public AppButton(string activityName, string activityDescription, string activityImage)
{
ActivityName = activityName;
ActivityDescription = activityDescription;
ActivityImage = ImageSource.FromResource(activityImage);
}
private void Button_Clicked(object sender, EventArgs e)
{
OnAppButtonPressed?.Invoke(ActivityName);
}
private async void Button_Pressed(object sender, EventArgs e)
{
await (sender as Button).BackgroundColorTo(Colors.FloralWhite);
}
private async void Button_Released(object sender, EventArgs e)
{
await (sender as Button).BackgroundColorTo(Colors.Transparent);
}
}`
It makes it look almost like a real button, and easiest way to do it in my opinion.
Any news on this one? :)
Description
It would be great to allow the
Button
control to accept not only aText
, but also aContent
orFormattedText
.Public API Changes
Intended Use-Case
In this case, for instance, an icon and a label can be added to the button. Maybe supporting
FormattedText
like on theLabel
control would do the same job (in my case)