Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Windows Presentation Foundation (WPF) se dodává s mnoha běžnými komponentami uživatelského rozhraní, které se používají téměř ve všech aplikacích pro Windows, například Button, Label, TextBox, Menua ListBox. Tyto objekty se historicky označují jako ovládací prvky. Výraz "control" se používá volně k označení jakékoli třídy, která představuje viditelný objekt v aplikaci. Je důležité si uvědomit, že třída nemusí dědit z třídy Control, aby měla viditelnou přítomnost. Třídy, které dědí z třídy Control obsahují ControlTemplate, což umožňuje příjemci ovládacího prvku radikálně změnit vzhled ovládacího prvku, aniž by bylo nutné vytvořit novou podtřídu. Tento článek popisuje, jak se ovládací prvky (ty, které dědí z Control třídy, i ty, které nejsou) běžně používají ve WPF.
Vytvoření instance ovládacího prvku
Ovládací prvek můžete do aplikace přidat pomocí jazyka XAML (Extensible Application Markup Language) nebo kódu. Představte si například následující obrázek okna WPF, které uživatele požádá o jméno a adresu:
Toto okno má šest ovládacích prvků: dva popisky, dvě textová pole a dvě tlačítka. XAML se používá k vytvoření těchto ovládacích prvků, jak je znázorněno v následujícím fragmentu kódu:
<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>
Všechny ovládací prvky lze v XAML vytvořit podobně. Stejné okno lze vytvořit v kódu:
// 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()
Přihlášení k odběru událostí
Událost ovládacího prvku můžete přihlásit k odběru pomocí XAML nebo kódu, ale můžete zpracovat pouze událost v kódu.
V XAML je událost nastavena jako atribut prvku. Zápis <Element.Event>handler<Element.Event> nelze použít pro události. Následující ukázka kódu ukazuje, jak se přihlásit k odběru události ClickButton:
<Button Click="Submit_Click" Grid.Row="2" Grid.Column="1" Name="Submit" Margin="2">Submit</Button>
A tady je postup, jak to udělat v kódu:
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
Následující fragment kódu zpracovává Click událost 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
Změna vzhledu ovládacího prvku
Vzhled ovládacího prvku se běžně mění tak, aby odpovídal vzhledu a chování aplikace. Vzhled ovládacího prvku můžete změnit provedením některého z následujících postupů v závislosti na tom, co chcete udělat:
- Změňte hodnotu vlastnosti ovládacího prvku.
- Vytvořte Style pro ovládací prvek.
- Vytvořte pro ovládací prvek nový ControlTemplate.
Změna vlastnosti ovládacího prvku
Mnoho ovládacích prvků má vlastnosti, které umožňují změnit způsob zobrazení ovládacího prvku, například pozadí tlačítka. Vlastnosti hodnoty můžete nastavit jak v XAML, tak v kódu. Následující příklad nastaví Background, FontSize a FontWeight vlastnosti na Button v 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>
A tady je postup, jak to udělat v kódu:
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))
Okno příkladu teď vypadá jako na následujícím obrázku:
Vytvoření stylu ovládacího prvku
WPF poskytuje rozsáhlou možnost určit vzhled ovládacích prvků vytvořením Style, místo nastavení vlastností u každého ovládacího prvku.
Style definice jsou obvykle definovány v XAML v objektu ResourceDictionary, například Resources vlastnost ovládacího prvku nebo okna. Prostředky se použijí na obor, ve kterém jsou deklarovány. Další informace najdete v tématu Přehled prostředků XAML.
Následující příklad použije Style na každý Button obsažený ve stejném Grid, který definuje styl:
<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>
A tady je postup, jak to udělat v kódu:
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)
Následující obrázek znázorňuje styl použitý v mřížce okna, který změní vzhled dvou tlačítek:
Místo použití stylu u všech ovládacích prvků určitého typu je možné je také přiřadit konkrétním ovládacím prvkům přidáním klíče do stylu ve slovníku prostředků a odkazováním na tento klíč ve Style vlastnosti ovládacího prvku. Další informace o stylech naleznete v tématu Stylování a Šablonování.
Vytvoření ControlTemplate
A Style umožňuje nastavit vlastnosti na více ovládacích prvcích najednou, ale někdy můžete chtít přizpůsobit vzhled ovládacího prvku nad rámec toho, co můžete dělat s Style. Třídy, které dědí z Control třídy mají ControlTemplate, který definuje strukturu a vzhled ovládacího prvku.
Zvažte Button ovládací prvek, běžně používaný ovládací prvek, který používá téměř každá aplikace. Primárním chováním tlačítka je umožnit aplikaci provést nějakou akci, když uživatel tlačítko vybere. Ve výchozím nastavení se tlačítko ve WPF zobrazí jako vyvýšený obdélník. Při vývoji aplikace můžete chtít využít chování tlačítka – to znamená způsob interakce uživatele s tlačítkem, který vyvolá Click událost – ale vzhled tlačítka můžete změnit nad rámec toho, co můžete udělat změnou vlastností tlačítka. V tomto případě můžete vytvořit novou ControlTemplate.
Následující příklad vytvoří ControlTemplate pro Button.
ControlTemplate vytváří vizuál pro Button, který představuje ohraničení se zaoblenými rohy a přechodovým pozadím.
<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>
Poznámka:
Vlastnost Background objektu Button musí být nastavena na hodnotu SolidColorBrush, aby příklad fungoval správně.
A tady je postup, jak to samé udělat v kódu. Následující kód vytvoří řetězec XAML a parsuje ji za účelem vygenerování šablony, kterou lze použít, což je podporovaný způsob, jak vygenerovat šablonu za běhu.
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)
Následující obrázek ukazuje, jak šablona vypadá při použití:
V předchozím příkladu ControlTemplate se použije na jedno tlačítko. Nicméně, ControlTemplate lze přiřadit k Style a použít u všech tlačítek, jak bylo ukázáno v části Vytvoření stylu pro ovládací prvek.
Další informace o tom, jak využít jedinečné funkce, které šablona poskytuje, najdete v tématu Styling a Šablonování.
Bohatý obsah v ovládacích prvcích
Většina tříd, které dědí z třídy Control, má schopnost obsahovat bohatý obsah. Například Label může obsahovat libovolný objekt, například řetězec, Imagenebo Panel. Následující třídy poskytují podporu pro bohatý obsah a fungují jako základní třídy pro většinu ovládacích prvků ve WPF:
ContentControl— Některé příklady tříd, které dědí z této třídy, jsou Label, Buttona ToolTip.
ItemsControl— Některé příklady tříd, které dědí z této třídy, jsou ListBox, Menua StatusBar.
HeaderedContentControl— Některé příklady tříd, které dědí z této třídy, jsou TabItem, GroupBoxa Expander.
HeaderedItemsControl— Některé příklady tříd, které dědí z této třídy, jsou MenuItem, TreeViewItema ToolBar.
Související obsah
- stylování a šablonování
- Přehled datových vazeb
.NET Desktop feedback