Put a WPF button just after a label

270 Views Asked by At

I have an WPF usercontrol which contains following grid.

<Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="auto"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="auto"/>
            <ColumnDefinition Width="auto"/>
        </Grid.ColumnDefinitions>

        <Image Grid.Column="0" 
               Width="24"
               Height="24"
               Margin="8"
               Visibility="{Binding Path=IsVisible, Converter={StaticResource InvertBoolToVisibility}}"
               Source="{Binding Path=MyIcon}"/>
        
        <Label Grid.Column="1"
               VerticalAlignment="Center"
               VerticalContentAlignment="Center"
               HorizontalContentAlignment="Stretch"
               HorizontalAlignment="Stretch"
               Height="Auto"
               Margin="5"
               Foreground="{Binding Path=ForegroundColor}">
            <TextBlock Text="{Binding Path=Text}" TextWrapping="Wrap"/>
        </Label>

        <Button Grid.Column="2"
                Width="80"
                Height="28"
                VerticalAlignment="Center"
                HorizontalAlignment="Left"
                VerticalContentAlignment="Center"
                HorizontalContentAlignment="Center"
                Margin="5,5,30,5"
                Padding="5"
                Content="Remove All"
                Foreground="Red"
                Visibility="{Binding Path=IsVisible, Converter={StaticResource BoolToVisibility}}"
                Click="RemoveAll_Click"/>

        <Image Grid.Column="3"
               Width="36"
               Height="36"
               Margin="8,2"
               Visibility="{Binding Path=IsVisible, Converter={StaticResource InvertBoolToVisibility}}"
               Source="{Binding Path=MyLogo}" />
    </Grid>

The problem with above grid is that button is not placed just after the Label content, instead when label content is short there is a huge space between the label content and the button.

I would like to put the button just after the label content, I don't want any space between label and button. How can I do this?

See below screenshot to see what's happening (each time I resize the window to right, there is more space between label and button):

enter image description here

I need the button to always keep on the right of the label (this is already working),

2

There are 2 best solutions below

2
JonasH On

I would usually use a StackPanel when I want things directly after one another. I.e. put a stackpanel into the grid, and put both the label and the button into the stackpanel. Don't forget to set the orientation of the stackpanel. This assumes you do not want the button to align with anything else.

Another approach would be to use another column for filling any remaining space. Currently your column 1 is set to size " * ", i.e. fill any remaining space. If you change it to auto and move the " * " to some other column, possibly a empty column, you should remove the space between the button and label.

0
Ai Zhang-MSFT On

Rodri. For making the button always be next to the label and not be squeezed out of the window. You could refer to the steps and code below.

  1. Change the width of the second column to auto.

  2. TextBox is used to update properties in Label(TextBlock).

  3. Set MaxWidth for the label, and it will wrap as the text increases.

    <Grid Width="700">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="auto"/>
        <ColumnDefinition Width="auto"/>
        <ColumnDefinition Width="auto"/>
        <ColumnDefinition Width="auto"/>
    </Grid.ColumnDefinitions>
    <Label Grid.Column="1"
           MaxWidth="300"
           Background="LightBlue" Height="80" >
        <TextBlock Text="{Binding MyText,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Background="AliceBlue" Grid.Column="0" Height="80"  TextWrapping="Wrap"/>
    </Label>
    
    <Button Grid.Column="2"
            Width="80"
            Height="28"
            VerticalAlignment="Center"
            HorizontalAlignment="Left"
            VerticalContentAlignment="Center"
                            HorizontalContentAlignment="Center"
                            Margin="5,5,30,5"
            Padding="5"
            Content="Remove All"
            Foreground="Red"    Click="Button_Click"/>
    <TextBox Text="{Binding MyText,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Background="AliceBlue" Grid.Column="3" Height="80" />       
      </Grid>
    
    
    
    public partial class MainWindow : Window, INotifyPropertyChanged
                 {
              public MainWindow()
                   {
              InitializeComponent();
               DataContext = this;
         }
    
    public event PropertyChangedEventHandler? PropertyChanged;
    
    private void Button_Click(object sender, RoutedEventArgs e)
    {
    
    }
    public string myText { get; set; } = "hello";
    public string MyText
    {
        get { return myText; }
        set
        {
            myText = value;
            OnPropertyChanged();
        }
    }
    protected void OnPropertyChanged([CallerMemberName] string name = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    }
    

    }