wpfxamluser-interfacewpf-positioning

XAML- How to fix the position of an image relative to the right hand side of the display window?


I am developing an application for which the GUI is being written/ displayed using XAML. I have most of the desired elements displayed on the GUI at the moment, and am now working on the layout- positioning the various elements in particular places.

Most of the controls/ buttons, etc are aligned to the left, and stay 'bound' to the left hand side of the GUI even if I resize the window by dragging its left hand edge further to the left (the icons, etc move to stay their relative distance from the edge of the window).

However, I have one element which I want to align to the right, so that it will stay 'bound' to the right hand side of the GUI- if I resize the window by dragging its right hand edge further to the right, it should move to stay its relative distance from the edge of the window... at the moment, that element is staying at the position that I have drawn it (i.e. 900 pixels from the left), no matter what the size of the window is- so if I resize the width of the window to less than 900 pixels, that element cannot be seen.

The XAML markup I have used for the elements that I want bound to the left hand side of the GUI is, for example:

<Button Style="{DynamicResource NoChromeButton}" Click="backBtn_Click" Margin="0, 0, 0, 0" HorizontalAlignment="Left" >
    <Image Source="C:\...\abc.png" Height="30" Width="40" />
</Button>    

The XAML markup that I am trying to use for the element I want bound to the right hand side of the GUI is:

<Button Style="{DynamicResource NoChromeButton}" Click="referThis" Margin="0, 0, 0, 0" HorizontalAlignment="Right" >
    <TextBlock>Button XYZ</TextBlock>
</Button>

However, setting the HorizontalAlignment to Right, doesn't actually move the text button to the right- it's still bound to the left hand side of the display... The only way I have found of moving it towards the right, is to set a large value for its 'x' position, i.e. Margin="900, 0, 0, 0", but then the position is not relative to the size of the window, so if I drag the right hand edge too far to the left, that button is outside the displayed area of the window, so I can't see it...

How I can I set the property of the button so that its position is relative to the right hand edge of the display window?

Edit

All of the elements in question are displayed inside the same <Grid> and <StackPanel> tags, i.e.

<StackPanel>
    <Grid ...>
        <Button ... HorizontalAlignment="Left">
        </Button>
        ...
        <Button ... HorizontalAlignment="Right">
        </button>
        ...
    </Grid>
    ...
</StackPanel>

Solution

  • The basic idea of the following solution is the Grid.

    Create a ColumnDefinition with fixed width for each element you want aligned to the left, and a ColumnDefinition with fixed width for each element you want aligned to the right. On the middle, create a ColumnDefinition with a Width="*", so WPF first calculates the size of the other columns, based on their fixed length, and then it fills the remaining space with the middle-column. Remember that each button has to set the Grid.Column property correctly to declare the column it wants to belong to.

    As you resize the Window, the Grid updates its layout and the flexible children. In this case, the only flexible child is the middle-column.

    Here's a simple implementation:

      <Grid>
        <Grid.ColumnDefinitions>
          <ColumnDefinition Width="auto"/>
          <ColumnDefinition Width="auto"/>
          <ColumnDefinition Width="*"/>
          <ColumnDefinition Width="auto"/>
          <ColumnDefinition Width="auto"/>
        </Grid.ColumnDefinitions>
    
        <Grid.Resources>
          <Style TargetType="{x:Type Button}">
            <Setter Property="Width" Value="100"/>
            <Setter Property="Height" Value="30"/>
            <Setter Property="Margin" Value="10"/>
          </Style>
        </Grid.Resources>
    
        <Button Grid.Column="0" Content="Button1Left"/>
        <Button Grid.Column="1" Content="Button2Left"/>
        <Button Grid.Column="3" Content="Button1Right"/>
        <Button Grid.Column="4" Content="Button2Right"/>
    
      </Grid>
    

    For more complete tutorials about the Grid control, check this, this and this.

    Notice that I've set a simple style for the buttons with certain dimensions and margins only to make clear the result, but you can use your own style.