Jak zdefiniować i odwołać się do zasobu WPF (WPF .NET)

W tym przykładzie pokazano, jak zdefiniować zasób i odwołać się do niego. Zasób można odwoływać się za pomocą języka XAML lub kodu.

Przykład XAML

W poniższym przykładzie zdefiniowano dwa typy zasobów: SolidColorBrush zasób i kilka Style zasobów.

<Window.Resources>
    <SolidColorBrush x:Key="MyBrush" Color="#05E0E9"/>
    <Style TargetType="Border">
        <Setter Property="Background" Value="#4E1A3D" />
        <Setter Property="BorderThickness" Value="5" />
        <Setter Property="BorderBrush">
            <Setter.Value>
                <LinearGradientBrush>
                    <GradientStop Offset="0.0" Color="#4E1A3D"/>
                    <GradientStop Offset="1.0" Color="Salmon"/>
                </LinearGradientBrush>
            </Setter.Value>
        </Setter>
    </Style>
    <Style TargetType="TextBlock" x:Key="TitleText">
        <Setter Property="FontSize" Value="18"/>
        <Setter Property="Foreground" Value="#4E87D4"/>
        <Setter Property="FontFamily" Value="Trebuchet MS"/>
        <Setter Property="Margin" Value="0,10,10,10"/>
    </Style>
    <Style TargetType="TextBlock" x:Key="Label">
        <Setter Property="HorizontalAlignment" Value="Right"/>
        <Setter Property="FontSize" Value="13"/>
        <Setter Property="Foreground" Value="{StaticResource MyBrush}"/>
        <Setter Property="FontFamily" Value="Arial"/>
        <Setter Property="FontWeight" Value="Bold"/>
        <Setter Property="Margin" Value="0,3,10,0"/>
    </Style>
</Window.Resources>

Zasoby

Zasób SolidColorBrush MyBrush służy do podawania wartości kilku właściwości, które każda Brush z nich przyjmują wartość typu. Ten zasób jest przywołyyny za pomocą x:Key wartości .

<Border>
    <StackPanel>
        <TextBlock Style="{StaticResource TitleText}">Title</TextBlock>
        <TextBlock Style="{StaticResource Label}">Label</TextBlock>
        <TextBlock HorizontalAlignment="Right" FontSize="36" Foreground="{StaticResource MyBrush}" Text="Text" Margin="20" />
        <Button HorizontalAlignment="Left" Height="30" Background="{StaticResource MyBrush}" Margin="40">Button</Button>
        <Ellipse HorizontalAlignment="Center" Width="100" Height="100" Fill="{StaticResource MyBrush}" Margin="10" />
    </StackPanel>
</Border>

W poprzednim przykładzie MyBrush zasób jest uzyskiwany za pomocą rozszerzenia StaticResource Markup. Zasób jest przypisywany do właściwości, która może akceptować typ zdefiniowanego zasobu. W tym przypadku Backgroundwłaściwości , Foregroundi Fill .

Wszystkie zasoby w słowniku zasobów muszą podać klucz. Gdy style są jednak zdefiniowane, mogą pominąć klucz, jak wyjaśniono w następnej sekcji.

Zasoby są również żądane przez zamówienie znalezione w słowniku, jeśli używasz rozszerzenia StaticResource Markup do odwołowania się do nich z innego zasobu. Upewnij się, że dowolny zasób, do którego odwołujesz się, jest zdefiniowany w kolekcji wcześniej niż żądany zasób. Aby uzyskać więcej informacji, zobacz Zasoby statyczne.

W razie potrzeby można obejść ścisłą kolejność tworzenia odwołań do zasobów przy użyciu rozszerzenia DynamicResource Markup w celu odwołania się do zasobu w czasie wykonywania, ale należy pamiętać, że ta DynamicResource technika ma konsekwencje dotyczące wydajności. Aby uzyskać więcej informacji, zobacz Zasoby dynamiczne.

Zasoby stylu

Poniższy przykład odwołuje się do stylów niejawnie i jawnie:

<Border>
    <StackPanel>
        <TextBlock Style="{StaticResource TitleText}">Title</TextBlock>
        <TextBlock Style="{StaticResource Label}">Label</TextBlock>
        <TextBlock HorizontalAlignment="Right" FontSize="36" Foreground="{StaticResource MyBrush}" Text="Text" Margin="20" />
        <Button HorizontalAlignment="Left" Height="30" Background="{StaticResource MyBrush}" Margin="40">Button</Button>
        <Ellipse HorizontalAlignment="Center" Width="100" Height="100" Fill="{StaticResource MyBrush}" Margin="10" />
    </StackPanel>
</Border>

W poprzednim przykładzie Style kodu zasoby TitleText i Label, każdy element docelowy określonego typu kontrolki. W tym przypadku oba elementy mają wartość docelową TextBlock. Style ustawiają różne właściwości kontrolek docelowych, gdy ten zasób stylu odwołuje się do jego klucza zasobu dla Style właściwości.

Styl, który jest przeznaczony dla kontrolki Border , nie definiuje klucza. Po pominięciu klucza typ obiektu docelowego przez TargetType właściwość jest niejawnie używany jako klucz stylu. Gdy styl jest kluczem do typu, staje się domyślnym stylem dla wszystkich kontrolek tego typu, o ile te kontrolki znajdują się w zakresie stylu. Aby uzyskać więcej informacji, zobacz Style, DataTemplates i niejawne klucze.

Przykłady kodu

Poniższe fragmenty kodu pokazują tworzenie i ustawianie zasobów za pomocą kodu

Tworzenie zasobu stylu

Tworzenie zasobu i przypisywanie go do słownika zasobów może nastąpić w dowolnym momencie. Jednak tylko elementy XAML używające składni DynamicResource zostaną automatycznie zaktualizowane przy użyciu zasobu po jego utworzeniu.

Weźmy na przykład następujące okno. Ma cztery przyciski. Przycisk forth używa dynamicResource do stylu samego siebie. Jednak ten zasób jeszcze nie istnieje, więc wygląda jak normalny przycisk:

<StackPanel Margin="5">
    <Button Click="Button_Click">Explicitly Styled</Button>
    <Button>Unstyled</Button>
    <Button>Unstyled</Button>
    <Button Style="{DynamicResource ResourceKey=buttonStyle1}">Dynamically Styled</Button>
</StackPanel>

Okno przed zastosowaniem stylu do przycisku

Następujący kod jest wywoływany po kliknięciu pierwszego przycisku i wykonaniu następujących zadań:

  • Tworzy kilka kolorów w celu łatwego odwołania.
  • Tworzy nowy styl.
  • Przypisuje zestawy do stylu.
  • Dodaje styl jako zasób o nazwie buttonStyle1 do słownika zasobów okna.
  • Przypisuje styl bezpośrednio do przycisku podnoszącego Click zdarzenie.
private void Button_Click(object sender, RoutedEventArgs e)
{
    // Create colors
    Color purple = (Color)ColorConverter.ConvertFromString("#4E1A3D");
    Color white = Colors.White;
    Color salmon = Colors.Salmon;

    // Create a new style for a button
    var buttonStyle = new Style(typeof(Button));

    // Set the properties of the style
    buttonStyle.Setters.Add(new Setter(Control.BackgroundProperty, new SolidColorBrush(purple)));
    buttonStyle.Setters.Add(new Setter(Control.ForegroundProperty, new SolidColorBrush(white)));
    buttonStyle.Setters.Add(new Setter(Control.BorderBrushProperty, new LinearGradientBrush(purple, salmon, 45d)));
    buttonStyle.Setters.Add(new Setter(Control.BorderThicknessProperty, new Thickness(5)));

    // Set this style as a resource. Any DynamicResource tied to this key will be updated.
    this.Resources["buttonStyle1"] = buttonStyle;

    // Set this style directly to a button
    ((Button)sender).Style = buttonStyle;
}
Private Sub Button_Click(sender As Object, e As RoutedEventArgs)

    'Create colors
    Dim purple = DirectCast(ColorConverter.ConvertFromString("#4E1A3D"), Color)
    Dim white = Colors.White
    Dim salmon = Colors.Salmon

    'Create a new style for a button
    Dim buttonStyle As New Style()

    'Set the properties of the style
    buttonStyle.Setters.Add(New Setter(Control.BackgroundProperty, New SolidColorBrush(purple)))
    buttonStyle.Setters.Add(New Setter(Control.ForegroundProperty, New SolidColorBrush(white)))
    buttonStyle.Setters.Add(New Setter(Control.BorderBrushProperty, New LinearGradientBrush(purple, salmon, 45D)))
    buttonStyle.Setters.Add(New Setter(Control.BorderThicknessProperty, New Thickness(5)))

    'Set this style as a resource. Any DynamicResource looking for this key will be updated.
    Me.Resources("buttonStyle1") = buttonStyle

    'Set this style directly to a button
    DirectCast(sender, Button).Style = buttonStyle

End Sub

Po uruchomieniu kodu zostanie zaktualizowane okno:

Okno po zastosowaniu stylu do przycisku

Zwróć uwagę, że styl przycisku został zaktualizowany. Styl został zastosowany automatycznie, ponieważ przycisk użył rozszerzenia znaczników DynamicResource, aby odwołać się do stylu, który jeszcze nie istnieje. Po utworzeniu stylu i dodaniu go do zasobów okna został zastosowany do przycisku. Aby uzyskać więcej informacji, zobacz Zasoby dynamiczne.

Znajdowanie zasobu

Poniższy kod przechodzi przez drzewo logiczne obiektu XAML, w którym jest uruchamiany, aby znaleźć określony zasób. Zasób może być zdefiniowany na samym obiekcie, jest elementem nadrzędnym, przez cały sposób do katalogu głównego, samą aplikacją. Poniższy kod wyszukuje zasób, zaczynając od samego przycisku:

myButton.Style = myButton.TryFindResource("buttonStyle1") as Style;
myButton.Style = myButton.TryFindResource("buttonStyle1")

Jawne odwołanie do zasobu

Jeśli masz odwołanie do zasobu, wyszukując go lub tworząc go, można go przypisać bezpośrednio do właściwości:

// Set this style as a resource. Any DynamicResource tied to this key will be updated.
this.Resources["buttonStyle1"] = buttonStyle;
'Set this style as a resource. Any DynamicResource looking for this key will be updated.
Me.Resources("buttonStyle1") = buttonStyle

Zobacz też