利用WPF建立自適應窗口大小布局的WinForm窗口

作者: 萬倉一黍  來源: 博客園  發布時間: 2010-11-18 22:08  閱讀: 5016 次  推薦: 0   原文鏈接   [收藏]  

  編寫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來實現自適應窗體的大小確是獨辟蹊徑。

0
0
 
標簽:WPF
 
 

文章列表

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()