0

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),

Willy
  • 9,848
  • 22
  • 141
  • 284
  • Make the second column width = auto and the third column width to `*` – MindSwipe Jul 21 '22 at 12:34
  • @MindSwipe I tried this and this is what is happening: if a resize window to the left, by reducing window width, then button is being cut-off. If the Label content is too long, then button disappears and it goes out. – Willy Jul 21 '22 at 12:44
  • Don't wrap a TextBlock into a Label. Either add text directly to the Content of the Label or if you are concerned with performance use the TextBlock instead of the Label. – BionicCode Jul 21 '22 at 13:21
  • @BionicCode I need to wrap a TextBlock into a label so the text can be wrapped and not cut-off. – Willy Jul 21 '22 at 13:59

2 Answers2

0

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.

JonasH
  • 28,608
  • 2
  • 10
  • 23
  • Doing your approach using another empty column and changing column 1 size to auto and the new empty column to *, the following problem appears: if a resize window to the left (dragging right side of the window), by reducing window width, then button is being cut-off. If the Label content is too long, then button disappears and it goes – Willy Jul 21 '22 at 14:00
  • @Rodri If the window size is smaller than the content, then *something* is going to be cut of. unless you use a wrap panel or some other method for rearranging the layout depending on window size. You may be able to mitigate some of it by setting min/max sizes of your controls. – JonasH Jul 21 '22 at 14:33
0

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));
    }
    

    }