6 WPF控件

WPF控件分類:html

  • 內容控件
  • 標題內容控件
  • 文本控件
  • 列表控件
  • 基於範圍的控件
  • 日期控件

控件類

控件是與用戶交互的元素。控件能夠得到焦點,能接受鍵盤或鼠標的輸入。編程

全部控件的基類是System.Windows.Control類,這類包括一些基本功能:app

  • 對齊
  • tab序列
  • 背景、前景、邊界
  • 文本內容的字體

背景和前景刷子

控件包括兩個屬性Background和Foreground屬性,這兩個屬性使用Brush對象。刷子對象的派生類包括SolidColorBrush、LinearGradientBrush、和TileBrush類。ide

用代碼設置顏色

爲名爲cmd的按鈕設置背景色:函數

cmd.Background = new SolidColorBrush(Colors.AliceBlue);

經過Colors類的靜態屬性得到預約義的顏色,將它傳遞給構造函數建立一個新的SolidColorBrush實例,將它賦值給按鈕的背景屬性。佈局

也可以使用系統顏色:性能

cmd.Background = new SolidColorBrush(SystemColors.ControlColor);

SystemColors類也提供預製的屬性返回SolidColorBrush對象:字體

cmd.Background = SystemColors.ControlBrush;

你能創造一個顏色對象,依靠提供R,G,B值(紅綠藍)。每一個值是從0到255一個數字:ui

int red = 0; int green = 255; int blue = 0;
cmd.Foreground = new SolidColorBrush(Color.FromRgb(red, green, blue));

你能設置顏色的透明度,經過調用Color.FromArgb()方法,爲其傳遞alpha值。alpha值爲255是徹底不透明,而爲0是徹底透明。spa

用XAML設置顏色

在XAML中,只須要提供顏色的名字或顏色值,其餘的工做由解析器負責。

<Button Background="Red">A Button</Button>

用 #rrggbb 或 #aarrggbb格式提供顏色值:

<Button Background="#FFFF0000">A Button</Button>

刷子支持自動改變通知。刷子從System.Windows.Freezable類派生而來。Freezable類有兩個狀態:可讀狀態,只讀狀態(凍結)

控件類還定義了BorderBrush和BorderThickness屬性。

字體

Control類定義幾個字體相關的屬性。決定控件文本的外觀。這些屬性列在表6-1。

名字 描述
FontFamily  
FontSize  
FontStyle  
FontWeight  
FontStretch  

Control類沒有定義任何使用它字體的屬性。然而許多控件包括Text屬性,沒有定義爲Control基類的成員。明顯地,除非被派生類使用,字體屬性沒有任何意義。

字體家族

 

鼠標光標

內容控件

內容控件是更特殊的控件類型,它能擁有並顯示一件內容。技術上,內容控件是能包含單個嵌套元素的控件。內容控件與佈局容器的區別是,內容控件只能包含一個子元素,而佈局容器能夠擁有任意個子元素。

固然,你仍然能把多個內容包裝到內容控件中。訣竅是把它們都包裹到單個容器中,諸如一個StackPanel、或一個Grid。例如,Window類自己是一個內容控件。明顯地,窗口常常有大量內容,可是,它們都被包裹在一頂層的容器中(典型地,Grid)。

全部的內容控件起源於ContentControl抽象類。內容控件類主要包括:一些公共控件Label、ToolTip。各類按鈕控件Button、RadioButton、CheckBox。一些更專用的ScrollViewer、UserControl。Window自己是個內容控件。

最後,存在一個內容控件子集,依靠從HeaderedContentControl類派生,增長了一層繼承。包括GroupBox,TabItem,和Expander控件。這些控件有內容區域和標題區域,標題區域用於顯示某種標題。

另外,用於導航的Frame、用於其餘控件內部的ListBoxItem、StatusBarItem等也是內容控件。

Content屬性

ContentControl類添加一個Content屬性,接受單個對象。Content屬性支持任何類型的對象,可是它把對象分爲兩組,而且區別對待:

  • 不派生自UIElement的對象:內容控件調用ToString()得到這些控件的文本,而後顯示文本。
  • 派生自UIElement的對象:這些對象包括全部可視元素。使用UIElement.OnRender()方法,被顯示在內容控件內部。

例如,一個提供簡單字符串的按鈕:

<Button Margin="3">Text content</Button>

使用Image類放置一個圖像到按鈕內:

<Button Margin="3">
  <Image Source="happyface.jpg" Stretch="None" />
</Button>

放置一個包裹圖像和文本的容器到按鈕內:

<Button Margin="3">
  <StackPanel>
    <TextBlock Margin="3">Image and text button</TextBlock>
    <Image Source="happyface.jpg" Stretch="None" />
    <TextBlock Margin="3">Courtesy of the StackPanel</TextBlock>
  </StackPanel>
</Button>

甚至能夠在按鈕中放置其餘內容控件,如文本框,按鈕、組合框。雖然這樣作不太合理,可是WPF容許這樣。

Window是內容控件,可是他只能是頂級容器,不能嵌套在其餘元素中。

內容控件的其餘屬性包括:

HasContent屬性,爲真時表示控件有內容。

ContentTemplate屬性,是一個告訴控件如何顯示對象的模板。使用ContentTemplate,更智能地顯示非UIElement派生來的對象。你能夠獲取對象的各類屬性值,並整理放入更復雜的標記中。

對齊內容

HorizontalContentAlignment、VerticalContentAlignment取值爲Top, Bottom, Left, Right、Center、Stretch

Padding屬性指控件邊界到其內容的距離。

HorizontalContentAlignment,VerticalContentAlignment,和Padding屬性定義在Control類中,不在更特殊的ContentControl類。由於,一些不是內容控件的控件也有某種內容。例如,TextBox不是內容控件,它使用上述屬性設置輸入文本。

WPF內容哲學

內容控件減小了控件的數量,可是,增長了一點控件的複雜度。

標籤(Label)

標籤控件主要的功能是助記鍵,使連接控件得到焦點的快捷鍵。標籤控件的Target屬性指定連接控件。爲了設置Target,使用綁定表達式指向另外一個控件。

<Label Target="{Binding ElementName=txtA}">Choose _A</Label>
<TextBox Name="txtA"></TextBox>
<Label Target="{Binding ElementName=txtB}">Choose _B</Label>
<TextBox Name="txtB"></TextBox>

標籤文本下劃線指明快捷鍵。若是真須要一個下劃線,能夠連續輸入兩個下劃線轉義。

同時按下Alt和所指定的快捷鍵,連接的控件就會得到焦點。例如,在本例中,按下Alt+A,焦點就會跳到txtA控件。

若是不須要助記鍵功能,能夠考慮使用TextBlock。

按鈕類的控件

按鈕類的控件包括Button、CheckBox、和RadioButton。他們都從ButtonBase派生。

Click支持命令功能。

ClickMode屬性,ClickMode.Release,ClickMode.Press,ClickMode.Hover

按鈕也支持快捷鍵。

按鈕

每一個窗口能夠有取消按鈕和默認按鈕,經過設置按鈕的IsCancel、IsDefault屬性。詳見159頁。

另外,還有一個容易混淆的IsDefaulted屬性,見160頁側邊條。

ToggleButton、RepeatButton

從ButtonBase派生的類還有三個:

  • GridViewColumnHeader
  • RepeatButton
  • ToggleButton

RepeatButton 和ToggleButton都位於System.Windows.Controls.Primitives名字空間。經常使用於組合、或派生成其餘控件,也能夠單獨使用。

CheckBox

CheckBox和RadioButton都是從ToggleButton派生。

ToggleButton添加了一個IsChecked屬性,它是一個可空布爾值。

爲了在WPF標記中分配一個空值,使用空標記擴展,以下所示:

<CheckBox IsChecked="{x:Null}">A check box in indeterminate state</CheckBox>

ToggleButton還有一個IsThreeState屬性,它決定是否能夠設置複選框爲未定態。默認爲false。

ToggleButton類定義三事件:Checked,Unchecked,和Indeterminate事件。

RadioButton

默認狀況下,單選按鈕按它們的容器分組。RadioButton的GroupName屬性容許你覆蓋這行爲。

<StackPanel>
  <GroupBox Margin="5">
    <StackPanel>
      <RadioButton>Group 1</RadioButton>
      <RadioButton>Group 1</RadioButton>
      <RadioButton>Group 1</RadioButton>
      <RadioButton Margin="0,10,0,0" GroupName="Group2">Group 2</RadioButton>
    </StackPanel>
  </GroupBox>
  <GroupBox Margin="5">
    <StackPanel>
      <RadioButton>Group 3</RadioButton>
      <RadioButton>Group 3</RadioButton>
      <RadioButton>Group 3</RadioButton>
      <RadioButton Margin="0,10,0,0" GroupName="Group2">Group 2</RadioButton>
    </StackPanel>
  </GroupBox>
</StackPanel>

不須要使用GroupBox容器包裹單選按鈕組,但這是一個廣泛的約定。GroupBox顯示一個邊界和一個標題。

