WPF: Как указать единицы в диалоговых модулях?
Я пытаюсь выяснить, как разложить простой диалог в WPF, используя соответствующие диалоговые модули (DLU).
Что такое диалоговое окно?
Диалог - это единица измерения, основанная на предпочтительном размере шрифта пользователя. Диалоговое окно определено так, что средний символ - 4 диалога единиц на 8 диалоговом уровне:
![enter image description here]()
Это означает, что диалоговые блоки:
- изменить выбранный шрифт
- изменено с выбранной настройкой DPI
- не являются квадратными
я потратил около двух часов на определение этого диалогового окна образца из Windows Vista с различными измерениями dlu. Может ли кто-нибудь указать соответствующую разметку XAML, которая генерирует это диалоговое окно?
alt text http://i44.tinypic.com/30a7390.jpg
(Ссылка на изображение)
Теперь, по общему признанию, я почти ничего не знаю о WPF XAML. Каждый раз, когда я начинаю, я становлюсь заглушенным, потому что я не могу понять, как разместить любой элемент управления. Кажется, что все в WPF должно содержаться на какой-то панели. Там StackPanels, FlowPanels, DockPanel, Grid и т.д. Если у вас нет одного из них, он не будет компилироваться.
Единственный XAML, с которым я смог придумать (uing 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 имеют разные размеры.
См. также
Bump: 6/20/2011
Ответы
Ответ 1
Следующий XAML даст вам эффект, который вы ищете.
Обратите внимание, что я удвоил единицы DLU в разметке - таким образом, сохраняя один и тот же аспект. Это выглядело забавно, когда у Button была высота 14 единиц. Возможно, вам придется переделывать цифры, представленные на рынке.
Кроме того, я начал удалять некоторые "макеты Vista" в отдельные стили. Возможно, вы сможете продолжить этот путь, так что у вас есть многократно используемый набор стилей, которые следуют рекомендациям Vista. Я уверен, что некоторые другие люди сделали что-то подобное.
Кроме того, я взял некоторые свободы с размером диалога. Вы упомянули, что вам нужны 210x96 единиц - вам нужно будет установить эту сумму, а также окно хром.
В любом случае, с содержимым:
<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, это может быть сделано множеством способов - это только одно решение.
Надеюсь, это поможет!
Ответ 2
Я знаю, что это очень старый, но я думал, что попытаюсь сделать то, что задал ОП. И как таковая это моя попытка. Кстати, прежде чем я продолжу, я должен указать, что по некоторым причинам измерения OPs не совсем работали при использовании DLU, но я думаю, что я подошел достаточно близко. Также, пожалуйста, имейте в виду, что я все еще относительный n00b, когда дело доходит до этого материала... так что если я сделал что-то неправильно или богохульно... извинения.
![Final Result]()
Сначала мне пришлось найти способ получить ширину и высоту заданной буквы данного шрифта (в моем случае, 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-конвертер, который принимает данный конвертер (в этом случае число в 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>
Надеюсь, что это тоже поможет будущим людям (если это полезно, хе-хе)
Ответ 3
Посмотрите Grid control - он поддерживает относительный размер.
Ответ 4
Вот более подробная ссылка, которую я нашел в MSDN о Макетные показатели. WPF DIU определяются как 1/96 дюйма, а конверсии DLU в пиксели зависят от шрифта, как вы можете видеть в таблице, показанной ниже.
![Converting from DLUs to relative pixels and back]()
Таким образом, используя эту информацию вместе с настройкой DPI системы и в зависимости от шрифта, на который вы нацеливаете, вы можете выяснить, сколько DUI коррелирует с данным измерением в вертикальных или горизонтальных блоках DLU. Я пока не видел никаких калькуляторов на основе javascript, но было бы довольно тривиально создавать подобный инструмент на любом языке программирования, что упростит это.
Ответ 5
Элемент макета 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 & Y Coordinates</TextBlock>