Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Windows Presentation Foundation (WPF) levereras med många av de vanliga UI-komponenterna som används i nästan alla Windows-appar, till exempel Button, Label, TextBox, Menuoch ListBox. Tidigare kallas dessa objekt för kontroller. Termen "kontroll" används löst för att betyda alla klasser som representerar ett synligt objekt i en app. Det är viktigt att observera att en klass inte behöver ärva från Control klassen för att ha en synlig närvaro. Klasser som ärver från Control klassen innehåller en ControlTemplate, som gör att användaren av en kontroll radikalt kan ändra kontrollens utseende utan att behöva skapa en ny underklass. Den här artikeln beskriver hur kontroller (både de som ärver från Control klassen och de som inte gör det) ofta används i WPF.
Skapa en instans av en kontroll
Du kan lägga till en kontroll i en app genom att använda XAML (Extensible Application Markup Language) eller kod. Tänk till exempel på följande bild av ett WPF-fönster som ber en användare om deras namn och adress:
Det här fönstret har sex kontroller: två etiketter, två textrutor och två knappar. XAML används för att skapa dessa kontroller, vilket visas i följande kodfragment:
<Window x:Class="Examples.ExampleApp"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Input Record" Height="Auto" Width="300" SizeToContent="Height">
<Grid Margin="5">
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Label>Enter your name:</Label>
<TextBox Grid.Row="0" Grid.Column="1" Name="FirstName" Margin="2" />
<Label Grid.Row="1">Enter your address:</Label>
<TextBox Grid.Row="1" Grid.Column="1" Name="LastName" Margin="2" />
<Button Grid.Row="2" Grid.Column="0" Name="Reset" Margin="2">Reset</Button>
<Button Grid.Row="2" Grid.Column="1" Name="Submit" Margin="2">Submit</Button>
</Grid>
</Window>
Alla kontroller kan skapas på samma sätt i XAML. Samma fönster kan skapas i kod:
// Grid container which is the content of the Window
Grid container = new() { Margin = new Thickness(5) };
container.RowDefinitions.Add(new RowDefinition());
container.RowDefinitions.Add(new RowDefinition());
container.RowDefinitions.Add(new RowDefinition());
container.ColumnDefinitions.Add(new ColumnDefinition());
container.ColumnDefinitions.Add(new ColumnDefinition());
// Create the two labels, assign the second label to the second row
Label labelName = new() { Content = "Enter your name:" };
container.Children.Add(labelName);
Label labelAddress = new() { Content = "Enter your address:" };
Grid.SetRow(labelAddress, 1);
container.Children.Add(labelAddress);
// Create the two textboxes, assign both to the second column and
// assign the second textbox to the second row.
TextBox textboxName = new() { Margin = new Thickness(2) };
Grid.SetColumn(textboxName, 1);
container.Children.Add(textboxName);
TextBox textboxAddress = new() { Margin = new Thickness(2) };
Grid.SetRow(textboxAddress, 1);
Grid.SetColumn(textboxAddress, 1);
container.Children.Add(textboxAddress);
// Create the two buttons, assign both to the third row and
// assign the second button to the second column.
Button buttonReset = new() { Margin = new Thickness(2), Content = "Reset" };
Grid.SetRow(buttonReset, 2);
container.Children.Add(buttonReset);
Button buttonSubmit = new() { Margin = new Thickness(2), Content = "Submit" };
Grid.SetColumn(buttonSubmit, 1);
Grid.SetRow(buttonSubmit, 2);
container.Children.Add(buttonSubmit);
// Create the popup window and assign the container (Grid) as its content
Window inputWindow = new()
{
Title = "Input Record",
Height = double.NaN,
Width = 300,
SizeToContent = SizeToContent.Height,
Content = container
};
inputWindow.Show();
' Grid container which is the content of the Window
Dim container As New Grid() With {.Margin = New Thickness(5)}
container.RowDefinitions.Add(New RowDefinition())
container.RowDefinitions.Add(New RowDefinition())
container.RowDefinitions.Add(New RowDefinition())
container.ColumnDefinitions.Add(New ColumnDefinition())
container.ColumnDefinitions.Add(New ColumnDefinition())
' Create the two labels, assign the second label to the second row
Dim labelName As New Label() With {.Content = "Enter your name:"}
container.Children.Add(labelName)
Dim labelAddress As New Label() With {.Content = "Enter your address:"}
Grid.SetRow(labelAddress, 1)
container.Children.Add(labelAddress)
' Create the two textboxes, assign both to the second column and
' assign the second textbox to the second row.
Dim textboxName As New TextBox() With {.Margin = New Thickness(2)}
Grid.SetColumn(textboxName, 1)
container.Children.Add(textboxName)
Dim textboxAddress As New TextBox() With {.Margin = New Thickness(2)}
Grid.SetRow(textboxAddress, 1)
Grid.SetColumn(textboxAddress, 1)
container.Children.Add(textboxAddress)
' Create the two buttons, assign both to the third row and
' assign the second button to the second column.
Dim buttonReset As New Button() With {.Margin = New Thickness(2), .Content = "Reset"}
Grid.SetRow(buttonReset, 2)
container.Children.Add(buttonReset)
Dim buttonSubmit As New Button() With {.Margin = New Thickness(2), .Content = "Submit"}
Grid.SetColumn(buttonSubmit, 1)
Grid.SetRow(buttonSubmit, 2)
container.Children.Add(buttonSubmit)
' Create the window and assign the container (Grid) as its content
Dim inputWindow As New Window() With
{
.Title = "Input Record",
.Height = Double.NaN,
.Width = 300,
.SizeToContent = SizeToContent.Height,
.Content = container
}
inputWindow.Show()
Prenumerera på händelser
Du kan prenumerera på en kontrolls händelse med hjälp av antingen XAML eller kod, men du kan bara hantera en händelse i kod.
I XAML anges händelsen som ett attribut för elementet. Du kan inte använda notationen <Element.Event>handler<Element.Event> för händelser. Följande kodfragment visar hur du prenumererar på Click händelsen för en Button:
<Button Click="Submit_Click" Grid.Row="2" Grid.Column="1" Name="Submit" Margin="2">Submit</Button>
Och så här gör du samma sak i koden:
Button buttonSubmit = new() { Margin = new Thickness(2), Content = "Submit" };
buttonSubmit.Click += Submit_Click;
Dim buttonSubmit As New Button() With {.Margin = New Thickness(2), .Content = "Submit"}
AddHandler buttonSubmit.Click, AddressOf Submit_Click
Följande kodfragment hanterar Click händelsen för en Button:
private void Submit_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("Someone clicked the submit button.");
}
Private Sub Submit_Click(sender As Object, e As Windows.RoutedEventArgs)
MessageBox.Show("Someone clicked the submit button.")
End Sub
Ändra utseendet på en kontroll
Det är vanligt att ändra utseendet på en kontroll så att den passar appens utseende och känsla. Du kan ändra utseendet på en kontroll genom att göra något av följande beroende på vad du vill göra:
- Ändra värdet för en egenskap för kontrollen.
- Skapa en Style för kontrollen.
- Skapa en ny ControlTemplate för kontrollen.
Ändra en kontrolls egenskap
Många kontroller har egenskaper som gör att du kan ändra hur kontrollen visas, till exempel en knapps bakgrund. Du kan ange värdeegenskaperna i både XAML och kod. I följande exempel anges Background, FontSize, och FontWeight-egenskaperna på en Button i XAML.
<Button Grid.Row="2" Grid.Column="1" Name="Submit" Margin="2" Content="Submit">
<Button.FontSize>18</Button.FontSize>
<Button.FontWeight>Bold</Button.FontWeight>
<Button.Background>
<LinearGradientBrush>
<GradientStop Color="#0073E6" Offset="0.0" />
<GradientStop Color="#81D4FA" Offset="0.9" />
</LinearGradientBrush>
</Button.Background>
</Button>
Och så här gör du samma sak i koden:
Button buttonSubmit = new() { Margin = new Thickness(2), Content = "Submit" };
buttonSubmit.FontSize = 18f;
buttonSubmit.FontWeight = FontWeights.Bold;
buttonSubmit.Background =
new LinearGradientBrush(
(Color)ColorConverter.ConvertFromString("#0073E6"),
(Color)ColorConverter.ConvertFromString("#81D4FA"),
new Point(0d, 0d),
new Point(0.9d, 0d));
Dim buttonSubmit As New Button() With {.Margin = New Thickness(2), .Content = "Submit"}
buttonSubmit.FontSize = 18.0F
buttonSubmit.FontWeight = FontWeights.Bold
buttonSubmit.Background =
New LinearGradientBrush(
ColorConverter.ConvertFromString("#0073E6"),
ColorConverter.ConvertFromString("#81D4FA"),
New Point(0D, 0D),
New Point(0.9D, 0D))
Exempelfönstret ser nu ut som följande bild:
Skapa ett format för en kontroll
WPF ger dig omfattande möjlighet att ange utseendet på kontroller genom att skapa en Style, i stället för att ange egenskaper för varje kontroll.
Style definitioner anges vanligtvis i XAML i en ResourceDictionary, till exempel en kontroll eller fönstrets Resources egenskap. Resurser tillämpas på användningsområdet där de deklareras. Mer information finns i Översikt över XAML-resurser.
Följande exempel tillämpar en Style på varje Button som finns i samma Grid som definierar stilen.
<Grid.Resources>
<Style TargetType="{x:Type Button}">
<Style.Setters>
<Setter Property="FontSize" Value="18" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush>
<GradientStop Color="#0073E6" Offset="0.0" />
<GradientStop Color="#81D4FA" Offset="0.9" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
</Grid.Resources>
Och så här gör du samma sak i koden:
Grid container = new() { Margin = new Thickness(5) };
container.RowDefinitions.Add(new RowDefinition());
container.RowDefinitions.Add(new RowDefinition());
container.RowDefinitions.Add(new RowDefinition());
container.ColumnDefinitions.Add(new ColumnDefinition());
container.ColumnDefinitions.Add(new ColumnDefinition());
Style buttonStyle = new(typeof(Button));
buttonStyle.Setters.Add(new Setter(Button.FontSizeProperty, 18d));
buttonStyle.Setters.Add(new Setter(Button.FontWeightProperty, FontWeights.Bold));
buttonStyle.Setters.Add(new Setter(Button.BackgroundProperty,
new LinearGradientBrush(
(Color)ColorConverter.ConvertFromString("#0073E6"),
(Color)ColorConverter.ConvertFromString("#81D4FA"),
new Point(0d, 0d),
new Point(0.9d, 0d))));
container.Resources.Add(typeof(Button), buttonStyle);
Dim container As New Grid() With {.Margin = New Thickness(5)}
container.RowDefinitions.Add(New RowDefinition())
container.RowDefinitions.Add(New RowDefinition())
container.RowDefinitions.Add(New RowDefinition())
container.ColumnDefinitions.Add(New ColumnDefinition())
container.ColumnDefinitions.Add(New ColumnDefinition())
Dim buttonStyle As New Style(GetType(Button))
buttonStyle.Setters.Add(New Setter(Button.FontSizeProperty, 18.0R))
buttonStyle.Setters.Add(New Setter(Button.FontWeightProperty, FontWeights.Bold))
buttonStyle.Setters.Add(New Setter(Button.BackgroundProperty,
New LinearGradientBrush(
ColorConverter.ConvertFromString("#0073E6"),
ColorConverter.ConvertFromString("#81D4FA"),
New Point(0D, 0D),
New Point(0.9D, 0D))))
container.Resources.Add(GetType(Button), buttonStyle)
Följande bild visar formatet som används för rutnätet i fönstret, vilket ändrar utseendet på de två knapparna:
I stället för att tillämpa formatmallen på alla kontroller av en viss typ kan de också tilldelas till specifika kontroller genom att lägga till en nyckel i formatet i resursordlistan och referera till den nyckeln i Style kontrollens egenskap. Mer information om format finns i Formatering och templatering.
Skapa ett ControlTemplate
A Style gör att du kan ange egenskaper för flera kontroller i taget, men ibland kanske du vill anpassa utseendet på en kontroll utöver vad du kan göra med en Style. Klasser som ärver från Control klassen har en ControlTemplate, som definierar strukturen och utseendet på en kontroll.
Överväg kontrollen Button , en vanlig kontroll som används av nästan alla appar. Det primära beteendet för en knapp är att göra det möjligt för en app att vidta vissa åtgärder när användaren väljer knappen. Som standard visas knappen i WPF som en upphöjd rektangel. När du utvecklar en app kanske du vill dra nytta av beteendet för en knapp, det vill sa, hur användaren interagerar med knappen, vilket genererar en Click händelse, men du kan ändra knappens utseende utöver vad du kan göra genom att ändra knappens egenskaper. I det här fallet kan du skapa en ny ControlTemplate.
I följande exempel skapas en ControlTemplate för en Button.
ControlTemplate skapar en visuell representation för Button som visar en kantlinje med rundade hörn och en gradientbakgrund.
<Button Grid.Row="2" Grid.Column="1" Name="Submit" Margin="2" Content="Submit">
<Button.Template>
<ControlTemplate TargetType="Button">
<Border Name="Border" CornerRadius="10" 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="PeachPuff" 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="LightBlue" Offset="0.9" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
</Button>
Anmärkning
Egenskapen Background av Button måste vara inställd på ett SolidColorBrush för att exemplet ska fungera korrekt.
Och så här gör du samma sak i kod. Följande kod skapar en XAML-sträng och analyserar den för att generera en mall som kan användas, vilket är det rekommenderade sättet att generera en mall vid körtid.
Button buttonSubmit = new() { Margin = new Thickness(2), Content = "Submit" };
// Create the XAML used to define the button template
const string xaml = """
<ControlTemplate TargetType="Button">
<Border Name="Border" CornerRadius="10" 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="PeachPuff" 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="LightBlue" Offset="0.9" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
""";
// Load the XAML into a stream that can be parsed
using MemoryStream stream = new(System.Text.Encoding.UTF8.GetBytes(xaml));
// Create a parser context and add the default namespace and
// the x namespace, which is common to WPF XAML
System.Windows.Markup.ParserContext context = new();
context.XmlnsDictionary.Add("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
context.XmlnsDictionary.Add("x", "http://schemas.microsoft.com/winfx/2006/xaml");
// Parse the XAML and assign it to the button's template
buttonSubmit.Template = (ControlTemplate)System.Windows.Markup.XamlReader.Load(stream, context);
// Set the other properties of the button
Grid.SetColumn(buttonSubmit, 1);
Grid.SetRow(buttonSubmit, 2);
// Assign the button to the grid container
container.Children.Add(buttonSubmit);
Dim buttonSubmit As New Button() With {.Margin = New Thickness(2), .Content = "Submit"}
' Create the XAML used to define the button template
Const xaml As String = "
<ControlTemplate TargetType=""Button"">
<Border Name=""Border"" CornerRadius=""10"" 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=""PeachPuff"" 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=""LightBlue"" Offset=""0.9"" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>"
' Load the XAML into a stream that can be parsed
Using stream As New MemoryStream(System.Text.Encoding.UTF8.GetBytes(xaml))
' Create a parser context and add the default namespace and
' the x namespace, which is common to WPF XAML
Dim context = New System.Windows.Markup.ParserContext()
context.XmlnsDictionary.Add("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation")
context.XmlnsDictionary.Add("x", "http://schemas.microsoft.com/winfx/2006/xaml")
' Parse the XAML and assign it to the button's template
buttonSubmit.Template = System.Windows.Markup.XamlReader.Load(stream, context)
End Using
' Set the other properties of the button
Grid.SetColumn(buttonSubmit, 1)
Grid.SetRow(buttonSubmit, 2)
' Assign the button to the grid container
container.Children.Add(buttonSubmit)
Följande bild visar hur mallen ser ut när den tillämpas:
I föregående exempel tillämpas den ControlTemplate på en enda knapp. Dock kan en ControlTemplate tilldelas en Style och tillämpas på alla knappar, precis som det demonstrerades i avsnittet Skapa ett format för en kontroll.
Mer information om hur du drar nytta av de unika funktioner som en mall tillhandahåller finns i Formatering och templating.
Omfattande innehåll i kontroller
De flesta klasser som ärver från Control klassen har kapacitet att innehålla omfattande innehåll. En kan till exempel Label innehålla valfritt objekt, till exempel en sträng, en Image, eller en Panel. Följande klasser ger stöd för omfattande innehåll och fungerar som basklasser för de flesta kontrollerna i WPF:
ContentControl— Några exempel på klasser som ärver från den här klassen är Label, Buttonoch ToolTip.
ItemsControl— Några exempel på klasser som ärver från den här klassen är ListBox, Menuoch StatusBar.
HeaderedContentControl— Några exempel på klasser som ärver från den här klassen är TabItem, GroupBoxoch Expander.
HeaderedItemsControl— Några exempel på klasser som ärver från den här klassen är MenuItem, TreeViewItemoch ToolBar.
Relaterat innehåll
.NET Desktop feedback