一起谈.NET技术,利用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来实现自适应窗体的大小确是独辟蹊径。

时间: 2024-10-16 05:39:21

一起谈.NET技术,利用WPF建立自适应窗口大小布局的WinForm窗口的相关文章

利用WPF建立自适应窗口大小布局的WinForm窗口

编写WinForm程序时,都会碰到一个问题.就是WinForm窗口在不同分辨率下的大小问题.举例说明,你编写的WinForm窗口在1024×768下是合适.匀称的.不过,如果用户的计算机的分辨率为1400×900时,你的WinForm窗口就显得偏小,其中的字体和控件都显得偏小.如果用户的分辨率为640×480,那你的窗口就远远超过它的屏幕的大小. 如何解决这个问题?一般的WinForm程序都会这样操作:程序启动-->获取屏幕分辨率-->调整窗体的大小-->调整各个控件大小及位置-->

一起谈.NET技术,WPF企业内训全程实录(上)

一. 摘要 圣殿骑士由于工作和项目需要,所以对一些技术进行了较为深入的研究,之前在整个公司做过一些技术专场的培训,由于每次时间较短且人员较多的关系,没能讲得很透彻.一直都想以文字的形式把这些培训细节写出来,但是发现进度确实很慢,所以先来几篇宏观的讲解,希望能起到"授人与鱼也授人以渔"的效果.今天我们就来分享一下WPF内训之旅,这篇文章以WPF培训为主线,中间贯穿了一些其他技术和使用心得.其他培训专题诸如"OO到设计模式"."WCF基础到企业应用"

一起谈.NET技术,WPF 基础到企业应用系列1——开篇有益

1.开篇前言 关于本人--圣殿骑士刚入住博客园和51CTO写技术博客,目前主要在一家外资企业从事项目管理.技术架构及企业技术培训工作.由于工作和项目需要,所以对一些技术进行了较为深入的研究,之前在整个公司做过一些技术专场的培训,由于每次时间较短且人员较多的关系,没能讲得很透彻,所以挺对不住那些同事的.现在在园子里开一个博客,希望能把所学的微薄知识书写出来,以供大家参考.近期将针对这些培训专场推出"OO到设计模式"."WCF基础到企业应用"."WPF基础到企

一起谈.NET技术,WPF 企业内训全程实录(中)

摘要 WPF企业内训全程实录由于文章比较长,所以一共拆分成了三篇,上篇WPF企业内训全程实录(上)主要讲了基础,这篇作为该实录的中篇,起着承上启下的作用,主要讲解开发模式.团队协作及应用框架.其实如果大家仔细看目录,可以发现我安排的顺序是首先讲解最基本的概念和基础内容.然后过渡到开发模式及框架.最后结合其他技术和项目实际运用,这也是学习并应用一门技术最好的流程.上篇实际上主要有两个侧重点:一则就是理清脉络--历史渊源.概念引入及基本阐述:二则是讲解WPFBasic--主要讲解WPF的每个知识点,

一起谈.NET技术,WPF 基础到企业应用系列3——WPF开发漫谈

1.开篇前言      首先很高兴这个系列能得到大家的关注和支持,基于对大家负责和对自己负责的态度,我会不断努力写好这个系列,分享自己的微薄技术和经验,希望在帮助别人的同时也不断提升自己.由于这篇文章稍多,所以读者花的时间长了一些,也希望大家能够见谅,这个系列以后会每周发三到四篇左右(主要是写一篇差不多要花几晚上,感觉思维比较发散),除了讲WPF技术本身之外,也会讲一些项目具体开发,所以敬请关注.在前两次的文章中我们对WPF有了一个比较全面的认识,那么在本篇文章当中,除了讲一些理论知识外,我们会

一起谈.NET技术,WPF 基础到企业应用系列4——WPF千年轮回

1.开篇前言      首先很高兴这个系列能得到大家的关注和支持,基于对大家负责和对自己负责的态度,我会不断努力写好这个系列,分享自己的微薄技术和经验,希望在帮助别人的同时也不断提升自己.由于这篇文章很多(现已拆分成2篇,今天这篇只是其中之一),一共花了几个个晚上的休息时间才完成,所以读者花的时间长了一些,也希望大家能够见谅,这个系列以后会每周发三到四篇左右(主要是写一篇差不多要花几晚上,感觉思维比较发散),除了讲WPF技术本身之外,也会讲一些项目具体开发,所以敬请关注.     本篇文章取名为

一起谈.NET技术,WPF 基础到企业应用系列2——WPF前世今生

1.开篇前言      很多时候了解一项新技术的历史和趋势往往比这项技术的本身价值还要重要.WPF作为一项新技术(已经三年多了,或者应该叫老技术了),我们都有必要了解它的来龙去脉,尤其是公司的CTO.技术总监.架构师等决策层,因为他们对技术的选型及应用具有决定权.对于开发者来说,了解自己正在从事的这个技术的前世今生,有助于我们更好的认识技术本身的价值,也可以避免我们少走一些弯路(圣殿骑士 就走过很多弯路,所以对此比较感慨).从IT技术发展的这些年可以看出,技术对于各大公司只是竞争的一种手段,而对

一起谈.NET技术,WPF/Silverlight深度解决方案:目录

介于目前WPF/Silverlight技术资料在国内相当稀缺,仅有的也是一些很基础的教程.为了更深度的剖析WPF/Silverlight的技术内涵,解决开发过程中的疑难杂症,分解实际应用案例的特色细节,"WPF/Silverlight深度解决方案"系列由此孕育而生.整个系列的所有文章均为原创,由本人的个人开发经验结合相关资料编写而成,过程中难免有错漏或不妥当的地方还望各位读者友善的指出.我们的目标只有一个:WPF/Silverlight技术深度挖掘.如果您有符合本系列主题的内容想要与大

一起谈.NET技术,WPF Multi-Touch 开发:基础触屏操作(Raw Touch)

多点触控(Multi-Touch)就是通过与触屏设备的接触达到人与应用程序交互的操作过程.例如,生活中经常使用的触屏手机.触屏笔记本.显示器以及微软最新的Surface 产品等这些都属于触屏操作设备.本篇将介绍如何开发能够支持MT 功能的应用程序. 在WPF 4 中已经具备的多点触控开发技术,当多个手指触碰到触屏设备时,WPF 会把每跟手指认为是一个触控设备,并为其分配唯一的识别ID,以便跟踪不同手指的操作手势.下面将通过实例演示WPF 所支持的低级别触控操作:触碰(TouchDown).分离(