【问题标题】:How can I create an adaptive layout in WPF?如何在 WPF 中创建自适应布局?
【发布时间】:2012-12-10 10:33:19
【问题描述】:

可以使用媒体查询将网站设计为适应较小的屏幕尺寸。例如,在宽屏上显示三列,在低分辨率手机上显示一列。

WPF 是否有类似的技术来根据可用屏幕空间或父控件大小调整布局?

例如,我想在大屏幕上水平显示 3 列,但在较小的屏幕上垂直显示。理想情况下,我想制定这样的布局:“如果此控件的宽度小于 400 磅,请以这种方式重新排列这些控件。”

如何在 WPF 中创建这样的自适应设计?也就是说,为特定父控件大小的控件定义不同的布局?

理想情况下,控件应该重新排列,而不是重复或重新创建,以避免极其缓慢。

【问题讨论】:

  • 您的意思是单独使用 XAML,还是正在寻找一种在代码中执行此操作的方法?
  • @Zipper 当然,我更喜欢在 XAML 中以声明方式执行此操作。如果不可能马上,我不介意写一些框架代码。但最终,我想在没有任何程序代码的情况下描述布局。

标签: c# .net wpf layout


【解决方案1】:

我知道做这样的事情的唯一方法是在代码中,你需要创建一个自定义布局。最简单的方法是创建一个继承自 Panel 的新类,并实现 MeasureOverride 和 ArrangeOverride。我以前做过自定义布局,但最终要为所有情况工作会带来相当大的痛苦。如果你用谷歌搜索“wpf 自定义布局”,你会得到一些很好的例子。鉴于您想要的所有功能,您肯定会为您完成工作。您可能需要查看附加属性以了解如何在 xaml 中添加注释,从而让您的代码了解不同大小应包含的内容。

【讨论】:

  • 这实际上很容易使用DataTriggers 来完成,它可以更改布局属性,甚至可能是基于父控件的ActualWidthActualHeight 属性的DataTemplate。您不需要为此在代码中自定义布局
【解决方案2】:

最简单的方法是使用DataTriggersConverter 来测试绑定值是大于还是小于参数。

这将允许您根据绑定值轻松调整样式设置器。例如,您可以使用

<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 对象,以在绑定中使用有关应用程序的其他信息,尽管我现在不记得它的确切语法。

【讨论】:

    【解决方案3】:

    如果您使用的是 WPF 的 UWP 风格,那么您可以使用 AdaptiveTrigger

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

    【讨论】:

    • 考虑到 UWP 和 WPF 大多是不相关的技术,我会说“XAML GUI 的 UWP 风格”或类似的东西。 :) 我想知道 WPF 是否存在这样的东西。也许继承 DataTrigger 可以工作。
    • 很公平。它们非常相似,您几乎可以立即在 UWP 中提高工作效率,并在此过程中学习您无法使用的部分。有时你会发现新的东西,就像我今天对 AdaptiveTrigger 所做的那样。
    • 有一张公开票可能会为 WPF 项目带来更多支持,以便将所需的 VisualState.StateTriggers 属性引入 WPF。 github.com/dotnet/wpf/issues/2080
    猜你喜欢
    • 1970-01-01
    • 2022-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多