【WPF學習】第十章 WPF布局示例


  前幾章用了相當大的篇幅研究有關WPF布局容器的復雜內容。在掌握了這些基礎知識后,就可以研究幾個完整的布局示例。通過研究完整的布局示例,可更好的理解各種WPF布局概念在實際窗口中的工作方式。

一、列設置

  布局容器(如Grid面板)使得窗口創建整個布局結構變得非常容易。例如,分析如下顯示的窗口及設置。該窗口在一個表格結構中排列各個組件——標簽、文本框以及按鈕。

 

   為創建這一表格,首先定義網格的行和列。行定義足夠簡單——只需要將每行的尺寸設置為所含內容的高度。這意味着所有行都將使用最大元素的高度,在該示例中,最大的元素是第三列中的Browse按鈕。

  接下來需要創建列。第一列和最后一列的尺寸要適合其內容(分別是標簽文本和Browse按鈕)。中間列占用所有剩余空間,這意味着當窗口變大時,該列的尺寸會增加,這樣可有更大的空間顯示選擇的文件夾(如果希望拉伸不超過一定的最大寬度,在定義列時可使用MaxWidth屬性,就像對單個元素使用MaxWidth屬性一樣)。

  現在已經具備了基本結構,接下來只需要在恰當的單元格中放置元素。然而,還需要仔細考慮邊距和對其方式。每個元素需要基本的邊距(3個單位較恰當)以在其周圍添加一些空間。此外,標簽和文本框的垂直方向上需要劇中,因為他們沒有Browse按鈕高。最后,文本框需要使用自動設置尺寸模式,這樣它會被拉伸以充滿整列。

  示例完整的代碼如下所示:

<Window x:Class="LayoutDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid Margin="3,3,10,3">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"></ColumnDefinition>
            <ColumnDefinition Width="*"></ColumnDefinition>
            <ColumnDefinition Width="Auto"></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <Label Grid.Row="0" Grid.Column="0" Margin="3" VerticalAlignment="Center">Home:</Label>
        <TextBox Grid.Row="0" Grid.Column="1" Margin="3" Height="Auto" VerticalAlignment="Center"></TextBox>
        <Button Grid.Row="0" Grid.Column="2" Margin="3" Padding="2">Browse</Button>
        <Label Grid.Row="1" Grid.Column="0" Margin="3" VerticalAlignment="Center">Network:</Label>
        <TextBox Grid.Row="1" Grid.Column="1" Margin="3" Height="Auto" VerticalAlignment="Center"></TextBox>
        <Button Grid.Row="1" Grid.Column="2" Margin="3" Padding="2">Browse</Button>
        <Label Grid.Row="2" Grid.Column="0" Margin="3" VerticalAlignment="Center">Web:</Label>
        <TextBox Grid.Row="2" Grid.Column="1" Margin="3" Height="Auto" VerticalAlignment="Center"></TextBox>
        <Button Grid.Row="2" Grid.Column="2" Margin="3" Padding="2">Browse</Button>
        <Label Grid.Row="3" Grid.Column="0" Margin="3" VerticalAlignment="Center">Secondary:</Label>
        <TextBox Grid.Row="3" Grid.Column="1" Margin="3" Height="Auto" VerticalAlignment="Center"></TextBox>
        <Button Grid.Row="3" Grid.Column="2" Margin="3" Padding="2">Browse</Button>
    </Grid>
</Window>

  一個不是非常明顯的事實是,因為使用了Grid控件,所以該窗口時非常靈活的。沒有任何一個元素——標簽、文本框以及按鈕——時通過硬編碼來定位和設置尺寸的。因此,可通過簡單地修改ColumnDefinition元素來快速改變整個網絡。甚至,如果添加了包含更長標簽文本的行(迫使第一列更寬),就會調整整個網格使其保持一致,包括已經添加的行。如果希望在兩行之間添加元素——例如,添加分割線以區分窗口的不同部分——可保持網格的列定義不變,但使用ColumnSpan屬性拉伸某個元素,使其覆蓋更大的區域。

二、動態內容

  與上面的演示的列設置一樣,當修訂應用程序時,可方便地修改使用WPF布局容器的窗口並且可以很容易地時窗口適應對應用程序的修訂。這樣的靈活性不僅能使開發人員在設計時受益,而且如果需要顯示在運行時變化很大的內容,這樣是非常有用的。

  一個例子是本地化文本——對於不同的區域,在用戶界面中顯示的文本需要翻譯成不同的語言。在老式的基於坐標的應用程序中,改變窗口中的文本會造成混亂,部分原因是少了英語文本翻譯成許多語言后會變得特別大。盡管允許改變元素的尺寸以適應更大的文本,但這樣做警察會使整體窗口失去平衡。

  下圖演示WPF布局控件時如何聰明地解決這一問題。在這個示例中,用戶界面可選擇短文本和長文本。當使用長文本時,包含文本的按鈕會自動改變其尺寸,而對其他內容也會相應的調整位置。並且因此改變了尺寸的按鈕共享同一布局容器(在該例中是一個表格列),所以整個用戶界面都會改變尺寸。最終結果是所有按鈕保持一致的尺寸——最大按鈕的尺寸。

               

 

  為實現這個效果,窗口使用一個具有兩行兩列的表格進行分割。左邊的列包含可改變大小的按鈕,而右邊的列包含文本框。底行用於放置Close按鈕,底行和頂行位於同一個表格中,從而可以根據頂行改變尺寸。

  示例完整代碼如下所示:

<Window x:Class="LayoutDemo.LayoutWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="LayoutWindow" Height="300" Width="300">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"></ColumnDefinition>
            <ColumnDefinition Width="*"></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <StackPanel Grid.Row="0" Grid.Column="0">
            <Button Name="btnPrev" Margin="10,10,10,3">Prev</Button>
            <Button Name="btnNext" Margin="10,3,10,3">Next</Button>
            <CheckBox Name="chkLongText" Margin="10,10,10,10"  Checked="chkLongText_Checked" Unchecked="chkLongText_UnChecked">Show Long Text</CheckBox>
        </StackPanel>
        <TextBox Grid.Row="0" Grid.Column="1" Margin="0,10,10,10" TextWrapping="Wrap" Grid.RowSpan="2">
            This is a test that demonstrates how buttons adapt themselfes to fit the content they contain when they aren't explicitly sized.This behavior makes localization much easier.
        </TextBox>
        <Button Grid.Row="1" Grid.Column="0" Name="btnClose" Margin="10,3,10,10">
            Close
        </Button>
    </Grid>
</Window>

  后台代碼如下所示:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace LayoutDemo
{
    /// <summary>
    /// LayoutWindow.xaml 的交互邏輯
    /// </summary>
    public partial class LayoutWindow : Window
    {
        public LayoutWindow()
        {
            InitializeComponent();
        }

        

        private void chkLongText_Checked(object sender, RoutedEventArgs e)
        {
            this.btnPrev.Content = "<-Go to the Previous Window";
            this.btnNext.Content = "Go to the Next Window ->";
        }

        private void chkLongText_UnChecked(object sender, RoutedEventArgs e)
        {
            this.btnPrev.Content = "Prev";
            this.btnNext.Content = "Next";
        }
    }
}

  Visiblity屬性是UIEelement基類的一部分,因此放置於WPF窗口中的任何內容都支持該屬性。該屬性可使用三個值,它們來自System.Windows.Visiblity枚舉,如下表所示:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM