H4mm3rHead
H4mm3rHead

Reputation: 573

Centering a WPF control

I have a window where I add a new UserControl to (with an image), I simply want to center the control in the middle of the screen (both vertically and horizontally). I can only get the vertical one to work. I'm gonna swap content in the DockPanel from my CodeBehind and want to show this startup screen before I start doing my slideshow UI, this means that the content is set from the CodeBehind.

My Window:

<Window x:Class="GreenWebPlayerWPF.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="512" Width="853" WindowStyle="None" WindowState="Maximized" WindowStartupLocation="CenterScreen">
    <DockPanel Width="Auto" Height="Auto" Name="TransitionContainer" Background="Black" Margin="0" LastChildFill="True"></DockPanel>
</Window>

My UserControl:

<UserControl x:Class="GreenWebPlayerWPF.FrontPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <DockPanel Background="Black">
        <Image Name="image1" Stretch="None" Source="/GreenWebPlayerWPF;component/gw.png" />
    </DockPanel>
</UserControl>

Please note that I'm using maximized/full screen.

Upvotes: 12

Views: 19789

Answers (3)

MeTitus
MeTitus

Reputation: 3428

It's quite an old one, but centring a control is now as simple as:

<Grid VerticalAlignment="Stretch" HorizontalAlignment="Stretch">

    <StackPanel VerticalAlignment="Center" HorizontalAlignment="Center" Height="350" Width="600">
        <TextBox />
    </StackPanel>

</Grid>

Upvotes: 1

pasx
pasx

Reputation: 2975

I keep running into this problem when trying to center elements on the page. The problem with the StackPanel is that HorizontalAlignment has no effect when the Orientation is Horizontal and VerticalAlignment no effect when Orientation is Vertical. So you keep banging your head trying to set values with no effect. It is not illogical that it works this way but it would be good if this was reported as an error.

The solution I found is to have two imbricated StackPanels one centered horizontally and the other vertically as shown below. Finding the size of the parent is needed to size the intermediate panel otherwise it would be flat and its content hidden - an absolute value would work as well. Although not a panacea itis a bit less verbose than using a grid.

<StackPanel Background="Bisque" Orientation="Vertical" Width="300" Height="300" >
    <StackPanel HorizontalAlignment="Center"  Orientation="Horizontal"
                  Height="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=StackPanel}, Path=ActualHeight}">
        <StackPanel VerticalAlignment="Center" Width="200" Height="60" Background="Blue">
        </StackPanel>
    </StackPanel>
</StackPanel>

Upvotes: 4

Pavel Minaev
Pavel Minaev

Reputation: 101565

Use a Grid:

  <Grid>  
    <Grid.ColumnDefinitions>
      <ColumnDefinition Width="*"/>
      <ColumnDefinition Width="Auto"/>
      <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
      <RowDefinition Height="*"/>
      <RowDefinition Height="Auto"/>
      <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <!-- Replace with your UserControl -->
    <Button Content="Foo" Grid.Column="1" Grid.Row="1"/>
  </Grid>

You can dock it inside your DockPanel (if you must have a DockPanel there) to stretch. And, of course, while the above is all markup, you can just as easily create such a grid from code.

Upvotes: 23

Related Questions