[WPF]建立自適應視窗大小佈局的WinForm視窗

来源:http://www.cnblogs.com/masonlu/archive/2016/03/10/5261954.html
-Advertisement-
Play Games

編寫WinForm程式時,都會碰到一個問題。就是WinForm視窗在不同解析度下的大小問題。舉例說明,你編寫的WinForm視窗在1024×768下是合適、勻稱的。不過,如果用戶的電腦的解析度為1400×900時,你的WinForm視窗就顯得偏小,其中的字體和控制項都顯得偏小。如果用戶的解析度為64


編寫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標簽裡面繼續寫我們想要的佈局就可以了,之後控制項會自動進行縮放


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一般簡單的樣式我們可以直接寫在控制項中 <Button Canvas.Left="20" Canvas.Top="30" Width="100" Height="120" Content="A"/> 也可以通過Style屬性定義該系列控制項的樣式 <Style TargetType="{x:Type B
  • 1. 8K 對應的SQL語句限制 select * from openquery (recei 連接伺服器名稱 執行的sql 語句放在 SELECT @@SERVERNAME 在本地進行執行 2. 使用 工具進行搭建主從伺服器 和對應的同步複製伺服器 1.SQL Server Proxy Servi
  • 集合(collection)提供了一種結構化組織任意對象的方式,從廣義的概念上講,數組、枚舉和結構等組合都是集合的一種表現,其內部的元素組織方式也都與集合的定義非常類似。但在C#中,集合這一專有名詞特指System.Collections命名空間下的各種子類,數組、枚舉和結構都不是System.Co
  • 根據大牛的方案修改的自己使用的Actor!
  • 關於C# webform 項目發佈 註意:aspx頁面無任何代碼,每個頁面都以dll形式發佈帶bin文件夾里 具體操作方法如下圖:
  • Line 在兩個坐標點之間畫一條直線,通過四個屬性設置它的起始和結束 <Line Stroke="Blue" StrokeThickness="3" X1="20" Y1="20" X2="300" Y2="20"></Line> 如果線條是畫在Canvas畫布中,那麼Canvas的附加屬性Top和
  • 經過上面的折騰,我成功用批處理編譯 .NET Framework 4.5.2 項目後, 我並未滿足, 我想要更方便的, 無須安裝那麼多操蛋的東西, 只需要有運行時環境就可以了, 行不行? 答案當然是可以的, 那便是近年漸火的 roslyn 開源項目.
  • 程式效果 最終得到程式的運行效果如圖。拖動Slider可以使按鈕的背景色出現相應變化。 需求分析和架構設計 如果是你,接到了這樣的一個程式設計要求,會怎樣思考?第一步當然是需求分析啦。這個程式相對簡單,需要分析的主要是各個控制項之間的數據聯繫。這主要體現在Slider, Textbox和Button間
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...