天天看點

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

  内容控件不僅包括基本控件,如标簽、按鈕以及工具提示;它們還包含特殊容器,這些容器可用于構造使用者界面中比較大的部分區域。

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

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

一、ScrollViewer

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

  盡管ScrollViewer控件可以包含任何内容,但通常用來封裝布局容器。如下示例中,使用Grid元素建立三列,用于顯示文本、文本框和按鈕。為使這個Grid面闆能夠滾動,隻需将Grid面闆封裝到ScrollViewer控件中,如下面的标記所示:

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

<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

  最終效果如下圖所示:

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

   在該例中,如果改變視窗的尺寸以使視窗足以容納所有内容,将會禁用滾動條。但仍會顯示滾動條,可通過設定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()。

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

【WPF學習】第二十一章 特殊容器
【WPF學習】第二十一章 特殊容器
<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

【WPF學習】第二十一章 特殊容器
【WPF學習】第二十一章 特殊容器
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

  最終效果如下所示:

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

   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類的控件中最簡單的一個。它顯示為具有圓角和标題的方框。下面是一個示例,下過如下圖所示:

【WPF學習】第二十一章 特殊容器
【WPF學習】第二十一章 特殊容器
<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

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

 三、TabItem

  TabItem表示TabControl控件中的一頁。TabItem類添加的唯一有意義的屬性是IsSelected,該屬性隻是頁籤(tab)目前是否顯示在TabControl控件中。下面是建立簡單示例:

【WPF學習】第二十一章 特殊容器
【WPF學習】第二十一章 特殊容器
<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

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

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

  與Content屬性意義,Header屬性也可以接受任何類型的對象。繼承自UIElement的類通過渲染來顯示,對于内斂文本以及其他所有對象則使用ToString()方法。這意味着可以建立組合框或頁籤,在他們的标題中包含圖形内容或任意元素。下面是一個示例:

【WPF學習】第二十一章 特殊容器
【WPF學習】第二十一章 特殊容器
<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

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

 四、Expander

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

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

【WPF學習】第二十一章 特殊容器
【WPF學習】第二十一章 特殊容器
<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

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

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

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

示例代碼如下所示:

【WPF學習】第二十一章 特殊容器
【WPF學習】第二十一章 特殊容器
<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學習】第二十一章 特殊容器
【WPF學習】第二十一章 特殊容器
【WPF學習】第二十一章 特殊容器

   在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控件會進行擴充以适應它包含的内容。下面是一個示例:

【WPF學習】第二十一章 特殊容器
【WPF學習】第二十一章 特殊容器
<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

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

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

作者:Peter Luo

出處:https://www.cnblogs.com/Peter-Luo/

本文版權歸作者和部落格園共有,歡迎轉載,但必須給出原文連結,并保留此段聲明,否則保留追究法律責任的權利。

繼續閱讀