主頁 > .NET開發 > 【WPF學習】第二十一章 特殊容器

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

2020-09-11 14:23:57 .NET開發

  內容控制元件不僅包括基本控制元件,如標簽、按鈕以及工具提示;它們還包含特殊容器,這些容器可用于構造用戶界面中比較大的部磁區域,

  首先介紹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控制元件時,可能導致非常奇怪的行為,不能正確地更新網格的行高,

 

轉載請註明出處,本文鏈接:https://www.uj5u.com/net/5925.html

標籤:WPF

上一篇:【Azure DevOps系列】使ASP.NET Core應用程式托管到Azure Web App Service

下一篇:少量代碼設計一個登錄界面 - .NET CORE(C#) WPF開發

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • WebAPI簡介

    Web體系結構: 有三個核心:資源(resource),URL(統一資源識別符號)和表示 他們的關系是這樣的:一個資源由一個URL進行標識,HTTP客戶端使用URL定位資源,表示是從資源回傳資料,媒體型別是資源回傳的資料格式。 接下來我們說下HTTP. HTTP協議的系統是一種無狀態的方式,使用請求/ ......

    uj5u.com 2020-09-09 22:07:47 more
  • asp.net core 3.1 入口:Program.cs中的Main函式

    本文分析Program.cs 中Main()函式中代碼的運行順序分析asp.net core程式的啟動,重點不是剖析原始碼,而是理清程式開始時執行的順序。到呼叫了哪些實體,哪些法方。asp.net core 3.1 的程式入口在專案Program.cs檔案里,如下。ususing System; us ......

    uj5u.com 2020-09-09 22:07:49 more
  • asp.net網站作為websocket服務端的應用該如何寫

    最近被websocket的一個問題困擾了很久,有一個需求是在web網站中搭建websocket服務。客戶端通過網頁與服務器建立連接,然后服務器根據ip給客戶端網頁發送資訊。 其實,這個需求并不難,只是剛開始對websocket的內容不太了解。上網搜索了一下,有通過asp.net core 實作的、有 ......

    uj5u.com 2020-09-09 22:08:02 more
  • ASP.NET 開源匯入匯出庫Magicodes.IE Docker中使用

    Magicodes.IE在Docker中使用 更新歷史 2019.02.13 【Nuget】版本更新到2.0.2 【匯入】修復單列匯入的Bug,單元測驗“OneColumnImporter_Test”。問題見(https://github.com/dotnetcore/Magicodes.IE/is ......

    uj5u.com 2020-09-09 22:08:05 more
  • 在webform中使用ajax

    如果你用過Asp.net webform, 說明你也算是.NET 開發的老兵了。WEBform應該是2011 2013左右,當時還用visual studio 2005、 visual studio 2008。后來基本都用的是MVC。 如果是新開發的專案,估計沒人會用webform技術。但是有些舊版 ......

    uj5u.com 2020-09-09 22:08:50 more
  • iis添加asp.net網站,訪問提示:由于擴展配置問題而無法提供您請求的

    今天在iis服務器配置asp.net網站,遇到一個問題,記錄一下: 問題:由于擴展配置問題而無法提供您請求的頁面。如果該頁面是腳本,請添加處理程式。如果應下載檔案,請添加 MIME 映射。 WindowServer2012服務器,添加角色安裝完.netframework和iis之后,運行aspx頁面 ......

    uj5u.com 2020-09-09 22:10:00 more
  • WebAPI-處理架構

    帶著問題去思考,大家好! 問題1:HTTP請求和回傳相應的HTTP回應資訊之間發生了什么? 1:首先是最底層,托管層,位于WebAPI和底層HTTP堆疊之間 2:其次是 訊息處理程式管道層,這里比如日志和快取。OWIN的參考是將訊息處理程式管道的一些功能下移到堆疊下端的OWIN中間件了。 3:控制器處理 ......

    uj5u.com 2020-09-09 22:11:13 more
  • 微信門戶開發框架-使用指導說明書

    微信門戶應用管理系統,采用基于 MVC + Bootstrap + Ajax + Enterprise Library的技術路線,界面層采用Boostrap + Metronic組合的前端框架,資料訪問層支持Oracle、SQLServer、MySQL、PostgreSQL等資料庫。框架以MVC5,... ......

    uj5u.com 2020-09-09 22:15:18 more
  • WebAPI-HTTP編程模型

    帶著問題去思考,大家好!它是什么?它包含什么?它能干什么? 訊息 HTTP編程模型的核心就是訊息抽象,表示為:HttPRequestMessage,HttpResponseMessage.用于客戶端和服務端之間交換請求和回應訊息。 HttpMethod類包含了一組靜態屬性: private stat ......

    uj5u.com 2020-09-09 22:15:23 more
  • 部署WebApi隨筆

    一、跨域 NuGet參考Microsoft.AspNet.WebApi.Cors WebApiConfig.cs中配置: // Web API 配置和服務 config.EnableCors(new EnableCorsAttribute("*", "*", "*")); 二、清除默認回傳XML格式 ......

    uj5u.com 2020-09-09 22:15:48 more
最新发布
  • C#多執行緒學習(二) 如何操縱一個執行緒

    <a href="https://www.cnblogs.com/x-zhi/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2943582/20220801082530.png" alt="" /></...

    uj5u.com 2023-04-19 09:17:20 more
  • C#多執行緒學習(二) 如何操縱一個執行緒

    C#多執行緒學習(二) 如何操縱一個執行緒 執行緒學習第一篇:C#多執行緒學習(一) 多執行緒的相關概念 下面我們就動手來創建一個執行緒,使用Thread類創建執行緒時,只需提供執行緒入口即可。(執行緒入口使程式知道該讓這個執行緒干什么事) 在C#中,執行緒入口是通過ThreadStart代理(delegate)來提供的 ......

    uj5u.com 2023-04-19 09:16:49 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    <a href="https://www.cnblogs.com/huangxincheng/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/214741/20200614104537.png" alt="" /&g...

    uj5u.com 2023-04-18 08:39:04 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    一:背景 1. 講故事 前段時間協助訓練營里的一位朋友分析了一個程式卡死的問題,回過頭來看這個案例比較經典,這篇稍微整理一下供后來者少踩坑吧。 二:WinDbg 分析 1. 為什么會卡死 因為是表單程式,理所當然就是看主執行緒此時正在做什么? 可以用 ~0s ; k 看一下便知。 0:000> k # ......

    uj5u.com 2023-04-18 08:33:10 more
  • SignalR, No Connection with that ID,IIS

    <a href="https://www.cnblogs.com/smartstar/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/u36196.jpg" alt="" /></a>...

    uj5u.com 2023-03-30 17:21:52 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:15:33 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:13:31 more
  • C#遍歷指定檔案夾中所有檔案的3種方法

    <a href="https://www.cnblogs.com/xbhp/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/957602/20230310105611.png" alt="" /></a&...

    uj5u.com 2023-03-27 14:46:55 more
  • C#/VB.NET:如何將PDF轉為PDF/A

    <a href="https://www.cnblogs.com/Carina-baby/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2859233/20220427162558.png" alt="" />...

    uj5u.com 2023-03-27 14:46:35 more
  • 武裝你的WEBAPI-OData聚合查詢

    <a href="https://www.cnblogs.com/podolski/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/616093/20140323000327.png" alt="" /><...

    uj5u.com 2023-03-27 14:46:16 more