1. 程式人生 > >【WPF學習】第二十一章 特殊容器

【WPF學習】第二十一章 特殊容器

  內容控制元件不僅包括基本控制元件,如標籤、按鈕以及工具提示;它們還包含特殊容器,這些容器可用於構造使用者介面中比較大的部分割槽域。

  首先介紹ScrollViewer控制元件,該控制元件直接繼承自ContentControl類,提供了虛擬介面,允許使用者圍繞更大的元素滾動。與所有內容控制元件一樣,ScrollViewer只能包含單個元素,雖然如此,你仍可在內部放置佈局容器來儲存自己需要的任意型別的元素。

  此後將分析附加繼承層中的另外三個控制元件:GroupBox、TabItem以及Expander。所有這些控制元件都繼承自HeaderedContentControl類,HeaderedContentControl又繼承自ContentControl類。HeaderedContentControl類的作用十分簡單,它表示包含單一元素內容(儲存在Content屬性中)和單一元素標題(儲存在Header屬性中)的容器。正是由於添加了標題,才使HeaderedContentControl與前面章節介紹的內容控制元件區別開來。重申一次,可使用標題和或內容的佈局容器,將內容封裝在HeaderedContentControl中。

一、ScrollViewer

  如果希望讓大量內容適應有限的空間,滾動是重要特性之一。在WPF中為了獲得滾動支援,需要在ScrollViewer控制元件中封裝希望滾動的內容。

  儘管ScrollViewer控制元件可以包含任何內容,但通常用來封裝佈局容器。如下示例中,使用Grid元素建立三列,用於顯示文字、文字框和按鈕。為使這個Grid面板能夠滾動,只需將Grid面板封裝到ScrollViewer控制元件中,如下面的標記所示:

 <ScrollViewer Name="scroller">

            <Grid Margin="0,10,0,0" Focusable="False">
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"></RowDefinition>
                    <RowDefinition Height="Auto"></RowDefinition>
                    <RowDefinition Height="Auto"></RowDefinition>
                    <RowDefinition Height="Auto"></RowDefinition>
                    <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="*" MinWidth="50" MaxWidth="800"></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>

                <Label Grid.Row="4" Grid.Column="0" Margin="3"
       VerticalAlignment="Center">Home:</Label>
                <TextBox Grid.Row="4" Grid.Column="1" Margin="3"
             Height="Auto"  VerticalAlignment="Center"></TextBox>
                <Button Grid.Row="4" Grid.Column="2" Margin="3" Padding="2">Browse</Button>

                <Label Grid.Row="5" Grid.Column="0" Margin="3"
             VerticalAlignment="Center">Network:</Label>
                <TextBox Grid.Row="5" Grid.Column="1" Margin="3"
             Height="Auto"  VerticalAlignment="Center"></TextBox>
                <Button Grid.Row="5" Grid.Column="2" Margin="3" Padding="2">Browse</Button>

                <Label Grid.Row="6" Grid.Column="0" Margin="3"
             VerticalAlignment="Center">Web:</Label>
                <TextBox Grid.Row="6" Grid.Column="1" Margin="3"
             Height="Auto"  VerticalAlignment="Center"></TextBox>
                <Button Grid.Row="6" Grid.Column="2" Margin="3" Padding="2">Browse</Button>

                <Label Grid.Row="7" Grid.Column="0" Margin="3"
             VerticalAlignment="Center">Secondary:</Label>
                <TextBox Grid.Row="7" Grid.Column="1" Margin="3"
             Height="Auto"  VerticalAlignment="Center"></TextBox>
                <Button Grid.Row="7" Grid.Column="2" Margin="3" Padding="2">Browse</Button>

            </Grid>

        </ScrollViewer>
ScrollViewer

  最終效果如下圖所示:

 

 

   在該例中,如果改變視窗的尺寸以使視窗足以容納所有內容,將會禁用滾動條。但仍會顯示滾動條,可通過設定VerticalScrollBarVisibility屬性來控制這一行為,該屬性使用ScrollBarVisibility列舉值。預設值 Visible確保總是提供垂直滾動條。如果希望當需要時顯示滾動條而當不需要時不顯示,可將該屬性設定為Auto。如果根本就不希望顯示滾動條,可將該屬性設定為Disable。

  ScrollViewer控制元件也支援水平滾動功能。但預設情況下,HorizontalScrollBarVisibility屬性設定為Hidden。為了使用水平滾動功能,需要將該屬性改為Visible或Auto。

  1、通過程式碼進行滾動

  為滾動上圖中顯示的視窗,可使用滑鼠單擊滾動條,將滑鼠移到網路上並使用滑鼠滾輪進行滾動,可使用Tab鍵檢視控制元件,或單擊網格控制元件的空白處並使用向上或向下的方向鍵進行滾動。如果這些還不夠靈活,還可使用ScrollViewer類提供的方法,通過程式碼來滾動內容:

  •   最明顯的方法是LineUp()和LineDown(),這兩個方法向上和向下移動的效果相當於單擊一次垂直滾動條兩端的箭頭按鈕。
  •   還可使用PageUp()和PageDown()方法,這兩個方法向上或向下滾動一整屏,相當於在滾動滑塊的上面或下面單擊滾動條
  •   用於水平滾動的類似方法包括LineLeft()、LineRight()、PageLeft()和PageRight()
  •   最後,還可使用ScrollToXxx()這一類方法,從而滾動到任何特定位置。對於垂直滾動,包括ScrollToEnd()和ScrollToHome(),這兩個方法可以滾動到內容的頂部和底部。還有ScrollToVerticalOffset(),該方法可滾動到特定位置。對於水平滾動也有類似的方法,包括ScrollToLeftEnd()、ScrollToRightEnd()和ScrollToHorizontalOffset()。

  現在建立一個簡單的示例,程式碼如下所示:

<Window x:Class="Controls.ScrollableTextBoxColumn"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ScrollableTextBoxColumn" Height="230.075" Width="300">
    <DockPanel>
        <Border DockPanel.Dock="Top"  BorderBrush="SteelBlue" BorderThickness="2">
            <StackPanel Margin="5" Orientation="Horizontal">
                <Button Padding="3" Click="LineUp">Line Up</Button>
                <Button Padding="3" Click="LineDown">Line Down</Button>
                <Button Padding="3" Click="PageUp">Page Up</Button>
                <Button Padding="3" Click="PageDown">Page Down</Button>
            </StackPanel>
        </Border>
        <ScrollViewer Name="scroller">

            <Grid Margin="0,10,0,0" Focusable="False">
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"></RowDefinition>
                    <RowDefinition Height="Auto"></RowDefinition>
                    <RowDefinition Height="Auto"></RowDefinition>
                    <RowDefinition Height="Auto"></RowDefinition>
                    <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="*" MinWidth="50" MaxWidth="800"></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>

                <Label Grid.Row="4" Grid.Column="0" Margin="3"
       VerticalAlignment="Center">Home:</Label>
                <TextBox Grid.Row="4" Grid.Column="1" Margin="3"
             Height="Auto"  VerticalAlignment="Center"></TextBox>
                <Button Grid.Row="4" Grid.Column="2" Margin="3" Padding="2">Browse</Button>

                <Label Grid.Row="5" Grid.Column="0" Margin="3"
             VerticalAlignment="Center">Network:</Label>
                <TextBox Grid.Row="5" Grid.Column="1" Margin="3"
             Height="Auto"  VerticalAlignment="Center"></TextBox>
                <Button Grid.Row="5" Grid.Column="2" Margin="3" Padding="2">Browse</Button>

                <Label Grid.Row="6" Grid.Column="0" Margin="3"
             VerticalAlignment="Center">Web:</Label>
                <TextBox Grid.Row="6" Grid.Column="1" Margin="3"
             Height="Auto"  VerticalAlignment="Center"></TextBox>
                <Button Grid.Row="6" Grid.Column="2" Margin="3" Padding="2">Browse</Button>

                <Label Grid.Row="7" Grid.Column="0" Margin="3"
             VerticalAlignment="Center">Secondary:</Label>
                <TextBox Grid.Row="7" Grid.Column="1" Margin="3"
             Height="Auto"  VerticalAlignment="Center"></TextBox>
                <Button Grid.Row="7" Grid.Column="2" Margin="3" Padding="2">Browse</Button>

            </Grid>

        </ScrollViewer>
    </DockPanel>
