简体   繁体   中英

How can I create an adaptive layout in WPF?

A website can be designed to adapt to smaller screen sizes using media queries. For example, three columns on a wide screen, one column on a low-resolution phone.

Is there a similar technique for WPF to adjust the layout based on available screen space or parent control size?

For example, I'd like to have 3 columns displayed horizontally on a large screen, but displayed vertically on smaller screen. Ideally, I'd like to formulate layouts like this: "If this control's width is less than 400 points, rearrange these controls in that way."

How can I create an adaptive design like this in WPF? That is, define different layouts for controls for specific parent control sizes?

Ideally controls should be rearranged instead of duplicated or recreated, to avoid being extremely slow.

The easiest way to do this is with DataTriggers and a Converter to test if the bound value is greater or less than a parameter.

This will allow you to easily adjust the style setters based on a bound value. For example, you could use

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

In the case where you have a more complex layout with many pieces that change based on some triggered value, you can replace entire Templates with your trigger instead of just individual properties

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

I believe you can also bind to the SystemParameters object to use additional information about the application in your bindings, although I can't remember the exact syntax for it right now.

如果你正在使用WPF的UWP风格,那么你可以使用AdaptiveTrigger

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

The only way I know to do something like this is in code, and you'll need to create a custom layout. The simplest way of doing that is to create a new class that inherits from Panel, and implement MeasureOverride and ArrangeOverride. I've done custom layouts before, and they can end up being a rather large pain to get working for all cases. If you Google "wpf custom layout" you'll get some good examples to start with. Given all the functionality you want, you'll definitely have your work cut out for you. You'll probably want to look at attached properties to see about putting annotations in the xaml to give your code an idea of what should be included at the different sizes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM