控制項
Windows Presentation Foundation (WPF) 隨附許多在幾乎每個 Windows 應用程式中都會使用的常見 UI 元件,例如 Button、Label、TextBox、 Menu 及 ListBox。 在過去,這些物件是稱為控制項。 雖然 WPF SDK 繼續使用「控制項」一詞來泛指在應用程式中代表可見物件的任何類別,但請務必注意,類別並不需要繼承自 Control 類別才能具有可見的存在。 從 Control 類別繼承的類別會包含 ControlTemplate,可讓控制項的取用者在不須建立新子類別的情況下,大幅變更控制項的外觀。 本主題探討 WPF 中的常見控制項使用方式,包括從 Control 類別繼承的控制項,以及不是從該類別繼承的控制項。
建立控制項的執行個體
您可以使用 Extensible Application Markup Language (XAML) 或程式碼,將控制項新增至應用程式。 下列範例示範如何建立一個要求使用者輸入其名字和姓氏的簡單應用程式。 此範例會以 XAML 建立六個控制項:兩個標籤、兩個文字方塊,以及兩個按鈕。 您可以用類似的方式建立所有控制項。
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Label>
Enter your first name:
</Label>
<TextBox Grid.Row="0" Grid.Column="1"
Name="firstName" Margin="0,5,10,5"/>
<Label Grid.Row="1" >
Enter your last name:
</Label>
<TextBox Grid.Row="1" Grid.Column="1"
Name="lastName" Margin="0,5,10,5"/>
<Button Grid.Row="2" Grid.Column="0"
Name="submit" Margin="2">
View message
</Button>
<Button Grid.Row="2" Grid.Column="1"
Name="Clear" Margin="2">
Clear Name
</Button>
</Grid>
下列範例會以程式碼建立相同的應用程式。 為求簡潔,此範例不包含如何建立 Grid (grid1
)。
grid1
的資料行和資料列定義與上述 XAML 範例中顯示的相同。
Label firstNameLabel;
Label lastNameLabel;
TextBox firstName;
TextBox lastName;
Button submit;
Button clear;
void CreateControls()
{
firstNameLabel = new Label();
firstNameLabel.Content = "Enter your first name:";
grid1.Children.Add(firstNameLabel);
firstName = new TextBox();
firstName.Margin = new Thickness(0, 5, 10, 5);
Grid.SetColumn(firstName, 1);
grid1.Children.Add(firstName);
lastNameLabel = new Label();
lastNameLabel.Content = "Enter your last name:";
Grid.SetRow(lastNameLabel, 1);
grid1.Children.Add(lastNameLabel);
lastName = new TextBox();
lastName.Margin = new Thickness(0, 5, 10, 5);
Grid.SetColumn(lastName, 1);
Grid.SetRow(lastName, 1);
grid1.Children.Add(lastName);
submit = new Button();
submit.Content = "View message";
Grid.SetRow(submit, 2);
grid1.Children.Add(submit);
clear = new Button();
clear.Content = "Clear Name";
Grid.SetRow(clear, 2);
Grid.SetColumn(clear, 1);
grid1.Children.Add(clear);
}
Private firstNameLabel As Label
Private lastNameLabel As Label
Private firstName As TextBox
Private lastName As TextBox
Private submit As Button
Private clear As Button
Sub CreateControls()
firstNameLabel = New Label()
firstNameLabel.Content = "Enter your first name:"
grid1.Children.Add(firstNameLabel)
firstName = New TextBox()
firstName.Margin = New Thickness(0, 5, 10, 5)
Grid.SetColumn(firstName, 1)
grid1.Children.Add(firstName)
lastNameLabel = New Label()
lastNameLabel.Content = "Enter your last name:"
Grid.SetRow(lastNameLabel, 1)
grid1.Children.Add(lastNameLabel)
lastName = New TextBox()
lastName.Margin = New Thickness(0, 5, 10, 5)
Grid.SetColumn(lastName, 1)
Grid.SetRow(lastName, 1)
grid1.Children.Add(lastName)
submit = New Button()
submit.Content = "View message"
Grid.SetRow(submit, 2)
grid1.Children.Add(submit)
clear = New Button()
clear.Content = "Clear Name"
Grid.SetRow(clear, 2)
Grid.SetColumn(clear, 1)
grid1.Children.Add(clear)
End Sub
變更控制項的外觀
變更控制項的外觀以符合您應用程式的外觀及操作,是很常見的做法。 您可以根據想要達成的目的,執行下列其中一項操作來變更控制項的外觀:
變更控制項的屬性值。
為控制項建立 Style。
為控制項建立新的 ControlTemplate。
變更控制項的屬性值
許多控制項都有可讓您變更控制項外觀的屬性,例如 Background 的 Button。 您可以在 XAML 和程式碼中都設定值屬性。 下列範例會在 XAML 中的 Background 上設定 FontSize、FontWeight 及 Button 屬性。
<Button FontSize="14" FontWeight="Bold">
<!--Set the Background property of the Button to
a LinearGradientBrush.-->
<Button.Background>
<LinearGradientBrush StartPoint="0,0.5"
EndPoint="1,0.5">
<GradientStop Color="Green" Offset="0.0" />
<GradientStop Color="White" Offset="0.9" />
</LinearGradientBrush>
</Button.Background>
View message
</Button>
下列範例會以程式碼設定相同的屬性。
LinearGradientBrush buttonBrush = new LinearGradientBrush();
buttonBrush.StartPoint = new Point(0, 0.5);
buttonBrush.EndPoint = new Point(1, 0.5);
buttonBrush.GradientStops.Add(new GradientStop(Colors.Green, 0));
buttonBrush.GradientStops.Add(new GradientStop(Colors.White, 0.9));
submit.Background = buttonBrush;
submit.FontSize = 14;
submit.FontWeight = FontWeights.Bold;
Dim buttonBrush As New LinearGradientBrush()
buttonBrush.StartPoint = New Point(0, 0.5)
buttonBrush.EndPoint = New Point(1, 0.5)
buttonBrush.GradientStops.Add(New GradientStop(Colors.Green, 0))
buttonBrush.GradientStops.Add(New GradientStop(Colors.White, 0.9))
submit.Background = buttonBrush
submit.FontSize = 14
submit.FontWeight = FontWeights.Bold
為控制項建立樣式
WPF 可讓您透過建立 Style 來大批指定控制項的外觀,而不需在應用程式中的每個執行個體上設定屬性。 下列範例會建立 Style 以套用至應用程式中的每個 Button。 Style 定義通常是以 XAML 在 ResourceDictionary 中定義,例如 Resources 的 FrameworkElement 屬性。
<Style TargetType="Button">
<Setter Property="FontSize" Value="14"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0.5"
EndPoint="1,0.5">
<GradientStop Color="Green" Offset="0.0" />
<GradientStop Color="White" Offset="0.9" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Style>
您也可以透過指派樣式索引鍵並在控制項的 Style
屬性中指定該索引鍵,將樣式只套用到某些特定類型的控制項。 如需樣式的詳細資訊,請參閱樣式設定和範本化。
建立 ControlTemplate
Style 可讓您一次在多個控制項上設定屬性,但有時您想要對 Control 外觀進行的自訂可能會超出建立 Style 所能達到的效果。 從 Control 類別繼承的類別會具有 ControlTemplate,可用來定義 Control 的結構和外觀。 Template 的 Control 屬性是公用屬性,因此您可以為 Control 提供一個與其預設值不同的 ControlTemplate。 您通常會為 ControlTemplate 指定一個新的 Control,而不從控制項繼承以自訂 Control 的外觀。
以相當常見的控制項 Button 作為例子。 Button 的主要行為是讓應用程式能夠在使用者按一下按鈕時採取某個動作。 根據預設,WPF 中的 Button 會顯示為凸起的矩形。 開發應用程式時,您可能會想要利用 Button 的行為 (亦即透過處理按鈕的點選事件),但您對按鈕外觀進行的變更可能超出變更按鈕屬性所能達到的效果。 在此情況下,您可以建立一個新的 ControlTemplate。
下列範例將為 ControlTemplate 建立 Button。
ControlTemplate 會建立一個具有圓角和漸層背景的 Button。
ControlTemplate 包含 Border,它的 Background 是具有兩個 LinearGradientBrush 物件的 GradientStop。 第一個 GradientStop 會使用資料繫結將 Color 的 GradientStop 屬性繫結至按鈕背景的色彩。 當您設定 Background 的 Button 屬性時,該值的色彩將會用來作為第一個 GradientStop。 如需有關資料繫結的詳細資訊,請參閱 資料繫結概觀。 此範例也會建立一個 Trigger,可在 Button 為 IsPressed 時變更 true
的外觀。
<!--Define a template that creates a gradient-colored button.-->
<Style TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border
x:Name="Border"
CornerRadius="20"
BorderThickness="1"
BorderBrush="Black">
<Border.Background>
<LinearGradientBrush StartPoint="0,0.5"
EndPoint="1,0.5">
<GradientStop Color="{Binding Background.Color,
RelativeSource={RelativeSource TemplatedParent}}"
Offset="0.0" />
<GradientStop Color="White" Offset="0.9" />
</LinearGradientBrush>
</Border.Background>
<ContentPresenter
Margin="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
RecognizesAccessKey="True"/>
</Border>
<ControlTemplate.Triggers>
<!--Change the appearance of
the button when the user clicks it.-->
<Trigger Property="IsPressed" Value="true">
<Setter TargetName="Border" Property="Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0.5"
EndPoint="1,0.5">
<GradientStop Color="{Binding Background.Color,
RelativeSource={RelativeSource TemplatedParent}}"
Offset="0.0" />
<GradientStop Color="DarkSlateGray" Offset="0.9" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Button Grid.Row="2" Grid.ColumnSpan="2" Name="submitName"
Background="Green">View message</Button>
注意
Background 的 Button 屬性必須設定為 SolidColorBrush,此範例才能正確運作。
訂閱事件
您可以使用 XAML 或程式碼來訂閱控制項的事件,但只能在程式碼中處理事件。 下列範例示範如何訂閱 Click
的 Button 事件。
<Button Grid.Row="2" Grid.ColumnSpan="2" Name="submitName" Click="submit_Click"
Background="Green">View message</Button>
submit.Click += new RoutedEventHandler(submit_Click);
AddHandler submit.Click, AddressOf submit_Click
下列範例會處理 Click
的 Button 事件。
void submit_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("Hello, " + firstName.Text + " " + lastName.Text);
}
Private Sub submit_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
MessageBox.Show("Hello, " + firstName.Text + " " + lastName.Text)
End Sub
控制項中的多格式內容
大多數會從 Control 類別繼承的類別都能夠包含多格式內容。 例如,Label 便可以包含任何物件,像是字串、Image 或 Panel。 下列類別可支援多格式內容,並作為 WPF 中大多數控制項的基底類別。
ContentControl-- 從此類別繼承的一些類別範例包括 Label、Button 及 ToolTip。
ItemsControl-- 從此類別繼承的一些類別範例包括 ListBox、Menu 及 StatusBar。
HeaderedContentControl-- 從此類別繼承的一些類別範例包括 TabItem、GroupBox 及 Expander。
HeaderedItemsControl-- 從此類別繼承的一些類別範例包括 MenuItem、TreeViewItem 及 ToolBar。
如需這些基底類別的詳細資訊,請參閱 WPF 內容模型。