Zoeken…
Hallo bronnen
WPF introduceert een zeer handig concept: de mogelijkheid om gegevens op te slaan als een bron, hetzij lokaal voor een controle, lokaal voor het gehele venster of globaal voor de hele toepassing. De gegevens kunnen vrijwel alles zijn wat u maar wilt, van actuele informatie tot een hiërarchie van WPF-besturingselementen. Hiermee kunt u gegevens op één plaats plaatsen en deze vervolgens vanaf of meerdere andere plaatsen gebruiken, wat erg handig is. Het concept wordt veel gebruikt voor stijlen en sjablonen.
<Window x:Class="WPFApplication.ResourceSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="ResourceSample" Height="150" Width="350">
<Window.Resources>
<sys:String x:Key="strHelloWorld">Hello, world!</sys:String>
</Window.Resources>
<StackPanel Margin="10">
<TextBlock Text="{StaticResource strHelloWorld}" FontSize="56" />
<TextBlock>Just another "<TextBlock Text="{StaticResource strHelloWorld}" />" example, but with resources!</TextBlock>
</StackPanel>
</Window>
Bronnen krijgen een sleutel, met behulp van het x: Key-kenmerk, waarmee u vanuit andere delen van de toepassing naar deze sleutel kunt verwijzen door deze sleutel te gebruiken, in combinatie met de StaticResource-markup-extensie. In dit voorbeeld bewaar ik gewoon een eenvoudige string, die ik vervolgens gebruik uit twee verschillende TextBlock-besturingselementen.
Soorten bronnen
Het delen van een eenvoudige string was eenvoudig, maar je kunt veel meer doen. In dit voorbeeld zal ik ook een complete reeks strings opslaan, samen met een verlooppenseel dat voor de achtergrond moet worden gebruikt. Dit zou u een redelijk goed idee moeten geven van hoeveel u kunt doen met middelen:
<Window x:Class="WPFApplication.ExtendedResourceSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="ExtendedResourceSample" Height="160" Width="300"
Background="{DynamicResource WindowBackgroundBrush}">
<Window.Resources>
<sys:String x:Key="ComboBoxTitle">Items:</sys:String>
<x:Array x:Key="ComboBoxItems" Type="sys:String">
<sys:String>Item #1</sys:String>
<sys:String>Item #2</sys:String>
<sys:String>Item #3</sys:String>
</x:Array>
<LinearGradientBrush x:Key="WindowBackgroundBrush">
<GradientStop Offset="0" Color="Silver"/>
<GradientStop Offset="1" Color="Gray"/>
</LinearGradientBrush>
</Window.Resources>
<StackPanel Margin="10">
<Label Content="{StaticResource ComboBoxTitle}" />
<ComboBox ItemsSource="{StaticResource ComboBoxItems}" />
</StackPanel>
</Window>
Deze keer hebben we een paar extra bronnen toegevoegd, zodat ons venster nu een eenvoudige tekenreeks, een reeks tekenreeksen en een LinearGradientBrush bevat. De tekenreeks wordt gebruikt voor het label, de reeks tekenreeksen wordt gebruikt als items voor het besturingselement ComboBox en het verlooppenseel wordt gebruikt als achtergrond voor het hele venster. Zoals u ziet, kan vrijwel alles worden opgeslagen als bron.
Lokale en applicatiebrede bronnen
Als u alleen een bepaalde bron voor een specifiek besturingselement nodig hebt, kunt u deze meer lokaal maken door deze aan dit specifieke besturingselement toe te voegen, in plaats van aan het venster. Het werkt op precies dezelfde manier, het enige verschil is dat u nu alleen toegang hebt vanuit het bereik van het besturingselement waar u het plaatst:
<StackPanel Margin="10">
<StackPanel.Resources>
<sys:String x:Key="ComboBoxTitle">Items:</sys:String>
</StackPanel.Resources>
<Label Content="{StaticResource ComboBoxTitle}" />
</StackPanel>
In dit geval voegen we de bron toe aan het StackPanel en gebruiken we deze vervolgens vanuit het onderliggende besturingselement, het label. Andere bedieningselementen in het StackPanel hadden er ook gebruik van kunnen maken, net zoals kinderen van deze kindbesturingselementen toegang hadden kunnen krijgen. Besturingselementen buiten dit specifieke StackPanel zouden hier echter geen toegang toe hebben.
Als u de mogelijkheid nodig hebt om vanuit meerdere vensters toegang te krijgen tot de bron, is dit ook mogelijk. Het App.xaml-bestand kan bronnen bevatten, net als het venster en elke vorm van WPF-besturing, en wanneer u ze opslaat in App.xaml, zijn ze wereldwijd toegankelijk in alle vensters en gebruikersbesturingselementen van het project. Het werkt op precies dezelfde manier als bij het opslaan en gebruiken vanuit een venster:
<Application x:Class="WpfSamples.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
StartupUri="WPFApplication/ExtendedResourceSample.xaml">
<Application.Resources>
<sys:String x:Key="ComboBoxTitle">Items:</sys:String>
</Application.Resources>
</Application>
Het gebruik is ook hetzelfde - WPF zal automatisch het bereik verhogen, van het lokale besturingselement naar het venster en vervolgens naar App.xaml, om een bepaalde bron te vinden:
<Label Content="{StaticResource ComboBoxTitle}" />
Hulpbronnen van Code-behind
In dit voorbeeld hebben we toegang tot drie verschillende bronnen van Code-behind, elk opgeslagen in een ander bereik
App.xaml:
<Application x:Class="WpfSamples.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
StartupUri="WPFApplication/ResourcesFromCodeBehindSample.xaml">
<Application.Resources>
<sys:String x:Key="strApp">Hello, Application world!</sys:String>
</Application.Resources>
</Application>
Venster:
<Window x:Class="WpfSamples.WPFApplication.ResourcesFromCodeBehindSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="ResourcesFromCodeBehindSample" Height="175" Width="250">
<Window.Resources>
<sys:String x:Key="strWindow">Hello, Window world!</sys:String>
</Window.Resources>
<DockPanel Margin="10" Name="pnlMain">
<DockPanel.Resources>
<sys:String x:Key="strPanel">Hello, Panel world!</sys:String>
</DockPanel.Resources>
<WrapPanel DockPanel.Dock="Top" HorizontalAlignment="Center" Margin="10">
<Button Name="btnClickMe" Click="btnClickMe_Click">Click me!</Button>
</WrapPanel>
<ListBox Name="lbResult" />
</DockPanel>
</Window>
Code achter:
using System;
using System.Windows;
namespace WpfSamples.WPFApplication
{
public partial class ResourcesFromCodeBehindSample : Window
{
public ResourcesFromCodeBehindSample()
{
InitializeComponent();
}
private void btnClickMe_Click(object sender, RoutedEventArgs e)
{
lbResult.Items.Add(pnlMain.FindResource("strPanel").ToString());
lbResult.Items.Add(this.FindResource("strWindow").ToString());
lbResult.Items.Add(Application.Current.FindResource("strApp").ToString());
}
}
}
Dus, zoals je ziet, slaan we drie verschillende "Hallo wereld!" berichten: één in App.xaml, één in het venster en één lokaal voor het hoofdpaneel. De interface bestaat uit een knop en een ListBox.
In Code-behind behandelen we de klikgebeurtenis van de knop, waarin we alle tekenreeksen aan de ListBox toevoegen, zoals te zien op de screenshot. We gebruiken de methode FindResource (), die de bron retourneert als een object (indien gevonden), en vervolgens veranderen we deze in de string waarvan we weten dat deze is met behulp van de methode ToString ().
Merk op hoe we de methode FindResource () op verschillende bereiken gebruiken - eerst op het paneel, vervolgens op het venster en vervolgens op het huidige toepassingsobject. Het is logisch om te zoeken naar de bron waarvan we weten dat deze zich bevindt, maar zoals reeds vermeld, gaat de zoekopdracht door naar een hoger niveau als de bron niet wordt gevonden, dus in principe hadden we de methode FindResource () op het paneel kunnen gebruiken in alle drie de gevallen, omdat het zou zijn doorgegaan tot het venster en later tot het toepassingsniveau, indien niet gevonden.
Hetzelfde is andersom niet waar - de zoekopdracht navigeert niet in de boomstructuur, dus je kunt niet beginnen met het zoeken naar een bron op toepassingsniveau, als deze lokaal is gedefinieerd voor het besturingselement of voor het venster.