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

來源:互聯網
上載者:User

編寫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標籤,不能在子標籤裡面)加上這幾行代碼:

 <Viewbox  Name="Viewbox1" Stretch="Fill">
            <Canvas Height="350" Name="Canvas1" Width="525" >

</Viewbox>

</Canvas>


其中Canvas的寬度和高度應該設定為和最開始的window標籤的寬度和高度一樣,這樣之後,只需要在Canvas標籤裡面繼續寫我們想要的布局就可以了,之後控制項會自動進行縮放


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.