Sök…


Hej resurser

WPF introducerar ett mycket praktiskt koncept: Möjligheten att lagra data som en resurs, antingen lokalt för en kontroll, lokalt för hela fönstret eller globalt för hela applikationen. Data kan vara ganska mycket vad du vill, från faktisk information till en hierarki med WPF-kontroller. Detta gör att du kan placera data på ett ställe och sedan använda dem från eller flera andra platser, vilket är mycket användbart. Konceptet används mycket för stilar och mallar.

<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>

ange bildbeskrivning här

Resurser ges en nyckel med attributet x: Key, som låter dig hänvisa till det från andra delar av applikationen med hjälp av denna nyckel, i kombination med StaticResource-markeringsförlängningen. I det här exemplet lagrar jag bara en enkel sträng som jag sedan använder från två olika TextBlock-kontroller.

Resursstyper

Det var enkelt att dela en enkel sträng, men du kan göra mycket mer. I det här exemplet lagrar jag också ett komplett utbud av strängar, tillsammans med en lutningborste som ska användas för bakgrunden. Detta bör ge dig en ganska bra idé om hur mycket du kan göra med resurser:

<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>

ange bildbeskrivning här

Den här gången har vi lagt till ett par extra resurser, så att vårt Fönster nu innehåller en enkel sträng, en rad strängar och en LinearGradientBrush. Strängen används för etiketten, matrisen av strängar används som objekt för ComboBox-kontrollen och lutningborsten används som bakgrund för hela fönstret. Så, som ni ser, kan nästan allt lagras som en resurs.

Lokala resurser och applikationsbrett

Om du bara behöver en given resurs för en specifik kontroll kan du göra den mer lokal genom att lägga till den till den specifika kontrollen, istället för fönstret. Det fungerar exakt på samma sätt, den enda skillnaden är att du nu bara kan komma åt från kontrollområdet där du placerar det:

<StackPanel Margin="10">
    <StackPanel.Resources>
        <sys:String x:Key="ComboBoxTitle">Items:</sys:String>
    </StackPanel.Resources>
    <Label Content="{StaticResource ComboBoxTitle}" />
</StackPanel>

I det här fallet lägger vi till resursen till StackPanel och använder den sedan från dess barnkontroll, etiketten. Andra kontroller inuti StackPanel kunde också ha använt den, precis som barn i dessa barnkontroller skulle ha kunnat komma åt den. Kontroller utanför denna specifika StackPanel skulle dock inte ha åtkomst till den.

Om du behöver förmågan att komma åt resursen från flera fönster är detta också möjligt. App.xaml-filen kan innehålla resurser precis som fönstret och alla typer av WPF-kontroll, och när du lagrar dem i App.xaml är de globalt tillgängliga i alla fönster och användarkontroller för projektet. Det fungerar exakt på samma sätt som vid lagring och användning från ett fönster:

<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>

Att använda den är också densamma - WPF kommer automatiskt att öka omfattningen, från den lokala kontrollen till fönstret och sedan till App.xaml, för att hitta en given resurs:

<Label Content="{StaticResource ComboBoxTitle}" />

Resurser från kod bakom

I det här exemplet kommer vi att få åtkomst till tre olika resurser från kod bakom, var och en lagras i ett annat omfång

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>

Fönster:

<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-bakom:

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());
                }
        }
}

ange bildbeskrivning här

Så, som ni ser, lagrar vi tre olika "Hej, värld!" meddelanden: Ett i App.xaml, ett inuti fönstret och ett lokalt för huvudpanelen. Gränssnittet består av en knapp och en ListBox.

I kod bakom hanterar vi klickhändelsen för knappen, i vilken vi lägger till alla textsträngar till ListBox, som det ses på skärmdumpen. Vi använder FindResource () -metoden, som returnerar resursen som ett objekt (om den hittas), och sedan förvandlar vi den till strängen som vi vet att den är med hjälp av ToString () -metoden.

Lägg märke till hur vi använder metoden FindResource () i olika omfattningar - först på panelen, sedan i fönstret och sedan på det aktuella applikationsobjektet. Det är meningsfullt att leta efter resursen där vi vet att den är, men som redan nämnts, om en resurs inte hittas, fortskrider sökningen upp hierarkin, så i princip kunde vi ha använt FindResource-metoden på panelen i alla tre fall, eftersom det skulle ha fortsatt upp till fönstret och senare upp till applikationsnivån, om den inte hittades.

Detsamma gäller inte tvärtom - sökningen navigerar inte längs trädet, så du kan inte börja leta efter en resurs på applikationsnivå, om den har definierats lokalt för kontrollen eller för fönstret.



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow