[WPF]建立自适应窗口大小布局的WinForm窗口
编写WinForm程序时,都会碰到一个问题。就是WinForm窗口在不同分辨率下的大小问题。举例说明,你编写的WinForm窗口在1024×768下是合适、匀称的。不过,如果用户的计算机的分辨率为1400×900时,你的WinForm窗口就显得偏小,其中的字体和控件都显得偏小。如果用户的分辨率为640×480,那你的窗口就远远超过它的屏幕的大小。
如何解决这个问题?一般的WinForm程序都会这样操作:程序启动——》获取屏幕分辨率——》调整窗体的大小——》调整各个控件大小及位置——》调整各个控件的字体。这样操作比较繁琐,并且要考虑到各种分辨率的情况。这样一来,如果WinForm窗口上有若干控件,调整是一件很痛苦的事。
有没有这样的手段。我只要调整WinForm窗口的大小,其中的各个控件大小(包括字体)自动的等比例缩放?
还记得一些DirectX的游戏程序吗?当设定为固定的分辨率时(比如800×600),在全屏的时候,他都会自动缩放。WinForm有这样的手段吗?
答案是肯定的。在WPF中就能很简单的实现该功能。
利用WPF中的ViewBox容器空间。ViewBox是一个容器空间,它会自动缩放容器中的子空间以填满自身,同时它只能有一个子控件。不过,我们可以把Canvas控件作为ViewBox控件的子控件。然后在Canvas控件中布局其他的控件。
先看看下面的窗口的Xaml文件
<Window x:Class="Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WPFTest"
mc:Ignorable="d"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
SizeToContent="Manual" Width="400" Height="300">
<DockPanel Name="DockPanel1" LastChildFill="True">
<Menu Height="23" Name="Menu1" DockPanel.Dock="Top">
<MenuItem Header="Menu1">
<MenuItem Header="H1" />
<MenuItem Header="H2" />
</MenuItem>
<MenuItem Header="Menu2">
<MenuItem Header="L1" />
<MenuItem Header="L2" />
<Separator />
<MenuItem Header="L4" />
</MenuItem>
</Menu>
<StatusBar Height="23" Name="StatusBar1" DockPanel.Dock="Bottom">
<StatusBarItem Content="S1" Name="S1"/>
<StatusBarItem Content="S2" Name="S2"/>
<StatusBarItem Content="S3" Name="S3"/>
</StatusBar>
<Viewbox Name="Viewbox1" Stretch="Fill">
<Canvas Height="200" Name="Canvas1" Width="300" Background="#FF8EDE75">
<Button Canvas.Left="43" Canvas.Top="40" Content="Button" Height="37" Name="Button1" Width="87" />
</Canvas>
</Viewbox>
</DockPanel>
</Window>
先简单的说明这个XAML文件
最外面的是Window容器,设置了标题(WPFTest)和大小(400×300),它也只能有一个子控件。
Window的子控件是DockPanel容器,是自动停靠容器控件。设置LastChildFill="True",表示最后一个子控件自动填充剩余的空间。没有设置大小,默认大小是Window的客户区大小。
DockPanel控件有三个子控件
Menu控件:菜单控件,自动停靠在容器的顶端
StatusBar控件:状态栏控件,自动停靠在容器的底部
ViewBox控件:容器控件,自动填充DockPanel剩余的控件。没有设置大小,为填充的大小。设置填充的模式为Fill,表示子控件填充自身的容器的大小
在ViewBox中放置了一个Canvas控件,设置了大小(注:一定要设置大小,否则默认时会产生各种不可思议的效果),设置了背景色
在Canvas中放置了一个Button控件。只是示例,Canvas中还能放置其他的控件
在Window的代码中输入如下的代码
Public Class Window1
Private _I As Integer
Private Sub Window1_SizeChanged(ByVal sender As Object, ByVal e As System.Windows.SizeChangedEventArgs) Handles Me.SizeChanged
_I += 1
Me.S1.Content = "窗口宽度:" & Me.Width
Me.S2.Content = "内容宽度:" & Me.Viewbox1.Width
Me.S3.Content = "按钮宽度:" & Me.Button1.Width & ";刷新次数:" & _I
End Sub
End Class
启动后是如下的效果
可以看出窗口的宽度是400,由于ViewBox没有设置宽度,故显示非数字,按钮的宽度是87
拖动右下角,调整Window的大小。如下图所示
和上图的比较,Window的大小发生了变化。ViewBox中的子控件也自动的拉伸了。这个从Button的外观能很明显的感受到。更神奇的是,无论我怎么调整Window的大小,Button的外观也随着Window的大小而改变,不过,在内部的逻辑中,Button的宽度始终是87,始终没有发生变化。
另,由于Menu和StatusBar不在ViewBox内。故这两个控件没有缩放,还是原始的大小
这给我们带来了极大的便利。无论window被调整到如何,在内部逻辑中,ViewBox中的子控件Canvas的逻辑大小始终是300×200。我们不需要再为调整后的大小设计额外的代码。
实际上,我猜测。ViewBox的显示机制是,先在内存中把按照逻辑大小把子控件显示出来,然后等比例的缩放显示到ViewBox的客户区。
回到开始的话题。编写的WinForm窗口如何应对不同的分辨率?
在WPF中,将所有的客户控件放在Canvas中再放在ViewBox控件中,利用ViewBox的特性来实现自动的缩放。流程就变成了:程序启动——》获取屏幕分辨率——》调整窗体的大小。其余控件的缩放就交给ViewBox控件吧。而且由于逻辑的大小没有发生变化,你还不必要再额外添加代码。
网上ViewBox控件介绍的比较少,用ViewBox来实现自适应窗体的大小确是独辟蹊径。
其实他说了那么多,其实就是添加几行代码而已。
建立WPF工程的时候不是会生成一个<Grid> </Grid>标签么? 只要在这个标签下面(紧挨着Grid标签,不能在子标签里面)加上这几行代码:
<Grid>
<Viewbox Name="Viewbox1" Stretch="Fill">
<Canvas Height="350" Name="Canvas1" Width="525" >
<Button Name="btn1"/>
<TextBox Name="txt"/>
</Canvas>
</Viewbox>
</Grid>
其中Canvas的宽度和高度应该设置为和最开始的window标签的宽度和高度一样,这样之后,只需要在Canvas标签里面继续写我们想要的布局就可以了,之后控件会自动进行缩放
[WPF]建立自适应窗口大小布局的WinForm窗口的更多相关文章
- 自适应XAML布局经验总结 (一)原则和页面结构设计
XAML布局回顾 Grid和StackPanel是核心布局,尤其以Grid最为重要. Grid是网格布局,XAML的设计者有可能参考了Html里的Table设计了Grid布局,但进行了改进.Html中 ...
- 【WPF】监听WPF的WebBrowser控件弹出新窗口的事件
原文:[WPF]监听WPF的WebBrowser控件弹出新窗口的事件 WPF中自带一个WebBrowser控件,当我们使用它打开一个网页,例如百度,然后点击它其中的链接时,如果这个链接是会弹出一个新窗 ...
- WPF中的常用布局
一 写在开头1.1 写在开头评价一门技术的好坏得看具体的需求,没有哪门技术是面面俱到地好. 1.2 本文内容本文主要内容为WPF中的常用布局,大部分内容转载至https://blog.csdn.net ...
- WPF中的常用布局 栈的实现 一个关于素数的神奇性质 C# defualt关键字默认值用法 接口通俗理解 C# Json序列化和反序列化 ASP.NET CORE系列【五】webapi整理以及RESTful风格化
WPF中的常用布局 一 写在开头1.1 写在开头微软是一家伟大的公司.评价一门技术的好坏得看具体的需求,没有哪门技术是面面俱到地好,应该抛弃对微软和微软的技术的偏见. 1.2 本文内容本文主要内容 ...
- 利用WPF建立自己的3d gis软件(非axhost方式)(六)跳转,增加外部三维模型
原文:利用WPF建立自己的3d gis软件(非axhost方式)(六)跳转,增加外部三维模型 先下载SDK:https://pan.baidu.com/s/1M9kBS6ouUwLfrt0zV0bPe ...
- boostrap栅格系统自适应的布局
1.栅格系统 Bootstrap是基于移动优先的原则开发的,使用了一系列的媒体查询(media queries)方法,为我们的布局和界面创建自适应的的分界点.这些分界点主要是基于视口宽度的最小值, ...
- 简单而兼容性好的Web自适应高度布局,纯CSS
纯CSS实现的自适应高度布局,中间内容不符自动滚动条.兼容IE9以上.chrome.FF.关键属性是box-sizing: border-box. 不废话,直接上代码: <!doctype ht ...
- RelativeLayout中的格局,自适应宽度布局
RelativeLayout中的布局,自适应宽度布局 该图片中为android布局:总布局为 RelativeLayoutAtLeft 为居左 <TextView android:backgro ...
- C# WinForm窗口最小化到系统托盘
* C# WinForm窗口最小化到系统托盘http://hi.baidu.com/kfxtgtqyapouyze/item/8ccfdcd5a174a7312a35c7c3 主要功能:(1).程序启 ...
随机推荐
- uicollectionview registerclass vs registernib
当cell是用代码实现的时候用registerclass,当cell是用xib文件实现的时候用registernib
- 研究SVM时安装的一些工具的方法
本文是个人存档,不介绍研究SVM相关内容. 1.bamboo在fedora19下 哪一行编译时报错,就注释掉 php插件不用装 提示ERROR: libcrfpp.so.0: cannot open ...
- .NET 配置项扩展
using System; using System.Configuration; namespace ConsoleApplication3 { /* web.config 或 app.config ...
- 基于VLC的视频播放器(转载)
最近在研究视频播放的功能,之前是使用VideoView.在网上看了一下,感觉不是很好,支持的格式比较少,现在网络视频的格式各种各样,感觉用VideoView播放起来局限性很大. 找到了一个比较合适的播 ...
- c# XML和实体类之间相互转换(序列化和反序列化)[砖]
link: http://blog.okbase.net/haobao/archive/62.html by: 好饱 我们需要在XML与实体类,DataTable,List之间进行转换,下面是XmlU ...
- TextView实现歌词同步
利用TextView实现歌词同步显示,这是一个简单的利用TextView实现滚动实时显示歌词的. 里面的内容都已经写上了详细的注释.里面播放音乐的时候歌词同步展示. 做媒体这块的朋友可以学习一下,练练 ...
- Office 365 系列四 ------ 绑定公司域名
Office 365包含了企业邮箱服务(Exchange Online),我们如果要用微软的企业邮箱,那么我们必须绑定我们公司的自己域名,而不是用微软 提供的二级域名,其实微软的整个Exchange ...
- CALayer
刚刚无聊,画了一个月亮. - (void)viewDidLoad { [super viewDidLoad]; self.view.layer.backgroundColor = [UIColor b ...
- 初学c# -- 学习笔记(五) winfrom自定义滚动条
找了些例子,要么庞大.要么搞个安装组件什么的,我要求能用就行了.实在找例子修改麻烦,就做了一个.其实实现挺简单,就是panel或图片什么的跟着鼠标走就行了. 这里panel自己可以加背景图或直接搞个图 ...
- 什么是业务运维,企业如何实现互联网+业务与IT的融合
业务运维并不是一个新概念,针对传统信息架构提出的业务服务管理就是把以业务为核心的IT系统与IT基础设施性能进行整合运维的解决方案.然而随着互联网+转型的不断推进,基础设施的智能化和广泛云化成为IT发展 ...