Поиск…


Привет, ресурсы

WPF вводит очень удобную концепцию: возможность хранения данных как ресурса, локально для элемента управления, локально для всего окна или по всему миру для всего приложения. Данные могут быть практически такими, какие вы хотите, от фактической информации до иерархии элементов управления WPF. Это позволяет размещать данные в одном месте, а затем использовать их или из нескольких других мест, что очень полезно. Концепция много используется для стилей и шаблонов.

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

введите описание изображения здесь

Ресурсам предоставляется ключ, используя атрибут x: Key, который позволяет ссылаться на него с других частей приложения с помощью этого ключа в сочетании с расширением разметки StaticResource. В этом примере я просто храню простую строку, которую я затем использую из двух разных элементов управления TextBlock.

Типы ресурсов

Совместное использование простой строки было легко, но вы можете сделать гораздо больше. В этом примере я также сохраню полный массив строк, а также градиентную кисть, которая будет использоваться для фона. Это должно дать вам довольно хорошее представление о том, сколько вы можете сделать с ресурсами:

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

введите описание изображения здесь

На этот раз мы добавили несколько дополнительных ресурсов, так что наше окно теперь содержит простую строку, массив строк и LinearGradientBrush. Строка используется для метки, массив строк используется как элементы для элемента управления ComboBox, а градиентная кисть используется в качестве фона для всего окна. Итак, как вы можете видеть, практически все может быть сохранено в качестве ресурса.

Локальные и прикладные широкие ресурсы

Если вам нужен только определенный ресурс для определенного элемента управления, вы можете сделать его более локальным, добавив его к этому конкретному элементу управления, а не к окну. Он работает точно так же, с той лишь разницей, что теперь вы можете получить доступ только из области управления, где вы его разместили:

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

В этом случае мы добавляем ресурс в StackPanel, а затем используем его из дочернего элемента управления Label. Другие элементы управления внутри StackPanel также могли бы использовать его, точно так же, как дети этих дочерних элементов управления могли бы получить к нему доступ. Однако элементы управления вне этого конкретного StackPanel не имели бы доступа к нему.

Если вам нужна возможность доступа к ресурсу из нескольких окон, это также возможно. Файл App.xaml может содержать ресурсы, такие как окно и любой вид элемента управления WPF, а когда вы храните их в 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/ExtendedResourceSample.xaml">
    <Application.Resources>
        <sys:String x:Key="ComboBoxTitle">Items:</sys:String>
    </Application.Resources>
</Application>

Использование этого же метода - WPF автоматически поднимет область действия, от локального элемента управления до окна и затем до App.xaml, чтобы найти данный ресурс:

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

Ресурсы от Code-behind

В этом примере мы будем получать доступ к трем различным ресурсам из кода-за-конца, каждый из которых хранится в другой области

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>

Окно:

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

Код-за:

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

введите описание изображения здесь

Итак, как вы можете видеть, мы сохраняем три разных «Привет, мир!». Сообщения: один в App.xaml, один внутри окна и один локально для главной панели. Интерфейс состоит из кнопки и ListBox.

В Code-behind мы обрабатываем событие нажатия кнопки, в котором мы добавляем каждую из текстовых строк в ListBox, как показано на скриншоте. Мы используем метод FindResource (), который возвращает ресурс как объект (если он найден), а затем мы превращаем его в строку, которую мы знаем, используя метод ToString ().

Обратите внимание, как мы используем метод FindResource () в разных областях - сначала на панели, затем в окне, а затем на текущем объекте приложения. Имеет смысл искать ресурс, где мы его знаем, но, как уже упоминалось, если ресурс не найден, поиск прогрессирует по иерархии, поэтому в принципе мы могли бы использовать метод FindResource () на панели в все три случая, так как это продолжалось бы до окна, а затем до уровня приложения, если не было найдено.

То же самое не так, наоборот: поиск не перемещается по дереву, поэтому вы не можете начать поиск ресурса на уровне приложения, если он определен локально для элемента управления или для окна.



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow