2

A Button contains a Grid. The structure is like the follows:

<Button>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="3*"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <Viewbox Grid.Column="0">
            <TextBlock></TextBlock>
        </Viewbox>

        <Viewbox Grid.Column="1">
            <TextBlock></TextBlock>
        </Viewbox>
    </Grid>
</Button>

The problem is that the TextBlocks position aren't fixed, so you can see the following situation, where the gridline is moved to the right when the text on left becomes longer. How to make the TextBlocks position fixed inside the grid cell (so the middle grid line stays regardless of the text length)?

enter image description here


EDIT: The above XAML will fix the positons of the TextBlocks as it is, but will not work when the Grid is inside a button. Images below of a Grid with blue background on a silver button: we can see the grid line changes as the text changes (while the ratio stays the same?) primarily because the Grid occupies different region of the Button.

So guess my real question is: How to make the Grid occupy the entire Button? (if the grid stays fixed, so does its grid line.)

enter image description here enter image description here


EDIT2: Below is the code that generates the Button, Grid, Viewbox, TextBlock structure represented by the above XAML. This code generates the Buttons as shown below, where the green Grid does not stretch to the entire blue Button and its occupied area differs based on its content. Setting Grid's properties as g.HorizontalAlignment = HorizontalAlignment.Stretch; g.VerticalAlignment = VerticalAlignment.Stretch; doesn't work.

enter image description here

Button b = new Button();
b.Background = Brushes.DeepSkyBlue;

Grid g = new Grid();
g.Name = "grid";
g.ShowGridLines = true;
g.Background = Brushes.LimeGreen;
g.HorizontalAlignment = HorizontalAlignment.Stretch;
g.VerticalAlignment = VerticalAlignment.Stretch;

//create columns
for (int i = 0; i < 2; i++)
{
    int len = i == 0 ? 3 : 1;
    ColumnDefinition cd = new ColumnDefinition();
    cd.Width = new GridLength(len, GridUnitType.Star);
    g.ColumnDefinitions.Add(cd);
}


//viewbox col 0
Viewbox vb = new Viewbox();
TextBlock tb1 = new TextBlock();
vb.Child = tb1;
Grid.SetRow(vb, 0);
Grid.SetColumn(vb, 0);
g.Children.Add(vb);

//viewbox col 1
Viewbox vb2 = new Viewbox();
TextBlock updown = new TextBlock();
vb2.Child = updown;
//specify the Marlett Font
updown.Style = (Style)Application.Current.FindResource("updownBlock");
Grid.SetRow(vb2, 0);
Grid.SetColumn(vb2, 1);
g.Children.Add(vb2);

//add grid to button
b.Content = g;
totoro
  • 3,257
  • 5
  • 39
  • 61

4 Answers4

1

this should help

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

    <Viewbox Grid.Column="0">
        <TextBlock></TextBlock>
    </Viewbox>

    <Viewbox Grid.Column="1">
        <TextBlock></TextBlock>
    </Viewbox>
</Grid>

using this example, grid will allot the required space to right column first and then remaining space will be given to left column.

I also removed the row definition as 1 row with * height is the default for grid


EDIT

in order to distribute the space based weighted proportion of available space you may define the weight in star values to both of the columns

<Grid.ColumnDefinitions>
    <ColumnDefinition Width="3*"/>
    <ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>

In above example grid will render left column 3 times bigger then the right column which will be rendered in 1/4 of the total space.


EDIT

set HorizontalContentAlignment="Stretch" & VerticalContentAlignment="Stretch" on the button so that the Grid can occupy whole space, by default it is Center.

pushpraj
  • 13,458
  • 3
  • 33
  • 50
  • thanks, this works. but now the right column becomes huge and left is tiny. How to specify the right column to take exactly 1/4 width of the grid regardless of the content of the left? – totoro Oct 16 '14 at 04:06
  • 1
    For exactly 1/4 width you can use that markup: – Ivan Zub Oct 16 '14 at 04:39
  • isn't `` same as ``? this seems to work with just the Grid, but doesn't work when the `Grid` is inside a `Button`. I'll update the question with more images. – totoro Oct 16 '14 at 05:27
  • 1
    @green, could you also post some sample code?, you may set `HorizontalContentAlignment="Stretch"` on the button so that the grid occupy whole space. – pushpraj Oct 16 '14 at 06:25
  • @pushpraj I'ved tried `Stretch`, but no use. (isn't that the default option?) My buttons are generated in C#, but the latter 2 images are just `Grid` inside a `Button` in XAML. I'll edit the question to include that. – totoro Oct 16 '14 at 06:51
  • @green, Could you please share some code for button generation? – pushpraj Oct 16 '14 at 09:25
  • @pushpraj I just added the code, which produces the same thing as the XAML. I made the background color of the Grid different from that of the Button, so it's easy to see the problem. – totoro Oct 17 '14 at 03:50
  • @pushpraj sorry I misread your previous `HorizontalContentAlignment` as simply `HorizontalAlignment`, which did solve my problem eventually. Would you add it to your answer so I can accept it as the solution? thanks! – totoro Oct 17 '14 at 04:07
  • Try use Button.Template as advised here http://stackoverflow.com/questions/31647009/how-to-get-button-content-to-fill-width-in-wpf – Robert Cutajar Mar 29 '16 at 09:52
1

Instead of setting the Grid's Alignment, setting the Button's ContentAlignment finally did the trick

b = new Button();
b.HorizontalContentAlignment = HorizontalAlignment.Stretch;
b.VerticalContentAlignment = VerticalAlignment.Stretch;

Now the gridline stays regardless of length of the content :)

enter image description here

totoro
  • 3,257
  • 5
  • 39
  • 61
  • Awesome! I'm very glad to find your post.:) I've been trying to position image on the left side of a button for a while. – Louis Oct 28 '16 at 16:12
0

Your ColumnDefinition width is 3 and *. * indicates all of the available space, also your textbox or Grid'd width does not seems to be fixed hence it is but obvious that textbloxk's position will change.

Possible steps you can take: 1. Set ColumnDefinition width="Auto" 2. Set the width of textblock and the parent Grid

Arushi Agrawal
  • 619
  • 3
  • 10
0

Buttonobject.HorizontalContentAlignment = HorizontalAlignment.Stretch; Buttonobject.VerticalContentAlignment = VerticalAlignment.Stretch;

Stretch property will make the content aligned to the button's grid