專用的容器

內容控件也包括一些專用的容器。

ScrollViewer直接從ContentControl繼承。

ContentControl類派生了HeaderedContentControl類,這個類包括一個標題和一個內容。標題和內容均可以嵌套單個子元素。HeaderedContentControl類派生了幾個子類:GroupBox,TabItem,和Expander。

ScrollViewer

儘管ScrollViewer能包裹任何元素,可是通常狀況下,它包裹一個佈局容器。

<ScrollViewer>
  <Grid Margin="3,3,10,3">
  </Grid>
</ScrollViewer>

VerticalScrollBarVisibility屬性,此屬性是ScrollBarVisibility枚舉。Visible、Auto、Disabled。默認值是Visible。

HorizontalScrollBarVisibility屬性,默認值是Hidden。

編程控制滾動

詳見171頁。

自定義滾動

詳見172頁。

GroupBox

GroupBox從HeaderedContentControl類派生。

<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>

GroupBox仍然要求一個佈局容器佈置內容。GroupBox沒有特別的功能,只是一個裝飾控件。

TabItem

TabItem表明TabControl的一個選項卡。TabItem類添加了IsSelected屬性,指示選項卡是不是TabControl當前顯示的選項卡。

<TabControl Margin="5">
  <TabItem Header="Tab One">
    <StackPanel Margin="3">
      <CheckBox Margin="3">Setting One</CheckBox>
      <CheckBox Margin="3">Setting Two</CheckBox>
      <CheckBox Margin="3">Setting Three</CheckBox>
    </StackPanel>
  </TabItem>
  <TabItem Header="Tab Two">
    ...
  </TabItem>
</TabControl>

經過設置TabControl的TabStripPlacement屬性,能夠將選項卡從正常的頂部放到側邊。

正如Content屬性,Header屬性能接受任何類型的對象。這是一個例子:

<TabControl Margin="5">
  <TabItem>
    <TabItem.Header>
      <StackPanel>
        <TextBlock Margin="3" >Image and Text Tab Title</TextBlock>
        <Image Source="happyface.jpg" Stretch="None" />
      </StackPanel>
    </TabItem.Header>

    <StackPanel Margin="3">
      <CheckBox Margin="3">Setting One</CheckBox>
      <CheckBox Margin="3">Setting Two</CheckBox>
      <CheckBox Margin="3">Setting Three</CheckBox>
    </StackPanel>
  </TabItem>

  <TabItem Header="Tab Two"></TabItem>
</TabControl>

Expander

見175頁。

文本控件

WPF包括三文本輸入控件:TextBox,RichTextBox,和PasswordBox。PasswordBox直接從Control派生。TextBox和RichTextBox控件派生自TextBoxBase。

不一樣於內容控件,文本框僅限於他們能包含的內容類型。TextBox永遠存儲一個字符串(Text屬性)。PasswordBox也處理字符串內容(Password屬性),儘管它使用SecureString。只有RichTextBox有能力存儲更世故的內容:一個FlowDocument。

多行文本

MaxLength屬性,設置TextBox容許的最大字符數。

TextWrapping屬性,設置爲Wrap或WrapWithOverflow,表示自動換行。

MinLines和MaxLines屬性,設置TextBox的最小(最大)可見的行數。

LineCount屬性,能夠檢索出文本框中的文本有多少行。

VerticalScrollBarVisibility、HorizontalScrollBarVisibility屬性,設置滾動條的可視狀態。

AcceptsReturn屬性,設置爲真表示TextBox接受回車。默認狀況下,TextBox不接受回車。

AcceptsTab屬性爲真表示接受Tab鍵,默認狀況下,TextBox不接受Tab鍵。

IsReadOnly屬性,阻止編輯文本。

文本選擇

見180頁。

拼寫檢查

見181頁。

密碼框

見183頁。

列表控件

列表控件的基類是ItemsControl類。

每一個ItemsControl類都有項目列表。有二種方法填充項目列表。最直白的方法是直接添加項到項集合,使用代碼或XAML。更經常使用的方法是數據綁定。這種方法是設置ItemsSource屬性爲要顯示的數據項集。

ItemsControl類派生的一個主要分支爲Selector類,包括ListBox, ComboBox,和TabControl類。能夠跟蹤當前選擇項(SelectedItem),或它的位置(SelectedIndex)。

其他的列表類不支持當前項,直接從ItemsControl類派生。這些類包括Menu、Toolbar、TreeView等。

ListBox

設置SelectionMode屬性爲Multiple能夠多選。在多選模式下,要使用SelectedItems集合而不是SelectedItem。

