Главная » Silverlight » Подключенные свойства пример кода

0

В главе 2 введен специальный тип зависимых свойств — подключенные свойства. Они представляют собой полнофункциональную версию зависимых свойств и так же, как и они, управляются системой свойств Silverlight. Отличие состоит в том, что под­ключенное свойство применяется к классу, отличному от того, в котором оно определено.

Наиболее характерный пример подключенных свойств можно увидеть в контейне­рах (см. главу 3). В частности, в классе Grid определены подключенные свойства Row и Column, которые устанавливаются в элементах содержимого для их позиционирова­ния. Аналогично этому в классе Canvas определены подключенные свойства Left и Тор, позволяющие размещать элементы с помощью абсолютных координат.

Для определения подключенного свойства, в отличие от обычного зависимого, ис­пользуется метод DependencyProperty .RegisterAttached (), а не Register () . Ниже при­веден пример кода, который регистрирует свойство Grid.Row.

Grid.RowProperty = DependencyProperty.RegisterAttached("Row", typeof(int), typeof(Grid), null);

Сигнатура метода RegisterAttached () такая же, как и метода Register ().

При создании подключенного свойства определять оболочку свойства .NET не нуж­но. Это объясняется тем, что подключенное свойство можно установить через любой зависимый объект. Например, свойство Grid.Row можно установить через объект Grid (если один элемент Grid вложен в другой) или через другой элемент. Установить свой­ство Grid.Row через элемент можно, даже если он не находится в контейнере Grid или в дереве элементов определено более одного объекта Grid.

Вместо оболочки свойства .NET, подключенному свойству необходима пара стати­ческих методов, которые можно вызвать для чтения и установки значения свойства.

В этих статических методах применяются методы SetValue () и GetValue (), наследуе­мые от класса DependencyObject. Статические методы должны иметь имена Setимя_ свойства() и Getимя_свойства().

Ниже приведен пример статических методов, реализующих подключенное свойство Grid.Row. Метод SetPropertyName () принимает два аргумента: элемент, для которого устанавливается свойство, и значение свойства. Свойство Grid.Row определено как це­лое, поэтому второй параметр метода SetRow () должен быть целочисленным.

public static void SetRow(UIElement element, int value)

{

element.SetValue(Grid.RowProperty, value);

}

Метод GetPropertyName () принимает элемент, обладающий данным свойством, и возвращает значение свойства. Свойство Grid. Row определено как целое, поэтому ме­тод GetRow () должен возвращать целочисленное значение.

public static int GetRow(UIElement element)

{

return (int)element.GetValue(Grid.RowProperty);

}

Позиционировать элемент в первой строке решетки Grid можно с помощью следу­ющего кода.

Grid.SetRow(txtElement, 0) ;

Приведенный оператор присваивает свойству Grid.Row значение 0 через объект txtElement, являющийся текстовым блоком TextBox. Свойство Grid.Row подключенное, поэтому его можно применить к любому другому элементу.

Пример с контейнером WrapBreakPanel

Теперь, когда вы знакомы с теорией зависимых свойств, можно рассмотреть их ис­пользование в реальном примере.

В главе 3 рассматривается создание пользовательских контейнеров, в которых опре­делены потоки элементов во многих строках для размещения в доступном пространстве панели. Например, пользовательская панель UniformGrid размещает элементы в не­видимой решетке, состоящей из одинаковых ячеек. В данном разделе рассматривается другая пользовательская панель — WrapBreakPanel, — объявленная следующим образом.

public class WrapBreakPanel : System.Windows.Controls.Panel

{ … }

Обычно панель WrapBreakPanel работает так же, как WrapPanel, хоть и не наследу­ет ее логику. Как и WrapPanel, панель WrapBreakPanel размещает дочерние элементы один за другим, переходя к следующей строке каждый раз, когда в текущей не остает­ся места. Однако в WrapBreakPanel добавлен ряд дополнительных средств, не реализу­емых панелью WrapPanel. Например, она позволяет установить принудительное завер­шение строки в любом месте с помощью подключенного свойства.

Примечание. Полный код панели WrapBreakPanel можно найти в кодах примеров для данной главы. В данном разделе рассматриваются только свойства, позволяющие настраивать поведение панели.

Панель WrapBreakPanel является элементом Silverlight, поэтому в ней применяются зависимые свойства, позволяющие использовать ее для связывания данных и в анимации.

Во многих случаях имеет смысл установить свойство Orientation, как и в WrapPanel. В приведенном ниже коде в класс WrapBreakPanel добавляется свойство Orientation, имеющее тип System.Windows .Controls .Orientation.

public static readonly DependencyProperty OrientationProperty = DependencyProperty.Register( "Orientation", typeof (Orientation)», typeof(WrapBreakPanel),

new PropertyMetadata(Orientation.Horizontal));

В этом коде используется несложный прием экономии времени. Регистрация свойства выполняется не в статическом конструкторе, а в определении. Изменять ском­пилированный код не нужно. Кроме того, в данном коде устанавливается значение по умолчанию Orientation.Horizontal.

Необходимо также добавить оболочку свойства.

public Orientation Orientation

get

(

return (Orientation)GetValue(OrientationProperty);

}

set

{

SetValue(OrientationProperty, value);

}

} ‘

При использовании WrapBreakPanel на странице Silverlight можно установить свой­ство Orientation, как и любое другое свойство.

<local:WrapBreakPanel Margin="5" Orientation="Vertical">

</local:WrapBreakPanel>

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

Панель WrapBreakPanel определяет подключенное свойство, предназначенное для принудительного разрыва строки любым элементом. Это позволяет задать вывод элемента в новой строке независимо от ширины контейнера. Подключенное свойство называется LineBreakBefore; в контейнере оно определено следующим образом.

public static DependencyProperty LineBreakBeforeProperty = DependencyProperty.RegisterAttached("LineBreakBefore", typeof(bool), typeof(WrapBreakPanel), null);

Для реализации свойства LineBreakBefore нужно создать статические методы обра­щения к нему, вызывающие методы GetValue () и SetValue () через элемент.

public static bool GetLineBreakBefore(UIElement eiement)

(

return (bool)element.GetValue(LineBreakBeforeProperty) ;

}

public static void SetLineBreakBefore(UIElement element,

bool value)

(

element.SetValue(LineBreakBeforeProperty, value);

)

В методы MeasureOverride () и ArrangeOverride () можно вставить проверку, необ­ходим ли разрыв.

if ((currentLineSize.Width + desiredSize.Width > constraint.Width) I I

(WrapBreakPanel.GetLineBreakBefore (element))) (…) .

Чтобы применить разрыв, добавьте свойство LineBreakBefore в разметку элемента.

clocal:WrapBreakPanel Margin="5" Background="LawnGreen"> <Button Width="50" Content="кнопка"></Button> <Button Width="150" Content="Широкая кнопка"></Button> <Button Width="50" Content="Кнопка"></Button> <Button Width="150" Content="Кнопка с разрывом" local: WrapBreakPanel.LineBreakBefore="True" FontWeight="Bold"></Button> <Button Width="150" Content="Широкая кнопка"></Button> <Button Width="50" Content="Кнопка"></Button> </local:WrapBreakPanel>

Результат показан на рис. 4.1.

Рис. 4.1. Панель WrapBreakPanel, поддерживающая разрыв строки

Источник: Мак-Дональд, Мэтью. Silverlight 3 с примерами на С# для профессионалов. : Пер. с англ. —- М. : ООО «И.Д. Вильяме», 2010. — 656 с. : ил. — Парал. тит. англ.

По теме:

  • Комментарии