Читайте также:
|
|
Самое первое место, где программист сталкивается с необходимостью отделить отображение от самих данных – это ресурсы. У каждого элемента есть свойство Resources, представляющее собой обычный словарь, который позволяет искать значение по ключу. Эта простая техника применяется в механизмах поддержки тем, стилизации и привязки к данным.
В программе на языке C# можно определять переменные для последующего использования. Часто это делается ради удобства чтения кода, а иногда в целях обобществления:
public class Window1: Window
{
public Window1()
{
Title = “Resources”;
Brush toShare = new SolidColorBrush(Colors.Yellow);
Button b = new Button();
b.Content = “My Button”;
b.Background = toShare;
Content = b;
}
}
В разметке эта проблема не так проста. Модель грамматического разбора XAML требует, чтобы все создаваемые объекты были свойствами чего-либо. Захоти мы получить кисть, общую для двух кнопок, пришлось бы создавать какой-то вид привязки одного элемента к другому, а это, очевидно, куда сложнее, чем просто завести переменную. Поэтому при разработке WPF было решено ввести единое свойство Resources, в котором можно хранить список именованных объектов. Эти объекты стали бы тогда доступны любому дочернему элементу. В следующем фрагменте кисть определяется в свойстве Resources окна, а затем используется в кнопке:
<Window
Text=’Resources’
xmlns=’http://schemas.microsoft.com/winfx/2006/xaml/presentation’
xmlns:x=’http://schemas.microsoft.com/winfx/2006/xaml’>
<Window.Resources>
<SolidColorBrush x:Key=’toShare’ >Yellow</SolidColorBrush>
</Window.Resources>
<Button Background=’{ StaticResource toShare }’>
My Button
</Button>
</Window>
Путь поиска ресурса несколько сложнее, чем просто проход вверх по иерархии. Просматривается также объект приложения, системная тема и тема по умолчанию для типов. Порядок просмотра таков:
1. Иерархия элементов.
2. Application.Resources.
3. Тема типа.
4. Системная тема.
Ранее мы говорили, что у класса типа Application есть свойство Resources, позволяющее определить ресурсы, глобальные для всего приложения. Рассмотрим на примере:
<Application x:Class=’EssentialWPF.MyApp’
xmlns=’http://schemas.microsoft.com/winfx/2006/xaml/presentation’
xmlns:x=’http://schemas.microsoft.com/winfx/2006/xaml’>
<Application.Resources>
<SolidColorBrush x:Key=’toShare’>Purple</SolidColorBrush>
</Application.Resources>
</Application>
Эта техника позволяет создавать ресурсы, общие для всех страниц, окон и элементов управления. На любом уровне приложения можно переопределить глобальное значение ресурса. В общем случае рекомендуется определять ресурс на самом нижнем возможном уровне. Если некий ресурс используется только в одной панели, то для этой панели его и надо определить. Если же ресурс используется в нескольких окнах, то определить его следует на уровне приложения. Определяя ресурс, важно помнить, что использовать его можно в разных местах. Поскольку каждый элемент WPF может присутствовать только в одном месте дерева отображения, мы не можем надежно использовать элемент в качестве ресурса:
<Window
x:Class=’EssentialWPF.Resources’
Title=’Resources’
xmlns=’http://schemas.microsoft.com/winfx/2006/xaml/presentation’
xmlns:x=’http://schemas.microsoft.com/winfx/2006/xaml’>
<Window.Resources>
<TextBox x:Key=’sharedTextBox’ />
</Window.Resources>
<Button Content=’{StaticResource sharedTextBox}’/>
</Window>
Эта разметка будет работать только, если на элемент sharedTextBox есть только одна ссылка. Попытайся мы воспользоваться этим ресурсом еще раз, приложение завершится с ошибкой:
<Window
x:Class=’EssentialWPF.Resources’
Title=’Resources’
xmlns=’http://schemas.microsoft.com/winfx/2006/xaml/presentation’
xmlns:x=’http://schemas.microsoft.com/winfx/2006/xaml’>
<Window.Resources>
<TextBox x:Key=’sharedTextBox’ />
</Window.Resources>
<StackPanel>
<!— это ошибка! —>
<Button Content=’{StaticResource sharedTextBox}’/>
<Button Content=’{StaticResource sharedTextBox}’/>
</StackPanel>
</Window>
Когда ресурс требуется использовать более одного раза, необходимо прибегнуть к классу FrameworkElementFactory. Для элементов, принадлежащих шаблонам, мы создаем фабрику, а не сами элементы. Большинству визуальных объектов (кистей, перьев, сеток и т.д.) фабрика не нужна, так как многократное использование обеспечивается наследованием классу Freezable.
Почему в лекции о привязке к данным мы говорим о ресурсах? Дело в том, что, используя ссылки на статические ресурсы, мы по существу выполняем присваивание переменной, как в приведенном выше фрагменте на C#. Когда эта переменная используется, никакой связи с исходной переменной уже нет. Рассмотрим следующий код:
Brush someBrush = Brushes.Red;
Button button1 = new Button();
button1.Background = someBrush;
someBrush = Brushes.Yellow;
// button1.Background здесь будет красным
При работе с ресурсами можно либо выполнить аналогичное статическое связывание в форме присваивания, либо организовать динамическое связывание:
<Window
Title=’Resources’
xmlns=’http://schemas.microsoft.com/winfx/2006/xaml/presentation’
xmlns:x=’http://schemas.microsoft.com/winfx/2006/xaml’>
<Window.Resources>
<SolidColorBrush x:Key=’toShare’>Yellow</SolidColorBrush>
</Window.Resources>
<Button Background=’{ DynamicResource toShare }’>
My Button
</Button>
</Window>
Поскольку на этот раз мы воспользовались динамическим связыванием, то можем изменить цвет кнопки, присвоив новое значение свойству Resources окна:
<!— window1.xaml —>
...
<Button Background=’{DynamicResource toShare}’ Click=’Clicked’>
My Button
</Button>
...
// window1.xaml.cs
...
void Clicked(object sender, RoutedEventArgs e)
{
Brush newBrush = new SolidColorBrush(Colors.Blue);
this.Resources[“toShare”] = newBrush;
}
...
Это очень полезный механизм. В сочетании с иерархической областью видимости ресурсов он позволяет обновить сразу все окна или страницы приложения.
Чтобы выполнить динамическое связывание ресурса программно, нам понадобится метод FrameworkElement.SetResourceReference:
button1.SetResourceReference(Button.BackgroundProperty,«toShare»);
Конечно, такие динамические ссылки не обходятся без накладных расходов, поскольку система должна отслеживать изменения ресурса.
При изменении любого ресурса обновляется все дерево. Поэтому статические и динамические ссылки на ресурсы можно использовать во многих местах, стоимость операции от количества ссылок не зависит. А вот часто изменять ресурсы для обновления пользовательского интерфейса не стоит. Зато и тревожиться по поводу большого числа ссылок на ресурсы не надо.
Ресурсы – это особая форма привязки к данным, оптимизированная в расчете на большое число привязок, которые редко обновляются. В общем случае, механизм привязки к данным оптимизирован в предположении умеренного числа привязок (в том числе и двусторонних) с высокой частотой обновления. Этот более общий вид привязки получил и более простое название; в WPF он называется просто связыванием или привязкой.
Дата добавления: 2015-08-13; просмотров: 75 | Нарушение авторских прав
<== предыдущая страница | | | следующая страница ==> |
Задача 4. | | | Основные принципы связывания |