WPF: How to specify units in Dialog Units

dpiwindowswpfxaml

i'm trying to figure out how to layout a simple dialog in WPF using the proper dialog units (DLUs).


What's a dialog unit?

A dialog is a unit of measure based on the user's preferred font size.
A dialog unit is defined such that the average character is 4 dialog
units wide by 8 dialog units high:

enter image description here

This means that dialog units:

  • change with selected font
  • changed with selected DPI setting
  • are not square

i spent about two hours dimensioning this sample dialog box from Windows Vista with the various dlu measurements. Can someone please give the corresponding XAML markup that generates this dialog box?

alt text

(Image Link)

Now admittedly i know almost nothing about WPF XAML. Every time i start, i get stymied because i cannot figure out how to place any control. It seems that everything in WPF must be contained on a panel of some kind. There's StackPanels, FlowPanels, DockPanel, Grid, etc. If you don't have one of these then it won't compile.

The only XAML i've been able to come up with (uing XAMLPad) so far:

<DockPanel xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Image Width="23" />
    <Label>Are you sure you want to move this file to the Recycle Bin?</Label>
    <Image Width="60" />
    <Label>117__6.jpg</Label>
    <Label>Type: ACDSee JPG Image</Label>
    <Label>Rating: Unrated</Label>
    <Label>Dimensions: 1072 × 712</Label>
    <Button Content="Yes" Width="50" Height="14"/>  
    <Button Content="Cancel" Width="50" Height="14"/>  
</DockPanel>

Which renders as a gaudy monstrosity. None of the controls are placed or sized right. i cannot figure out how to position controls in a window, nor size them properly.

Can someone turn that screenshot into XAML?

Note: You're not allowed to measure the screenshot. All the Dialog Unit (dlu) widths and heights are specified.

Note: 1 horizontal DLU != 1 vertical DLU. Horizontal and vertical DLUs are different sizes.


See also

Bump: 6/20/2011

Best Solution

The following XAML will give you the effect you are looking for.

Note that I have doubled the DLU units in the markup - thus keeping the same aspect. It looked funny having a Button height of 14units. You may need to tinker with the figures presented in the market.

Also, I started to remove some of the "Vista Layout" into separate styles. You may be able to continue down this path so you have quite a reusable set of styles which follow the Vista guidelines. I'm fairly sure some other people have done something similar.

Furthermore, I took some liberties with the size of the dialog. You mentioned you wanted 210x96units - you would need to set this amount, plus the window chrome.

Anyway, on with the content:

  <Window x:Class="VistaLayout.Dialog"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      Title="Delete File" 
      ResizeMode="NoResize"
      Height="212" Width="430">
    <Window.Resources>
      <Style x:Key="FooterButtonStyle" TargetType="{x:Type Button}">
        <Setter Property="Width" Value="100" />
        <Setter Property="Height" Value="28" />
        <Setter Property="Margin" Value="8,0,0,0" />
      </Style>
      <Style x:Key="FooterPanelStyle" TargetType="{x:Type UniformGrid}">
        <Style.Resources>
          <Style TargetType="{x:Type Button}" BasedOn="{StaticResource FooterButtonStyle}" />
        </Style.Resources>
        <Setter Property="Rows" Value="1" />
        <Setter Property="HorizontalAlignment" Value="Right" />
      </Style>
    </Window.Resources>
    <DockPanel Margin="14">
      <!-- Footer -->
      <UniformGrid DockPanel.Dock="Bottom" 
                       Style="{StaticResource FooterPanelStyle}">
        <Button>_Yes</Button>
        <Button>_No</Button>
      </UniformGrid>

      <!-- Main Content -->
      <Grid>
        <Grid.ColumnDefinitions>
          <ColumnDefinition Width="Auto" />
          <ColumnDefinition Width="8" />
          <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>

        <Image Width="64" />

        <StackPanel Grid.Column="2">
          <TextBlock Margin="0,6,0,14">Are you sure you want to move this file to the Recycle Bin?</TextBlock>

          <Grid>
            <Grid.ColumnDefinitions>
              <ColumnDefinition Width="Auto" />
              <ColumnDefinition Width="14" />
              <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>

            <Image Width="60" />

            <StackPanel Grid.Column="2">
              <TextBlock>117__6.jpg</TextBlock>
              <TextBlock>Type: ACDSee JPG Image</TextBlock>
              <TextBlock>Rating: Unrated</TextBlock>
              <TextBlock>Dimensions: 1072 × 712</TextBlock>
            </StackPanel>

          </Grid>

        </StackPanel>

      </Grid>

    </DockPanel>
  </Window>

As with most XAML, this could be done in a myriad of ways - this is only one solution.

Hope this helps!