24

我试图弄清楚如何使用正确的对话框单元(DLU)在 WPF 中布局一个简单的对话框。


什么是对话单元?

对话框是基于用户首选字体大小的度量单位。定义一个对话单元,使平均字符为 4 个对话单元宽乘以 8 个对话单元高:

在此处输入图像描述

这意味着对话单元:

  • 用所选字体更改
  • 使用选定的 DPI 设置更改
  • 不是方形的

我花了大约两个小时在 Windows Vista 中使用各种dlu测量来确定这个示例对话框的尺寸。有人可以提供生成此对话框的相应 XAML 标记吗?

替代文字图片链接

现在诚然,我对 WPF XAML 几乎一无所知。每次我开始时,我都会受到阻碍,因为我不知道如何进行任何控制。似乎 WPF 中的所有内容都必须包含在某种面板上。有 StackPanels、FlowPanels、DockPanel、Grid等。如果您没有其中之一,则无法编译。

到目前为止,我能够提出的唯一 XAML(使用 XAMLPad):

<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>

这呈现为一个华而不实的怪物。没有任何控件放置或调整大小。我无法弄清楚如何在窗口中放置控件,也无法正确调整它们的大小。

有人可以将该屏幕截图转换为 XAML 吗?

注意:您不能测量屏幕截图。指定了所有对话单元 (dlu) 的宽度和高度。

注意: 1 个水平 DLU != 1 个垂直 DLU。水平和垂直 DLU 的大小不同。


也可以看看

碰撞: 2011 年 6 月 20 日

4

5 回答 5

8

以下 XAML 将为您提供您正在寻找的效果。

请注意,我将标记中的 DLU 单元加倍 - 从而保持相同的方面。按钮高度为 14 个单位看起来很有趣。您可能需要修改市场上提供的数据。

此外,我开始将一些“Vista 布局”删除为单独的样式。您也许可以继续沿着这条路走下去,这样您就有了一组遵循 Vista 指南的可重复使用的样式。我很确定其他人也做过类似的事情。

此外,我对对话框的大小采取了一些自由。你提到你想要 210x96units - 你需要设置这个数量,加上窗口镶边。

无论如何,继续内容:

  <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>

与大多数 XAML 一样,这可以通过多种方式完成 - 这只是一种解决方案。

希望这可以帮助!

于 2008-12-28T03:46:12.433 回答
2

我知道这已经很老了,但我想我会尝试按照 OP 的要求去做。因此,这是我的尝试。顺便说一句,在我继续之前,我应该指出,由于某种原因,在使用 DLU 时 OPs 测量结果并不完全正确,但我认为我已经相当接近了。另外请记住,当涉及到这些东西时,我仍然是一个相对的n00b......所以如果我做错了什么或亵渎神明......道歉。

最后结果

首先,我必须找到一种方法来获取给定字体的给定字母的宽度和高度(在我的情况下,Segoe UI 为 10px)......为此我使用了这个 SO 答案:how-to-calculate-wpf -textblock-width-for-its-known-font-size-and-characters我创建了一个静态类来保存结果双打:

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;
    }
}

获得指标后,我必须创建一个 WPF 转换器,该转换器采用给定的 ConverterParameter(在本例中为 DLU 中的数字)并输出双倍像素。这是我用的转换器...

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();
    }
}

我认为不用说我有一个单独的垂直版本的转换器。

完成后,我只需在 XAML 中布置窗口,并使用转换器设置高度和宽度。我使用一个网格来布置整个窗口。但是要设置列宽和行高,我使用了转换器,如下所示:

<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>

希望这对未来的人也有帮助(如果它实际上有帮助的话)

于 2014-10-04T02:03:20.213 回答
1

查看Grid 控件- 它支持相对大小。

于 2008-12-27T17:44:15.893 回答
1

这是我在 MSDN 上找到的关于Layout Metrics的更详细的链接。WPF DIU 定义为 1/96 英寸,DLU 到像素的转换取决于字体,如下表所示。

从 DLU 转换为相对像素并返回

因此,将这些信息与系统 DPI 设置一起使用,并根据您所定位的字体,您可以计算出有多少 DUI 与垂直或水平 DLU 单位中的给定测量相关。我还没有看到任何基于 javascript 的计算器,但是用任何编程语言创建一个类似的工具来让它变得更容易一点是非常简单的。

于 2010-05-22T14:21:23.930 回答
0

Canvas 布局元素允许基于坐标的布局,类似于您习惯的布局,如果您有 Canvas,您甚至可以在可视化编辑器中获得一些指导。例如:

<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>
于 2009-05-27T19:16:05.507 回答