如何在 WPF 中创建自适应布局?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14013959/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I create an adaptive layout in WPF?
提问by Athari
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?
WPF 是否有类似的技术可以根据可用屏幕空间或父控件大小调整布局?
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."
例如,我想在大屏幕上水平显示 3 列,但在较小的屏幕上垂直显示。理想情况下,我想制定这样的布局:“如果此控件的宽度小于 400 磅,则以这种方式重新排列这些控件。”
How can I create an adaptive design like this in WPF? That is, define different layouts for controls for specific parent control sizes?
如何在 WPF 中创建这样的自适应设计?也就是说,为特定的父控件大小定义不同的控件布局?
Ideally controls should be rearranged instead of duplicated or recreated, to avoid being extremely slow.
理想情况下,控件应该重新排列而不是重复或重新创建,以避免非常慢。
回答by Rachel
The easiest way to do this is with DataTriggersand a Converterto test if the bound value is greater or less than a parameter.
最简单的方法是使用DataTriggers和 aConverter来测试绑定值是大于还是小于参数。
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 SystemParametersobject to use additional information about the application in your bindings, although I can't remember the exact syntax for it right now.
我相信您还可以绑定到SystemParameters对象以在绑定中使用有关应用程序的其他信息,尽管我现在不记得它的确切语法。
回答by Drew Noakes
If you're using the UWP flavour of WPF, then you might use AdaptiveTrigger:
如果您使用的是 WPF 的 UWP 风格,那么您可以使用AdaptiveTrigger:
<AdaptiveTrigger MinWindowWidth="720" MinWindowHeight="900" />
回答by Zipper
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.
我知道做这样的事情的唯一方法是在代码中,你需要创建一个自定义布局。最简单的方法是创建一个继承自Panel 的新类,并实现MeasureOverride 和ArrangeOverride。我以前做过自定义布局,但它们最终可能会为所有情况下工作带来相当大的痛苦。如果你谷歌“wpf 自定义布局”,你会得到一些很好的例子。考虑到您想要的所有功能,您肯定会为您完成工作。您可能希望查看附加属性以了解如何在 xaml 中添加注释,从而让您的代码了解应该以不同大小包含哪些内容。

