WPF: How to specify units in Dialog Units?

后端 未结 5 904
感情败类
感情败类 2020-12-05 10:22

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?

相关标签:
5条回答
  • 2020-12-05 10:49

    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!

    0 讨论(0)
  • 2020-12-05 10:49

    Look into the Grid control - it has support for relative sizing.

    0 讨论(0)
  • 2020-12-05 10:59

    I know this is very old, but I thought I would attempt to do what the OP asked. And as such this is my attempt. BTW, before I continue, I should point out that for some reason, the OPs measurements didn't quite work out when using DLUs, but I think I've come reasonably close. Also please keep in mind I'm still a relative n00b when it comes to this stuff... so if I've done something wrong or blasphemous... apologies.

    Final Result

    First I had to find a way to get the width and height of a given letter of a given font (In my case, Segoe UI at 10px)... which for that I used this SO answer: how-to-calculate-wpf-textblock-width-for-its-known-font-size-and-characters to which I made a static class to hold the resulting doubles:

    public static class Fonts
    {
        public static double HorizontalDluMultiplier;
        public static double VerticalDluMultiplier;
    
        static Fonts()
        {
            var formattedText = new FormattedText(
                "A",
                CultureInfo.CurrentUICulture,
                FlowDirection.LeftToRight,
                new Typeface("Segoe UI"),
                12.0,
                Brushes.Black);
            Fonts.HorizontalDluMultiplier = formattedText.Width / 4;
            Fonts.VerticalDluMultiplier = formattedText.Height / 8;
        }
    }
    

    Once I had the metrics I had to create a WPF converter that takes a given ConverterParameter (In this case a number in DLUs) and spits out a double of pixels. This is the converter I used...

    public class HorizontalDluToPixelConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return (Double.Parse((parameter as string))) * Fonts.HorizontalDluMultiplier;
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    

    I think it goes without saying that I had a seperate Vertical version of the converter.

    Once that was done, I was just a matter of laying out the window in XAML and when it came to setting heights and widths, using the converter. I used a single grid to lay out the entire window. but to set the column widths and row heights I used the converter like so:

    <Window.Resources>
        <converters:HorizontalDluToPixelConverter x:Key="HorizontalConverter" />
        <converters:VerticalDluToPixelConverter x:Key="VerticalConverter" />
    </Window.Resources>
    
    <Grid.RowDefinitions>
        <RowDefinition Height="{Binding Converter={StaticResource VerticalConverter}, ConverterParameter=7}" />
        etc...
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="{Binding Converter={StaticResource HorizontalConverter}, ConverterParameter=7}" />
        etc... etc...
    </Grid.ColumnDefinitions>
    

    Hope this helps future people as well (if it is infact helpful heh)

    0 讨论(0)
  • 2020-12-05 11:03

    Here is a more detailed link I found on MSDN about Layout Metrics. WPF DIUs are defined as 1/96 of an inch and DLU to pixel conversions are font dependent as you can see in the table shown below.

    Converting from DLUs to relative pixels and back

    So using this information along with a systems DPI setting and depending on the font that you are targeting you could figure out how many DUI correlate to a given measurement in vertical or horizontal DLU units. I haven't seen any javascript based calculators for this yet but it would be pretty trivial to create a similar tool in any programming language that makes this a little easier.

    0 讨论(0)
  • 2020-12-05 11:03

    The Canvas layout element allows for coordinate-based layout similar to what you're used to and if you have a Canvas you even get some guidelines in the visual editor. eg:

    <Window xmlns:mc='http://schemas.openxmlformats.org/markup-compatibility/2006' xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' xmlns:d='http://schemas.microsoft.com/expression/blend/2008' mc:Ignorable='d' Title='Spin-Echo Image Processing' Width='673' x:Class='ImageR2.CLASPmap' Height='961' xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'>
        <Canvas Name='canvas1'>
            <TextBlock Name='TEXT_Program' Canvas.Top='27' Width='133' Height='21' Canvas.Left='875'>CLASPmap:</TextBlock>
            <TextBlock Name='TEXT_Heading' Canvas.Top='27' Width='368' Height='27' Canvas.Left='1008'>Transverse Relaxation Rate Mapping</TextBlock>
            <TextBlock Name='TEXT_XYCoordinates' Canvas.Top='251' Width='139' Height='21' Canvas.Left='869'>X &amp; Y Coordinates</TextBlock>
    
    0 讨论(0)
提交回复
热议问题