</Window>
ScrollableTextBoxColumn.xaml
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 Controls
{
    /// <summary>
    /// ScrollableTextBoxColumn.xaml 的互動邏輯
    /// </summary>
    public partial class ScrollableTextBoxColumn : Window
    {
        public ScrollableTextBoxColumn()
        {
            InitializeComponent();
        }
        private void LineUp(object sender, RoutedEventArgs e)
        {
            scroller.LineUp();
        }
        private void LineDown(object sender, RoutedEventArgs e)
        {
            scroller.LineDown();
        }
        private void PageUp(object sender, RoutedEventArgs e)
        {
            scroller.PageUp();
        }
        private void PageDown(object sender, RoutedEventArgs e)
        {
            scroller.PageDown();
        }
    }
}
ScrollableTextBoxColumn.xaml.cs

  最終效果如下所示:

   2、自定義滾動條

  ScrollViewer控制元件內建的滾動功能是很有用的。該功能允許緩慢滾動任何內容,從複雜的向量圖形乃至元素網格。不過,ScrollViewer控制元件最奇特的特徵是允許其包含的內容參與滾動過程。下面是工作原理:

  (1)在ScrollViewer控制元件中放置能滾動的元素,可以是實現了IScrollInfo介面的任意元素。

  (2)通過將ScrollViewer.CanContentScroll屬性設定為true,告訴ScrollViewer控制元件其內容知道如何進行滾動。

  (3)當和ScrollViewer控制元件進行互動時(通過使用滾動條、滑鼠輪和滾動方法等),ScrollViewer控制元件通過IScrollInfo介面來呼叫元素的恰當方法。元素接著執行它自己的自定義滾動功能。

  IScrollInfo介面定義了一套方法,這套方法響應不同的滾動動作。例如,它包含了ScrollViewer控制元件提供的許多滾動方法,如LineUp()、LineDown()、PageUp()以及PageDown()。它還定義了一些處理滑鼠滾輪的方法。

  實現了IScrollInfo介面的元素極少,其中一個元素是StackPanel面板容器。StackPanel類對IScrollInfo介面的實現使用邏輯滾動,從元素滾動到元素,而不是逐行滾動。

  如果在ScrollViewer控制元件中放置StackPanel面板,而且不設定CanContentScroll,將得到普通的滾動行為。一次可向上或向下滾動幾個畫素。但如果將CanContentScroll屬性設定為true,那麼每次單擊時會滾動到下一個元素的開頭:

<ScrollViewer CanContentScroll="True">
        <StackPanel>
            <Button Height="100">1</Button>
            <Button Height="100">2</Button>
            <Button Height="100">3</Button>
            <Button Height="100">4</Button>
        </StackPanel>
    </ScrollViewer>

  StackPanel面板的邏輯滾動系統對應用程式可能有用也可能沒用。但是,如果要建立具有特殊滾動行為的自定義面板,它是必不可少的。

二、GroupBox

  GroupBox是這三個繼承自HeaderedContentControl類的控制元件中最簡單的一個。它顯示為具有圓角和標題的方框。下面是一個示例,下過如下圖所示:

<Window x:Class="Controls.GroupBoxDemo"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="GroupBoxDemo" Height="300" Width="300">
    <Grid>
        <GroupBox Header="A GroupBox Test" Padding="5" Margin="5" VerticalAlignment="Top">
            <StackPanel>
                <RadioButton Margin="3">One</RadioButton>
                <RadioButton Margin="3">Two</RadioButton>
                <RadioButton Margin="3">Three</RadioButton>
                <Button  Margin="3">Save</Button>
            </StackPanel>
        </GroupBox>
    </Grid>
</Window>
GroupBoxDemo

 

 三、TabItem

  TabItem表示TabControl控制元件中的一頁。TabItem類新增的唯一有意義的屬性是IsSelected,該屬性只是選項卡(tab)當前是否顯示在TabControl控制元件中。下面是建立簡單示例:

<Window x:Class="Controls.TabItemDemo"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="TabItemDemo" Height="300" Width="300">
    <TabControl Margin="5">
        <TabItem Header="Tab One">
            <StackPanel Margin="5">
                <CheckBox Margin="3">Setting One</CheckBox>
                <CheckBox Margin="3">Setting Two</CheckBox>
                <CheckBox Margin="3">Setting Three</CheckBox>
            </StackPanel>
        </TabItem>
        <TabItem Header="Tab Two">
            <StackPanel Margin="5">
                <CheckBox Margin="3">Setted One</CheckBox>
                <CheckBox Margin="3">Setted Two</CheckBox>
                <CheckBox Margin="3">Setted Three</CheckBox>
            </StackPanel>
        </TabItem>
    </TabControl>
</Window>
TabItemDemo.xaml

  可以使用TabStripPlacement屬性,使各個選項卡在選項卡控制元件的側邊顯示,而不是在正常頂部位置顯示。

  與Content屬性意義,Header屬性也可以接受任何型別的物件。繼承自UIElement的類通過渲染來顯示,對於內斂文字以及其他所有物件則使用ToString()方法。這意味著可以建立組合框或選項卡,在他們的標題中包含圖形內容或任意元素。下面是一個示例:

