Forum Xamarin.Forms

Announcement:

The Xamarin Forums have officially moved to the new Microsoft Q&A experience. Microsoft Q&A is the home for technical questions and answers at across all products at Microsoft now including Xamarin!

To create new threads and ask questions head over to Microsoft Q&A for .NET and get involved today.

How to set Padding of Button

zapzqczapzqc USMember ✭✭
edited August 2014 in Xamarin.Forms

I want to discrease the distance between text and border。How?
And I found that the smallest size of button is 80*40?Right? When I set HeightRequest = "20" ,the text of Button display incomplete.

Posts

  • CraigDunnCraigDunn USXamarin Team Xamurai

    Which platform/s are you testing on? The display of the button will vary slightly due to the default sizing and font metrics on each platform. Can you provide screenshots to explain what you want to achieve?

    There is no way to control the space between the text and button edges in Xamarin.Forms by setting a 'padding' property, because it does not exist.

    You could write a custom renderer for the platforms where you want to tweak the layout, and manually manage the sizing in the renderer.

  • zapzqczapzqc USMember ✭✭
    edited August 2014

    Thank you . I resolved it.

    Android.
    the code is

    See the picture ,the first one ,I write a custom renderer ,set padding = "0", the second one is Xamarin.Forms's default style. You can see the space between the text and button edges is wide.

    protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { base.OnElementPropertyChanged(sender, e); var view = (ExtendedButton)this.Element; var nativeButton = (global::Android.Widget.Button)this.Control; nativeButton.SetPadding((int)view.Padding.Left, (int)view.Padding.Top, (int)view.Padding.Right, (int)view.Padding.Bottom); }

    1.png 2.2K
  • KeithRoweKeithRowe USMember
    edited February 2015

    So there is no way to do button text padding without doing a custom renderer? I guess that's what you said explicitly :) Sorry, and can't delete the comment...

  • AmitSingh6789AmitSingh6789 USMember

    no sir

  • hvaughanhvaughan USMember ✭✭✭

    @KeithRowe @zapzqc
    Was looking for this myself and found the post below which mentions a completely simple solution. Just set a good WidthRequest. I set mine in my ContentView's SizeChanged:

    ContentView.xaml.cs:

    SizeChanged += (sender, args) => {
        YesButton.WidthRequest = Width * 0.4;
        NoButton.WidthRequest  = Width * 0.4;
    };
    

    ContentView.xaml:

    <Button x:Name="NoButton"
            Text="No"
            BorderWidth="1"
            BorderColor="Blue"
            Clicked="OnClicked"
            CommandParameter="No"
            HorizontalOptions="Center"
            Grid.Row="3" Grid.Column="2"/>
    

    Source:
    https://forums.xamarin.com/discussion/comment/109669/#Comment_109669

  • ErkanGozukucukErkanGozukucuk USMember ✭✭

    @KeithRowe said:
    So there is no way to do button text padding without doing a custom renderer? I guess that's what you said explicitly :) Sorry, and can't delete the comment...

    You can do like this:
    <StackLayout> <StackLayout Padding="10,0,10,0"> <Button Text="MyButton"></Button> </StackLayout> </StackLayout>

  • SylvainGravelSylvainGravel CAMember ✭✭
    edited December 2016

    @ErkanGozukucuk said:

    @KeithRowe said:
    So there is no way to do button text padding without doing a custom renderer? I guess that's what you said explicitly :) Sorry, and can't delete the comment...

    You can do like this:
    <StackLayout> <StackLayout Padding="10,0,10,0"> <Button Text="MyButton"></Button> </StackLayout> </StackLayout>

    This doesn't really achieve the desired effect if you use a background color and/or want rounded corners. Here is my take on things, slightly more performant than the StackLayout and using an effect to get the rounded corners back.

    <ContentView Grid.Row="1" Grid.Column="0"
                             HorizontalOptions="Center"
                             Padding="3, 0, 3, 0"
                             BackgroundColor="{StaticResource MainOrange}">
        <Button Margin="0, 0, 0, 0"/>
    
        <ContentView.Effects>
            <effects:RoundedBorderViewEffect CornerRadius="3"/>
        </ContentView.Effects>
    </ContentView>
    
    

    And the Effect

    [assembly:ExportEffect (typeof(RoundedBorderViewEffect), nameof(RoundedBorderViewEffect))]
    namespace App.iOS.Views.Effects
    {
        class RoundedBorderViewEffect : PlatformEffect
        {
            private View _SharedView => Element as View;
            private UIView _NativeView => Control ?? Container;
            private PCL.Views.Effects.RoundedBorderViewEffect _Effect => Element.Effects.FirstOrDefault(e => e is PCL.Views.Effects.RoundedBorderViewEffect) as PCL.Views.Effects.RoundedBorderViewEffect;
    
            protected override void OnAttached()
            {
                if (_SharedView != null)
                {
                    _SharedView.PropertyChanged += SharedControlPropertyChanged;
                }
    
                _NativeView.Layer.CornerRadius = (nfloat)_Effect.CornerRadius;
                _NativeView.Layer.MasksToBounds = true;
            }
    
            protected override void OnDetached()
            {
                if (_SharedView != null)
                {
                    _SharedView.PropertyChanged -= SharedControlPropertyChanged;
                }
            }
    
            private void SharedControlPropertyChanged(object sender, PropertyChangedEventArgs args)
            {
            }
        }
    }
    
  • JonahKunzJonahKunz USMember ✭✭

    Here is a but of a hack for XAML if you want. It just stacks a label on top of a button inside of a grid.
    <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" /> </Grid.ColumnDefinitions> <Label Text="{Binding AdjustmentDescription}" VerticalTextAlignment="Center" Grid.Column="0" Margin="5,0" /> <Label Text="{Binding DollarAmount}" Grid.Column="1" VerticalTextAlignment="Center" /> <Button BackgroundColor="White" BorderColor="Black" BorderWidth="1" HorizontalOptions="End" WidthRequest="50" HeightRequest="30" Command="{Binding BindingContext.DeleteAdjustment, Source={x:Reference Name=BidWindow}}" CommandParameter="{Binding AdjustmentID}" Margin="3" Grid.Column="2" /> <Label Text="X" InputTransparent="True" Grid.Column="2" Margin="3" HeightRequest="30" WidthRequest="50" FontSize="Large" FontAttributes="Bold" VerticalTextAlignment="Center" HorizontalTextAlignment="Center" /> </Grid>

  • ClayMartinClayMartin USUniversity ✭✭

    @NickKovalsky, extending your solution a bit (this is far from perfect):

    public class ButtonWithPadding : Button
    {
    #region Padding

        public static BindableProperty PaddingProperty = BindableProperty.Create(nameof(Padding), typeof(Thickness), typeof(ButtonWithPadding), default(Thickness), defaultBindingMode: BindingMode.OneWay);
    
        public Thickness Padding
        {
            get { return (Thickness)GetValue(PaddingProperty); }
            set { SetValue(PaddingProperty, value); }
        }
    
        #endregion Padding
    
        //logic flags
        private bool _measured = false;
        private bool _self = false;
    
        protected override SizeRequest OnMeasure(double widthConstraint, double heightConstraint)
        {
            if (!_self) _measured = true;
            return base.OnMeasure(widthConstraint, heightConstraint);
        }
    
        protected override void OnSizeAllocated(double width, double height)
        {
            base.OnSizeAllocated(width, height);
    
            if (_measured)
            {
                _measured = false;
                _self = true;
    
                double totalWidthPadding = 0;
                double totalHeightPadding = 0;
                if (Padding != null)
                {
                    totalWidthPadding = Padding.Left + Padding.Right;
                    totalHeightPadding = Padding.Top + Padding.Bottom;
                    WidthRequest = width + totalWidthPadding;
                    HeightRequest = height + totalHeightPadding;
                }
                else
                {
                    WidthRequest = width + 12; // Your width padding * 2 
                }
            }
            else
            {
                _self = false;
            }
        }
    
    
    }
    
  • Johannd10Johannd10 Member

    The better solution for me :
    public class CustomButton : Button
    {
    public static readonly BindableProperty PaddingProperty = BindableProperty.Create(nameof(Padding), typeof(Thickness), typeof(Button), default(Thickness));

            public Thickness Padding
            {
                get => (Thickness)this.GetValue(PaddingProperty);
                set => this.SetValue(PaddingProperty, value);
            }
        }
    

    Renderer IOS :
    [assembly: ExportRenderer(typeof(CustomButton), typeof(CustomButtonRenderer))]
    namespace XXX
    {
    public class CustomButtonRenderer : ButtonRenderer
    {
    protected override void OnElementChanged(ElementChangedEventArgs e)
    {
    base.OnElementChanged(e);

                if (this.Control == null || this.Element == null)
                {
                    return;
                }
    
                this.DoChange();
            }
    
            private void DoChange()
            {
                // Padding
                this.Control.ContentEdgeInsets = new UIEdgeInsets(
                    (float)((CustomButton)this.Element).Padding.Top,
                    (float)((CustomButton)this.Element).Padding.Left,
                    (float)((CustomButton)this.Element).Padding.Bottom,
                    (float)((CustomButton)this.Element).Padding.Right);
            }
    }
    

    Renderer Android :
    [assembly: ExportRenderer(typeof(CustomButton), typeof(CustomButtonRenderer))]
    namespace XXX
    {
    public class CustomButtonRenderer : ButtonRenderer
    {
    protected override void OnElementChanged(ElementChangedEventArgs e)
    {
    base.OnElementChanged(e);

                if (this.Control == null || this.Element == null)
                {
                    return;
                }
                this.DoChange();
            }
    
        private void DoChange()
            {
                this.Control.SetPadding(
                    (int)((CustomButton)this.Element).Padding.Left,
                    (int)((CustomButton)this.Element).Padding.Top,
                    (int)((CustomButton)this.Element).Padding.Right,
                    (int)((CustomButton)this.Element).Padding.Bottom);
            }
    }
    
Sign In or Register to comment.