WPF:如何在对话单元中指定单位?

我想弄清楚如何使用适当的对话单元 (DLUs)在WPF中布局一个简单的对话框。


什么是对话单元?

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

在这里输入图像说明

这意味着对话单元:

  • 改变选定的字体
  • 更改为选定的DPI设置
  • 不是方的

我花了大约两个小时从Windows Vista中select这个示例对话框,并使用各种dlu测量。 有人可以给出产生这个对话框的相应的XAML标记吗?

替代文字http://i44.tinypic.com/30a7390.jpg ( 图片链接 )

无可否认,我对WPF XAML几乎一无所知。 每当我开始时,我都会因为无法弄清楚如何放置任何控制而受到阻碍。 似乎WPF中的一切都必须包含在某种types的面板中。 有StackPanels,FlowPanels,DockPanel, 网格等,如果你没有其中之一,那么它不会编译。

到目前为止,我唯一能够想到的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是不同的大小。


也可以看看

  • 调整为屏幕和字体设置的WPF应用程序(或者,我如何将DLU与WPF中的单元相关联?)
  • WPF全局字体大小
  • WPFbutton相同/推荐宽度
  • WPF版本的.ScaleControl?
  • Microsoft用户体验指南:build议的大小和间距
  • Microsoft用户体验指南:布局指标

凹凸: 6/20/2011

下面的XAML会给你你正在寻找的效果。

请注意,我把标记中的DLU单位增加了一倍,因此保持了相同的方面。 它看起来很有趣,有14个单位的按钮高度。 您可能需要修改市场上的数字。

此外,我开始删除一些“Vista布局”到不同的风格。 您可能可以继续沿着这条道路走下去,所以您有一套遵循Vista准则的可重复使用的样式。 我相当肯定其他人做了类似的事情。

此外,我对对话的大小有了一些自由。 你提到你想要210×96单位 – 你需要设置这个数量,加上窗口铬。

无论如何,关于内容:

  <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一样,这可以通过多种方式完成 – 这只是一个解决方案。

希望这可以帮助!

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

最后结果

首先,我必须找到一种方法来获得一个给定的字体的宽度和高度给定的字体(在我的情况下,在10px的Segoe用户界面)…这是我用这个答案: 如何计算-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> 

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

看看网格控制 – 它支持相对大小。

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

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

因此,将这些信息与系统DPI设置一起使用,并根据您定位的字体,可以计算出垂直或水平DLU单位中给定测量的DUI数量。 我还没有看到任何基于JavaScript的计算器,但是在任何编程语言中创建一个类似的工具使得这个更容易一些,这将是非常微不足道的。

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>