Как создать адаптивный макет в WPF?

веб-сайт может быть разработан для адаптации к меньшим размерам экрана с помощью медиа-запросов. Например, три столбца на широком экране, один столбец на телефоне с низким разрешением.

существует ли аналогичный метод для WPF для настройки макета на основе доступного пространства экрана или размера родительского элемента управления?

например, я хотел бы, чтобы 3 столбца отображались горизонтально на большом экране, но отображались вертикально на меньшем экране. В идеале я хотел бы сформулировать такие макеты: "Если ширина этого элемента управления меньше 400 точек, переставьте эти элементы управления таким образом."

Как я могу создать такой адаптивный дизайн в WPF? То есть определить различные макеты для элементов управления для определенных размеров родительского элемента управления?

В идеале элементы управления должны быть переставлены, а не дублированы или воссозданы, чтобы не быть чрезвычайно медленными.

3 ответов


самый простой способ сделать это с DataTriggers и Converter чтобы проверить, больше или меньше связанного значения параметра.

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

<Style x:Key="MyControlStyle">
    <!-- Default Values -->
    <Setter Property="Grid.Row" Value="0" />
    <Setter Property="Grid.Column" Value="0" />
    <Style.Triggers>
        <DataTrigger Value="True" 
                     Binding="{Binding ActualHeight, ElementName=MyWindow, 
                         Converter={StaticResource IsValueLessThanParameter}, 
                         ConverterParameter=400}">
            <!-- Values to use when Trigger condition is met -->
            <Setter Property="Grid.Row" Value="1" />
            <Setter Property="Grid.Column" Value="1" />
        </DataTrigger>
    </Style.Triggers>
</Style>

в случае, когда у вас есть более сложный макет со многими частями, которые меняются на основе некоторого вызванного значения, вы можете заменить целые Шаблоны своим триггером, а не просто индивидуальные свойства

<Style x:Key="MyContentControlStyle" TargetType="{x:Type ContentControl}">
    <Setter Property="ContentTemplate" Value="{StaticResource BigTemplate}" />
    <Style.Triggers>
        <DataTrigger Value="True" 
                     Binding="{Binding ActualHeight, ElementName=MyWindow, 
                         Converter={StaticResource IsValueLessThanParameter}, 
                         ConverterParameter=400}">
            <Setter Property="ContentTemplate" Value="{StaticResource LittleTemplate}" />
        </DataTrigger>
    </Style.Triggers>
</Style>

Я считаю, что вы также можете привязаться к SystemParameters объект для использования дополнительной информации о приложении в ваших привязках, хотя я не могу вспомнить точный синтаксис для него прямо сейчас.


Если вы используете вкус UWP WPF, то вы можете использовать AdaptiveTrigger:

<AdaptiveTrigger MinWindowWidth="720" MinWindowHeight="900" />

единственный способ сделать что-то подобное-это код, и вам нужно будет создать пользовательский макет. Самый простой способ сделать это-создать новый класс, который наследуется от Panel, и реализовать MeasureOverride и ArrangeOverride. Я делал пользовательские макеты раньше, и они могут оказаться довольно большой болью, чтобы работать для всех случаев. Если Вы Google "пользовательский макет wpf", вы получите несколько хороших примеров для начала. Учитывая всю функциональность, которую вы хотите, у вас обязательно будет свой работа создана для тебя. Вероятно, вы захотите посмотреть вложенные свойства, чтобы узнать о размещении аннотаций в xaml, чтобы дать вашему коду представление о том, что должно быть включено в разных размерах.