WPF: Как указать единицы измерения в диалоговых единицах?

Я пытаюсь понять, как разметить простой диалог в WPF, используя правильный блоки диалога (DLU).


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:

WPF: Как указать единицы измерения в диалоговых единицах?

This means that dialog units:

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

Я потратил около двух часов на определение размеров этого образца диалогового окна в Windows Vista с различными измерениями dlu. Может ли кто-нибудь дать соответствующую разметку XAML, которая генерирует это диалоговое окно?

WPF: Как указать единицы измерения в диалоговых единицах? (Ссылка на изображение)

Теперь по общему признанию я почти ничего не знаю о WPF XAML. Каждый раз, когда я начинаю, я захожу в тупик, потому что не могу понять, как установить какой-либо контроль. Кажется, что все в WPF должно содержаться на какой-то панели. Есть 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?

Примечание: Вы не можете измерять скриншот. Указаны все значения ширины и высоты Dialog Unit (dlu).

Примечание: 1 горизонтальный DLU! = 1 вертикальный DLU. Горизонтальные и вертикальные DLU бывают разных размеров.


Смотрите также

Ударяться: 20.06.2011

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
24
0
6 482
5

Ответы 5

Посмотрите на Сетка управления - он поддерживает относительный размер.

Принимает ли система управления сетью такие устройства, как: width = "210dlu" в дополнение к width = "9999px"?

Ian Boyd 18.05.2010 22:48

Следующий XAML даст вам желаемый эффект.

Обратите внимание, что я удвоил единицы DLU в разметке - таким образом, сохранил тот же аспект. Это выглядело забавно, имея высоту кнопки в 14 единиц. Возможно, вам придется повозиться с цифрами, представленными на рынке.

Кроме того, я начал выделять некоторые из «Vista Layout» в отдельные стили. Возможно, вы сможете продолжить этот путь, чтобы получить достаточно многоразовый набор стилей, соответствующих рекомендациям 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, это можно сделать множеством способов - это только одно решение.

Надеюсь это поможет!

Откуда вы берете значения ширины и высоты? Будут ли эти числа масштабироваться в соответствии с предпочтениями пользователя шрифта Windows? Насколько я понимаю, любые длины, указанные без единиц измерения, считаются «логическими пикселями», где 1 логический пиксель равен 1/96 дюйма.

Ian Boyd 30.12.2008 21:49

XamlPad не может показать вам элементы <Window>, т.е. будет подавляться вещами <Window> из-за некоторой безопасности. Так что я все равно не могу его просмотреть.

Ian Boyd 30.12.2008 22:04

Вы разрабатываете приложение Xdap? Если это так, вам нужно будет изменить Window на userControl. Этот класс предполагает наличие файла с выделенным кодом. Попробуйте создать новый UserControl и скопировать XAML. Замените Window на UserControl. Конечно, вам придется обновить имя x: Class.

Brad Leach 31.12.2008 01:09

Окно будет масштабироваться в соответствии с предпочтениями пользователя в DPI, но не обязательно с их предпочтениями шрифта. Этот xaml не учитывает выбор шрифта пользователем - он использует Segeo UI, который я считаю стандартным (хотя я могу ошибаться).

Brad Leach 31.12.2008 01:12

Я провел небольшое исследование DLU, которое, похоже, основано на размере шрифта. Система компоновки WPF основана на устройствах, не зависящих от устройства. Я не знаю, как использовать DLU в WPF. Тем не менее, представленный макет должен стать хорошей отправной точкой для создания диалогового окна разумного размера.

Brad Leach 31.12.2008 02:49

Элемент макета холста позволяет создавать макет на основе координат, аналогичный тому, к которому вы привыкли, и если у вас есть холст, вы даже получите некоторые рекомендации в визуальном редакторе. например:

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

Проблема в том, что вводимые вами значения принимаются WPF как пиксели. Где снимок экрана предоставляет значения в горизонтальных и вертикальных диалоговых единицах (DLU). И чтобы уточнить, DLU не обязательно квадратные.

Ian Boyd 28.05.2009 22:51

Вот более подробная ссылка, которую я нашел в MSDN о Показатели макета. WPF DIU определены как 1/96 дюйма, а преобразования DLU в пиксели зависят от шрифта, как вы можете видеть в таблице, показанной ниже.

Converting from DLUs to relative pixels and back

Таким образом, используя эту информацию вместе с настройкой DPI системы и в зависимости от шрифта, на который вы ориентируетесь, вы можете выяснить, сколько DUI коррелирует с данным измерением в вертикальных или горизонтальных единицах DLU. Я еще не видел для этого никаких калькуляторов на основе javascript, но было бы довольно тривиально создать аналогичный инструмент на любом языке программирования, который сделает это немного проще.

я не думаю, что это тривиально; никто еще не смог этого сделать.

Ian Boyd 28.06.2011 05:27

Я знаю, что это очень старый, но я подумал, что попытаюсь сделать то, что попросил OP. И это моя попытка. Кстати, прежде чем продолжить, я должен указать, что по какой-то причине измерения OP не совсем сработали при использовании DLU, но я думаю, что я подошел достаточно близко. Также, пожалуйста, имейте в виду, что я все еще относительный новичок, когда дело доходит до этого ... так что если я сделал что-то не так или кощунственно ... извиняюсь.

Final Result

Сначала мне нужно было найти способ получить ширину и высоту заданной буквы данного шрифта (в моем случае, пользовательский интерфейс Segoe с размером 10 пикселей) ... для чего я использовал этот ответ SO: как-вычислить-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>

Надеюсь, это поможет и будущим людям (если это действительно полезно, хех)

Другие вопросы по теме