<Window x:Class="Controls.GraphicalTabTitles"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="GraphicalTabTitles" Height="300" Width="300">
    <TabControl Margin="5" >
        <TabItem>
            <TabItem.Header>
                <StackPanel>
                    <TextBlock Margin="3">Image and Text Tab Title</TextBlock>
                    <Image Source="happyface.jpg" Stretch="None"></Image>
                </StackPanel>
            </TabItem.Header>
            <StackPanel Margin="5">
                <CheckBox Margin="3">Setting One</CheckBox>
                <CheckBox Margin="3">Setting Two</CheckBox>
                <CheckBox Margin="3">Setting Three</CheckBox>
            </StackPanel>
        </TabItem>
        <TabItem Header="Tab Two">
            <StackPanel Margin="5">
                <CheckBox Margin="3">Setted One</CheckBox>
                <CheckBox Margin="3">Setted Two</CheckBox>
                <CheckBox Margin="3">Setted Three</CheckBox>
            </StackPanel>
        </TabItem>
    </TabControl>
</Window>
GraphicalTabTitles

 

 四、Expander

   最奇特的具有標題的內容控制元件是Expander控制元件。它封裝了一塊內容,通過單擊小箭頭按鈕可以顯示或隱藏所包含的內容。

  使用Expander控制元件是十分簡單的——只需在該控制元件內部包裝希望使其能夠摺疊的內容。通常,每個Expander控制元件開始時都是摺疊的,但可在標記中(或程式碼中)通過設定IsExpanded屬性來改變這種行為。下面是一個簡單Expander示例:

<Window x:Class="Controls.ExpandableContent"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ExpandableContent" Height="300" Width="300" SizeToContent="Height">
    <StackPanel>
        <Expander Margin="5" Padding="5"  Header="Region One"
                  BorderThickness="1" BorderBrush="Black">
            <Button Padding="3">Hidden Button One</Button>
        </Expander>
        <Expander Margin="5" Padding="5" Header="Region Two" 
            BorderThickness="1" BorderBrush="Black">
            <TextBlock TextWrapping="Wrap">
        Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nam mi sapien, viverra et, lacinia varius, ullamcorper sed, sapien. Proin rutrum arcu vitae tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Pellentesque libero dui, eleifend faucibus, auctor at, aliquet a, nulla. Nunc eros. Phasellus mauris nisi, eleifend nec, adipiscing nec, luctus nec, lacus. Aliquam justo metus, vestibulum non, accumsan id, hendrerit at, nibh. Praesent accumsan urna quis tortor. Proin erat libero, facilisis nec, rhoncus ut, malesuada ut, ipsum. Donec id nibh.
            </TextBlock>
        </Expander>
        <Expander Margin="5" Padding="5" Header="Region Three" IsExpanded="True"
              BorderThickness="1" BorderBrush="Black">
            <Button Padding="3">Hidden Button Two</Button>
        </Expander>
    </StackPanel>
</Window>
ExpandableContent

 

 

 

   還可以選擇擴充套件器的方向。上圖使用的是標準值(Down),但也可將ExpandDirection樹上設定為Up、Left或Right。當摺疊Expander時,箭頭始終指向將要展開的方向。

  當使用不同的ExpandDirection值,情況就比較有趣了,因為對使用者介面其他部分的影響取決於容器的型別。有些容器(如WrapPanel面板)只要擠壓其他元素使其離開原來的位置。其他容器,如Grid面板,可以選擇按比例或自動改變大小。下面有一個示例使用不同展開程度,該示例有一個具有4個單元格的網格。每個單元格中都包含一個具有不同展開方向的擴充套件器。例按比例改變其大小,從而強制Expander控制元件中的文字進行換行(自動改變尺寸的列回簡單地被拉伸以適應文字,使它比視窗還大)。行被設定為自動改變尺寸,所以會擴充套件以容納附加的內容。

示例程式碼如下所示:

<Window x:Class="Controls.MultiDirectionExpanders"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MultiDirectionExpanders" Height="327.2" Width="328.8">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition ></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <Expander Margin="5" Padding="5" Header="Region One"
              BorderThickness="1" BorderBrush="Black">
            <TextBlock TextWrapping="Wrap">
        Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
        Nam mi sapien, viverra et, lacinia varius, ullamcorper sed, sapien.
            </TextBlock>
        </Expander>
        <Expander Grid.Column="1" 
      Margin="5" Padding="5" Header="Region Two" ExpandDirection="Right"  
              BorderThickness="1" BorderBrush="Black">
            <TextBlock TextWrapping="Wrap">
        Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
        Nam mi sapien, viverra et, lacinia varius, ullamcorper sed, sapien.
            </TextBlock>
        </Expander>
        <Expander Grid.Row="1"
      Margin="5" Padding="5" Header="Region Three" ExpandDirection="Up"
              BorderThickness="1" BorderBrush="Black">
            <TextBlock TextWrapping="Wrap">
        Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
        Nam mi sapien, viverra et, lacinia varius, ullamcorper sed, sapien.
            </TextBlock>
        </Expander>
        <Expander Grid.Row="1" Grid.Column="1" 
      Margin="5" Padding="5" Header="Region Three" ExpandDirection="Left" 
              BorderThickness="1" BorderBrush="Black">
            <TextBlock TextWrapping="Wrap">
        Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
        Nam mi sapien, viverra et, lacinia varius, ullamcorper sed, sapien.
            </TextBlock>
        </Expander>
    </Grid>
</Window>
MultiDirectionExpanders

 

 

 

 

 

 

 

 

 

   在WPF程式中使用Expander控制元件是非常合適的,因為WPF鼓勵使用流式佈局模型,從而可以很方便地處理會大幅增大或縮小的內容區域。

  如果要使其他控制元件與Expander同步,可處理Expanded和Collapsed事件。這些事件的名稱並未表明其含義,這些事件正好在顯示或隱藏內容前觸發。這兩個事件為實現延遲載入提供一種有用的方法。例如,如果建立Expander控制元件中的內容非常耗時,可能會直到要顯示時才檢索這些內容。或者可能希望在顯示之前更新內容。無論哪種情況,都可以通過響應Expanded事件來執行相應的工作。

  通常,當展開Expander時,它會增大以適應所包含的內容。當展開所有內容後,如果視窗不足以顯示所有內容,這可能會帶來問題。下面是處理該問題的集中策略:

  •   為視窗設定最小尺寸(使用MinWidth和MinHeight屬性),確保視窗在最小時也可以容納所有內容。
  •   設定視窗的SizeToContent屬性,從而當開啟或關閉Expander控制元件時,是視窗自動擴充套件為所需的大小。通常將SizeToContent屬性設定為Manual,但也可以使用Width或Height,以使視窗為了適應所包含的內容在任意方向上擴充套件或收縮。
  •   通過硬編碼Expander控制元件的Height和Widht屬性來限制其尺寸,但當Expander控制元件中的內容太長時,可能會裁剪掉部分內容。
  •   使用ScrollViewer控制元件建立可滾動的擴充套件區域。

  對於大多數情況,這些技術都是非常簡單的。唯一需要進一步說明的是如何組合使用Expander控制元件和ScrollViewer控制元件,為讓這個方法湊效,需要贏編碼ScrollViewer控制元件的尺寸。否則,ScrollViewer控制元件會進行擴充套件以適應它包含的內容。下面是一個示例:

<Window x:Class="Controls.ExpandableScrollableContent"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ExpandableScrollableContent" Height="300" Width="300">
    <StackPanel>
        <Expander Margin="5" Padding="5" Header="Region One">
        </Expander>
        <Expander Margin="5" Padding="5" Header="Region Two" >
            <ScrollViewer Height="50" >
                <TextBlock TextWrapping="Wrap">
          Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nam mi sapien, viverra et, lacinia varius, ullamcorper sed, sapien. Proin rutrum arcu vitae tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Pellentesque libero dui, eleifend faucibus, auctor at, aliquet a, nulla. Nunc eros. Phasellus mauris nisi, eleifend nec, adipiscing nec, luctus nec, lacus. Aliquam justo metus, vestibulum non, accumsan id, hendrerit at, nibh. Praesent accumsan urna quis tortor. Proin erat libero, facilisis nec, rhoncus ut, malesuada ut, ipsum. Donec id nibh.
                </TextBlock>
            </ScrollViewer>
        </Expander>
        <Expander Margin="5" Padding="5" Header="Region Three" IsExpanded="True">
            <Button Padding="3">Hidden Button Two</Button>
        </Expander>
    </StackPanel>
</Window>
ExpandableScrollableContent

 

   如果有一個系統,能讓Expander控制元件根據視窗的可用空間,設定內容區域的尺寸,那將是非常好的。但這會明顯增加複雜度(例如,當Expander控制元件展開時,如果在多個區域共享空間)。Grid佈局容器看起來像是潛在的解決方案,但它不能和Expander控制元件很好地整合。如果嘗試這樣的做的話,當摺疊Expander控制元件時,可能導致非常奇怪的行為,不能正確地更新網格的行高。

&n