這篇我們來大概的看一下WPF的各種神馬控件,首先我們要知道所有的wpf控件都是繼承自Control,從用途上可以分為四種
1:內容控件(Content Controls)
2:條目控件(Items Controls)
3:文本控件(Text Controls)
4:范圍控件(Range Controls)
一:內容控件
內容控件的最大的特征就是有一個Content屬性,從前面的文章中,我們多多少少也知道Content接收的是一個Object類型,或許
我們會立即想到莫非Button就是一個內容控件,確實,Button算是一個內容控件,凡是內容控件都繼承自ContentControl,因為
Content屬性就是屬於ContentControl。
1:ButonBase
要說Button,我們需要從ButtonBase說起,首先看一下類圖。
<1>Button
從圖中我們可以看出,Button是繼承自ButtonBase的,Button有個很有趣的地方就是ButtonBase中存在一個ClickMode屬性,
什么意思呢?也就是說Click事件是用什么方式觸發?觸發方式在ClickMode中以枚舉的方式展現,Hover,Press和Release,默認
也就是Press。
那么下面我用Hover的形式來觸發Click事件,蠻有意思的,嘿嘿。
1 <Window x:Class="ButtonDemo.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 Title="MainWindow" Height="350" Width="525"> 5 <Grid> 6 <Button Content="Button" Height="23" IsDefault="True" Margin="124,77,304,211" ClickMode="Hover" Name="button1" Width="75" Click="button1_Click" /> 7 </Grid> 8 </Window>
<2>RepeatButton
首先這玩意我們在webform或者winform中貌似都沒有見過,在wpf中也是一個新增的控件,那么它的用途是什么呢?很簡單,我們在
看video的時候都有“快進”,“快退”,你懂的,首先我們看下RepeatButton中的定義,我們發現有一個
Delay:作用就是按下時第一次觸發Click的時間延遲,
Interval:每次click發生的時間間隔,如果大家玩轉了Timer控件都應該很清楚。
1 <Window x:Class="RepeatButtonDemo.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 Title="MainWindow" Height="350" Width="525"> 5 <Canvas> 6 <TextBox Canvas.Left="151" Canvas.Top="69" Height="33" Name="textBox1" Width="172" Text="0" /> 7 <RepeatButton x:Name="test" Delay="100" Click="test_Click" Width="172" 8 Content="確定" Height="61" Canvas.Left="151" Canvas.Top="121" /> 9 </Canvas> 10 </Window>
1 namespace RepeatButtonDemo 2 { 3 /// <summary> 4 /// MainWindow.xaml 的交互邏輯 5 /// </summary> 6 public partial class MainWindow : Window 7 { 8 public MainWindow() 9 { 10 InitializeComponent(); 11 } 12 13 private void test_Click(object sender, RoutedEventArgs e) 14 { 15 var num = Convert.ToInt32(textBox1.Text); 16 17 textBox1.Text = (++num).ToString(); 18 } 19 } 20 }
<3>GridViewColumnHeader
這個是與GridView控件一起搭配使用,放在后面一起講。
<4>ToggleButton
從圖中我們看到ToggleButton是CheckBox和RadioButton的基類,大家一看,這玩意我們早就會了,是的,大家都會,這里我就說
點有新鮮味道的東西,首先我們看下ToggleButton的類定義。
嘿嘿,興趣點來了,怎么IsChecked是可空類型?而且還存在王八IsThreeState屬性,難道還有第三種狀態?是的,這是在Html
中沒有的,這里我們要知道,實際上我們最終的UI呈現的要么是CheckBox,要么是Radiobutton,要使第三種狀態有效,我們只
需要設置IsThreeState屬性和Indeterminate事件即可。
1 <Window x:Class="CheckBoxDemo.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 Title="MainWindow" Height="350" Width="525"> 5 <Grid> 6 <CheckBox Content="CheckBox" Height="16" HorizontalAlignment="Left" Margin="96,137,0,0" Name="checkBox1" VerticalAlignment="Top" IsThreeState="True" Indeterminate="checkBox1_Checked" /> 7 </Grid> 8 </Window>
1 namespace CheckBoxDemo 2 { 3 /// <summary> 4 /// MainWindow.xaml 的交互邏輯 5 /// </summary> 6 public partial class MainWindow : Window 7 { 8 public MainWindow() 9 { 10 InitializeComponent(); 11 } 12 13 private void checkBox1_Checked(object sender, RoutedEventArgs e) 14 { 15 MessageBox.Show("不錯"); 16 } 17 } 18 }
2: HeaderedContentControl
顧名思義,這是一個帶有標題的內容控件,或許大家第一個反應過來的估計就是GroupBox,是的,這玩意我們在Html中用的太多了,
老規矩,我們還是看看類圖。
<1> Expander
首先得要申明,Expander是wpf中新增的一個控件,在html中我們經常會看到一個伸縮控件,折疊起來只能看到標題,伸展開才能
看到內容,繼續上代碼說話。
1 <Window x:Class="ExpanderDemo.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 Title="MainWindow" Height="350" Width="525"> 5 <Grid> 6 <Expander Header="年齡組" Height="208" Margin="39,33,154,70" Name="expander1" Width="310"> 7 <StackPanel> 8 <RadioButton Content="RadioButton1" Height="16" Name="radioButton1" /> 9 <RadioButton Content="RadioButton2" Height="16" Name="radioButton2" /> 10 </StackPanel> 11 </Expander> 12 13 </Grid> 14 </Window>
<2> GroupBox
關於GroupBox的使用,我想我也不用羅嗦了,太簡單不過了。
<3>TabItem
TabItem控件是與TabControl控件搭配使用,這個放到條目控件上說。
3:ToolTip
首先我們要知道ToolTip也是繼承自ContentControl,在使用ToolTip的時候我們要注意兩點。
<1>: ToolTip有點特殊,它不能獨立的作為一個控件使用,而是與其他具體控件的ToolTip聯合使用。
<2>:ToolTip提供了一個ToolTipSerivce類,可用於設計Tooltip顯示的相對位置,提示時間,嘿嘿,蠻有意思。
1 <Window x:Class="ToolTipDemo.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 Title="MainWindow" Height="350" Width="525"> 5 <Grid> 6 <Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="130,103,0,0" Name="button1" VerticalAlignment="Top" Width="75" 7 ToolTipService.HorizontalOffset="20" 8 ToolTipService.VerticalOffset="20" > 9 <Button.ToolTip> 10 <StackPanel> 11 <GroupBox Header="XXX選擇題,你懂得..."> 12 <GroupBox.Content> 13 <StackPanel> 14 <TextBlock x:Name="A">A:XXXX</TextBlock> 15 <TextBlock x:Name="B">B:XX</TextBlock> 16 <TextBlock x:Name="C">C:OOOO</TextBlock> 17 <TextBlock x:Name="D">D:OO</TextBlock> 18 </StackPanel> 19 </GroupBox.Content> 20 </GroupBox> 21 </StackPanel> 22 </Button.ToolTip> 23 </Button> 24 </Grid> 25 </Window>
4:ScrollViewer
在內容控件中很常用的一個莫過於ScrollViewer,因為我們在界面布局時,永遠都是“內容”大於界面,那么內容超出了我們該怎么辦呢?
我們知道Html中Div具有裁剪功能,當內容超出,自動就有滾動條,那么在wpf中的ScrollViewer也能夠實現同樣的功能。
1 <Window x:Class="ScrollViewerDemo.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 Title="MainWindow" Height="350" Width="525"> 5 <Grid> 6 <ScrollViewer Height="108" HorizontalAlignment="Left" Margin="98,63,0,0" 7 Name="scrollViewer1" VerticalAlignment="Top" Width="224" 8 VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto"> 9 <StackPanel x:Name="Test" Orientation="Horizontal"> 10 11 </StackPanel> 12 </ScrollViewer> 13 </Grid> 14 </Window>
1 namespace ScrollViewerDemo 2 { 3 /// <summary> 4 /// MainWindow.xaml 的交互邏輯 5 /// </summary> 6 public partial class MainWindow : Window 7 { 8 public MainWindow() 9 { 10 InitializeComponent(); 11 12 for (int i = 0; i < 100; i++) 13 { 14 TextBox tbx = new TextBox(); 15 16 tbx.Text = i.ToString(); 17 18 Test.Children.Add(tbx); 19 } 20 } 21 } 22 }
二:條目控件
條目控件首先都是繼承自ItemsControl,在ItemsControl中我們發現有兩個比較有意思的屬性,Items和ItemsSource。
Items:
從圖中可以看出Items屬於ItemCollection的集合類型,所以每一個Item里面都可以放入一個Object類型對象,這里有意思的地方就是,
如果我放入的是一個UI元素,那么很好,wpf會調用UI的OnRender方法將UI元素呈現,如果說是一個沒有OnRender方法的元素,那該
怎么辦呢?wpf很智能,它會創建一個TextBlock,然后調用該對象的ToString()將字符串呈現在TextBlock上。
ItemsSource:
從前面文章中我們也看到,ItemsSource常用於數據綁定,所以是一個非常實用的屬性。
好,接下來我們看一下條目控件的類圖
從圖中,我們大致可以看出這些控件可以分為兩大類。
第一類:就是“條目容器”,比如Menu。
第二類:就是“具體條目”,比如MenuItem,但是在MenuItem中又可以分為“帶標題”和“不帶標題”的兩類具體條目”。
<1>MenuBase
從圖中我們可以看出MenuBase的子類有兩個Menu和ContextMenu,在Winform中我想大家肯定玩爛了,這里我也不多說了。
<2>Selector
既然是選擇性的控件,那么難免少不了SelectedIndex或者SelectedItem,可以我們反應就是Listbox,嘿嘿,關於ListBox
和ComboBox這里就不多說了,我們具體的還是看下TabControl和ListView,先還是看下Selector類中的定義。
TabControl:
這個控件我們在Html中用的還是比較多的,顧名思義就是選項卡,因為我們知道用ListBox是很占用空間的,而TabControl是具有更小的
地方展現更多的內容,其實TabControl的每一個標簽頁都是一個TabItem。
1 <Window x:Class="TabControlDemo.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 Title="MainWindow" Height="350" Width="525"> 5 <Grid> 6 <TabControl Height="100" HorizontalAlignment="Left" Margin="103,51,0,0" 7 Name="tabControl1" VerticalAlignment="Top" Width="200" 8 TabStripPlacement="Top" > 9 <TabItem Header="星期一" Name="tabItem1"> 10 <TabItem.Content> 11 <TextBlock x:Name="test1" Text="你懂的"/> 12 </TabItem.Content> 13 </TabItem> 14 <TabItem Header="星期一" Name="tabItem2"> 15 <TabItem.Content> 16 <TextBlock x:Name="test2" Text="你不懂的"/> 17 </TabItem.Content> 18 </TabItem> 19 </TabControl> 20 </Grid> 21 </Window>
ListView:
這個控件我們在實際開發中經常用於數據綁定,它是繼承自ListBox,ListBox默認只能顯示一列,而ListView則可以用於顯示多列,
這里我提一個很有興趣的玩意ObservableCollection<T>。它有什么用呢?其實ObservableCollection可以允許一個UI元素作為觀察者
對它進行監視,也就是說如果ObservableCollection中的元素有變動,作為觀察的UI元素也會相應的改變,下面舉個例子。
1 <Window x:Class="ListViewDemo.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 DataContext="{Binding RelativeSource={RelativeSource Self}}" 5 Title="MainWindow" Height="350" Width="525"> 6 <Grid> 7 <ListView ItemsSource="{Binding PersonList}"> 8 <ListView.View> 9 <GridView> 10 <GridViewColumn Header="姓名" DisplayMemberBinding="{Binding Path=Name}"/> 11 <GridViewColumn Header="年齡" DisplayMemberBinding="{Binding Path=Age}"/> 12 </GridView> 13 </ListView.View> 14 </ListView> 15 <Button Content="刪除一行" Click="Button_Click" Margin="315,174,35,103" /> 16 </Grid> 17 </Window>
1 namespace ListViewDemo 2 { 3 /// <summary> 4 /// MainWindow.xaml 的交互邏輯 5 /// </summary> 6 public partial class MainWindow : Window 7 { 8 private ObservableCollection<Person> personList = new ObservableCollection<Person>(); 9 10 public ObservableCollection<Person> PersonList 11 { 12 get { return personList; } 13 set { personList = value; } 14 } 15 16 public MainWindow() 17 { 18 InitializeComponent(); 19 20 personList.Add(new Person() { Name = "一線碼農", Age = 24 }); 21 22 personList.Add(new Person() { Name = "XXX", Age = 21 }); 23 } 24 25 private void Button_Click(object sender, RoutedEventArgs e) 26 { 27 personList.RemoveAt(0); 28 } 29 } 30 31 public class Person 32 { 33 public string Name { get; set; } 34 35 public int Age { get; set; } 36 } 37 }
<==== 單擊刪除一行后 ====>
<3>StatusBar
關於狀態欄控件,我想大家在WinForm中已經玩爛了,此處也就不多說了。
<4>TreeView
我們知道TreeView是一個樹形控件,在Html中如果想展現一個樹形結構,我們只要將數據結構“深度優先”一下就OK了,關於
TreeView的數據綁定,我的前一篇文章也說過,這里也就走馬觀花一下。
三:文本控件
在wpf中,文本控件有三個,分別是:TextBox,RichTextBox和PasswordBox,先不管怎么樣,上類圖
這幾個控件,我想在winform中用的還是比較熟的,這里也就不羅嗦了。
四:范圍控件
還是先上圖:
下面我們看看RangeBase的類定義:
圖中可以看出RangeBase是一個抽象類,定義了4個基本屬性:LargeChange,SmallChange,Maximum,Minimum,有了這些東西
我們才能方便快捷的使用范圍控件。
<1> ScrollBar
在先前的例子中,我們經常用一個控件來綁定ScrollBar的Value來形成聯動,也就可以避免在后台的不必要代碼,靈活方便。
1 <Window x:Class="ScrollBar.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 Title="MainWindow" Height="350" Width="525"> 5 <Grid> 6 <StackPanel Height="100" Margin="97,61,206,150" Name="stackPanel1" Width="200"> 7 <ScrollBar Name="test" Orientation="Horizontal" Maximum="100" Minimum="5" SmallChange="2" Height="17" Width="186" /> 8 <Label Content="滑動塊值"/> 9 <TextBox Name="txtScrollValue" Text="{Binding ElementName=test, Path=Value}"/> 10 </StackPanel> 11 </Grid> 12 </Window>
<2>ProgressBar
這個控件我們在實際應用上使用的還是比較多的,因為我們在完成一個任務時,可能需要等待數十秒或者數分鍾,所以為了不讓用戶認為
系統處於假死狀態,就要用一個等待進度條,這里有意思的地方就是,如果我們不知道任務何時完成或者說不在乎任務何時結束,我們可以
設一個無限等待的進度條,也就是說進度條上有一個“小矩形”在不停的滾動,我們要做的也就是設置IsIndeterminate=true即可。