iDppma
iDppma

Reputation: 11

How to set a button size regarding the height of its container in XAML?

I am developping a WPF application in XAML. I am a beginner and I have an issue with my button. I need to set its height as a proportion of its container which is a grid. I saw that the height can be set to a value or to "Auto", but I don't know how to say to my button that his height must be 3/4 of the height of the grid in which it is contained.

Does anybody know how to deal with that ? Is it possible to do that with XAML ?

The objective is that when the grid grows, the button grows with it.

Any help would be appreciate.

Thanks

Here is the code I wrote :

<Window x:Class="WpfAppButtonSize.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:WpfAppButtonSize"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800">

<Grid>
    <Grid Height="100" Width="250" HorizontalAlignment="Center" VerticalAlignment="Center">
        <Button Content="Button 1" FontSize="30" Height="75" Width="150"/>
    </Grid>
</Grid>

For the button, instead of Height="75", I would like to say Height=0.75 * Grid Height

Upvotes: 0

Views: 1491

Answers (4)

Julian
Julian

Reputation: 8836

If you give your Grid and your Button a name by specifying the x:Name attribute, you could set the Button's Height in the code behind whenever the Grid's size changes.

XAML

<Grid x:Name="MyGrid">
    <Button x:Name="MyButton" />
</Grid>

MainWindow.xaml.cs

In WPF you could then do this in the code-behind:

public MainWindow()
{
    InitializeComponent();
    
    MyGrid.SizeChanged += (s,e) =>
    {
        if(e.HeightChanged)
        {
            MyButton.Height = MyGrid.Height * 0.75;
        }
    }
}

while in other .NET technologies, such as Xamarin.Forms or .NET MAUI it would have to look like this:

public MainWindow()
{
    InitializeComponent();
    
    MyGrid.PropertyChanged += (s,e) =>
    {
        if(e.PropertyName == nameof(MyGrid.Height))
        {
            MyButton.Height = MyGrid.Height * 0.75;
        }
    }
}

Upvotes: 1

iDppma
iDppma

Reputation: 11

I succeded using the following :

  1. Creating a new class Converters with Convert function

Converters.cs

namespace WpfAppButtonSize 
{
public class Converters : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        double.TryParse((parameter as string).Replace(',', '.'), NumberStyles.Any, CultureInfo.InvariantCulture, out double param);
        return param * (double)value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return true;
    }
}
  1. Bind the actual height of my button to the height of my grid + use the converter as a static resouce and a converter parameter

MainWindow.xaml

<Window.Resources>
    <converter:Converters x:Key="converter" />
</Window.Resources>
    
<Grid>
    <Grid x:Name="MyGrid" Height="100" Width="250" HorizontalAlignment="Center" VerticalAlignment="Center">
        <Button x:Name="MyButton" Content="Button 1" FontSize="30" Width="150" Height="{Binding ElementName=MyGrid, Path=ActualHeight, Converter={StaticResource converter}, ConverterParameter=0.75}" />
    </Grid>
</Grid>
**And dont forget to add the converter namespace to the xaml :**
xmlns:converter="clr-namespace:WpfAppButtonSize"

The following post also helped me : XAML Binding to a converter

Thank you all for your help.

Upvotes: 0

v87
v87

Reputation: 25

You can achieve this using converter and binding "ActualHeight" property of Grid.

<Button Height="{Binding ElementName="mygGrid" Path=ActualHeight, Converter={StaticResource percentageConverter}}"/>

Upvotes: 1

Peregrine
Peregrine

Reputation: 4546

The easiest way is to place the button within its own grid, with rows sized approporiately to generate the spacing.

e.g.

<Grid ...>

    <Grid Grid.Row="???" Grid.Column="???" ...>
        <Grid.RowDefinitions>
            <RowDefinition Height="3*" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
    
        <Button Grid.Row="0" ... />
    </Grid>

</Grid>

Upvotes: 2

Related Questions