添加列表框項:

<ListBox>
  <ListBoxItem>Green</ListBoxItem>
  <ListBoxItem>Blue</ListBoxItem>
  <ListBoxItem>Yellow</ListBoxItem>
  <ListBoxItem>Red</ListBoxItem>
</ListBox>

ListBoxItem派生自ContentControl。

例如,建立一個圖像的列表框:

<ListBox>
  <ListBoxItem>
    <Image Source="happyface.jpg"></Image>
  </ListBoxItem>
  <ListBoxItem>
    <Image Source="happyface.jpg"></Image>
  </ListBoxItem>
</ListBox>

能夠省略上例的ListBoxItem,列表框足夠智能,能夠識別列表項:

<ListBox>
  <StackPanel Orientation="Horizontal">
    <Image Source="happyface.jpg"  Width="30" Height="30"></Image>
    <Label VerticalContentAlignment="Center">A happy face</Label>
  </StackPanel>
  
  <StackPanel Orientation="Horizontal">
    <Image Source="redx.jpg" Width="30" Height="30"></Image>
    <Label VerticalContentAlignment="Center">A warning sign</Label>
  </StackPanel>
  
  <StackPanel Orientation="Horizontal">
    <Image Source="happyface.jpg"  Width="30" Height="30"></Image>
    <Label VerticalContentAlignment="Center">A happy face</Label>
  </StackPanel>
</ListBox>

下面是一個列表項爲複選框的例子:

<ListBox Name="lst" SelectionChanged="lst_SelectionChanged"
  CheckBox.Click="lst_SelectionChanged">
  <CheckBox Margin="3">Option 1</CheckBox>
  <CheckBox Margin="3">Option 2</CheckBox>
</ListBox>

若是你沒有使用ListBoxItem填充列表項,當你讀SelectedItem值時,將不會獲得ListBoxItem對象,而是你放置到列表中的對象。在上例中,SelectedItem將提供一個CheckBox對象。

下面代碼獲取當前的選擇項,顯示該項目是否被選中。

private void lst_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (lst.SelectedItem == null) return;
    txtSelection.Text = String.Format(
      "You chose item at position {0}.\r\nChecked state is {1}.",
      lst.SelectedIndex,
      ((CheckBox)lst.SelectedItem).IsChecked);
}

若是你但願知道哪個項目失去選擇,你能使用SelectionChangedEventArgs對象的RemovedItems屬性。相似地,AddedItems屬性告訴你哪個項目被添加到選擇。在單選模式,不管什麼時候選擇改變,永遠是一項目被添加和一項目被移除。在multiple或extended模式,就不必定了。

下面是遍歷列表項目集合的代碼:

private void cmd_ExamineAllItems(object sender, RoutedEventArgs e)
{
    var sb = new StringBuilder();
    foreach (CheckBox item in lst.Items)
    {
        if (item.IsChecked == true)
        {
            sb.Append(item.Content);
            sb.Append(" is checked.");
            sb.Append("\r\n");
        }
    }
    txtSelection.Text = sb.ToString();
}

ListBoxItem也有一些額外的功能:IsSelected屬性、Selected事件和Unselected事件。這些功能也能夠經過ListBox的SelectedItem屬性和SelectionChanged事件實現。

有趣地,存在一個技術,當你使用嵌套對象方法時,獲取指定對象的ListBoxItem包裹器。訣竅是ContainerFromElement()方法。這是使用這個技術的代碼檢查第一項目是不是列表的被選擇項:

var item = (ListBoxItem)lst.ContainerFromElement(
    (DependencyObject)lst.SelectedItems[0]);
MessageBox.Show("IsSelected: " + item.IsSelected.ToString());

 

ComboBox

組合框用法與列表框基本相同。

若是你容許用戶經過在組合框鍵入文原本選擇一個項目,你必須設置IsEditable屬性爲true,而且你必須確保你存儲平凡的僅文本的ComboBoxItem對象,或一個提供有意義的ToString()表示法的對象。例如,若是你填充一個可編輯的帶有圖像對象組合框,文本出如今上面的部分是Image類的全名,這不是很是使用。

基於範圍的控件

基於範圍的控件基類是RangeBase類,從Control類派生。包括ScrollBar, Slider, 和ProgressBar類。RangeBase類的屬性包括:

Value、Maximum、Minimum、SmallChange、LargeChange

由於有ScrollView控件,ScrollBar不多用。如今關注Slider和ProgressBar。

Slider

見188頁

ProgressBar

見190頁

日期控件

見190頁。

相關文章
相關標籤/搜索