Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
course_(Windows&Web).docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
4.68 Mб
Скачать

Повторное использование шаблона Control’а

В предыдущем примере описание шаблона расположено внутри элемента. Однако гораздо чаще шаблон Control’а размещают отдельно, т.к. часто вы будете применять шаблон сразу к нескольким Control’ам. Шаблон можно поместить в ресурсы:

<UserControl.Resources> <ControlTemplate x:Key="ButtonTemplate" TargetType="Button" > <Border BorderBrush="Orange" BorderThickness="3" CornerRadius="10" Background="Red"> <TextBlock Foreground="White" Text="A Custom Template"/> </Border> </ControlTemplate> </UserControl.Resources>

Затем в теге кнопки дописать ссылку на StaticResource:

<Button Template="{StaticResource ButtonTemplate}"/>

Такой подход не только упростит создание множества специализированных кнопок, но и позволит вам в будущем свободно модифицировать шаблон Control’а без необходимости изменять каждую кнопку, тем самым, уменьшая риск что-то испортить.

Есть еще один вариант – вы можете вложить описание шаблона в описание стиля. Преимущество такого подхода в том, что стиль может сочетать сеттеры, устанавливающие другие свойства, с сеттером, определяющим новый шаблон Control’а. Применяя стиль к кнопке, вы задействуете все сеттеры. В результате ваша кнопка получит новый шаблон, а также все упомянутые в стиле значения свойств.

ContentPresenter

Кнопка из предыдущего примера довольно бесполезна, т.к. отображает только «вшитый» текст. Вы, конечно же, захотите иметь возможность задавать контент кнопки через свойство Button.Content. Для этого вам понадобится метка-заполнитель специального назначения – «ContentPresenter».

ContentPresenter присутствует во всех Control’ах содержащих какой-либо контент. Это специальная метка означающая «вставь контент здесь» и говорящая Silverlight, куда следует поместить содержимое Control’а. Вот как вы можете применить ее в нашем примере:

<UserControl.Resources> <ControlTemplate x:Key="ButtonTemplate" TargetType="Button" > <Border BorderBrush="Orange" BorderThickness="3" CornerRadius="10" Background="Red"> <ContentPresenter/> </Border> </ControlTemplate> </UserControl.Resources>

Замечание: ContentPresenter – наиболее востребованная, но не единственная метка. Control’ы представляющие списки и использующие ItemsControl применяют в своих шаблона метку ItemsPresenter, определяющую место, где должна располагаться панель списка элементов. Прокручиваемый контент Control’а ScrollViewer представлен меткой ScrollContentPresenter.

Связывание в Шаблонах

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

<Button Template="{StaticResource ButtonTemplate}" Content="A Templated Button" Margin="10" Padding="20"/>

В этой разметке свойствам кнопки Margin и Padding заданы значения 10 и 20 соответственно. За учет свойства Margin отвечает контейнер, содержащий кнопку, поэтому с этим проблем не возникает. Но свойство Padding не берется в расчет, поэтому края кнопки вплотную прилегают к ее контенту. Дело в том, что свойство Padding не будет иметь никакого эффекта, пока вы сами не позаботитесь об этом. Иначе говоря, именно ваш шаблон должен позаботиться о дополнительных отступах вокруг контента кнопки, величина которых задается в Padding.

Для этой цели в Silverlight\WPF есть специальная возможность – связывание в шаблонах (template bindings). С помощью template binding шаблон Control’а сможет извлекать значения свойств Control’а использующего данный шаблон. В следующем примере вы можете использовать template binding для получения значения свойства Padding и создания отступа вокруг ContentPresenter:

<ControlTemplate x:Key="ButtonTemplate" TargetType="Button" > <Border BorderBrush="Orange" BorderThickness="3" CornerRadius="10" Background="Red"> <ContentPresenter Margin="{TemplateBinding Padding}"/> </Border> </ControlTemplate>

Теперь желаемый эффект получен и установлен некоторый зазор между текстом и краями кнопки. Рис. 3.3 демонстрирует вашу новую скромную кнопку:

Рисунок 3.3. Кнопка пользовательского шаблона Control’а

Замечание: Связывание в шаблонах похоже на обычное связывание данных (data bindings), но весит гораздо меньше, поскольку предназначено специально для шаблонов и поддерживает только одностороннее связывание данных (другими словами, можно передать информацию от Control’а в шаблон, но не наоборот).

Стало быть, вам придется добавить в ContentPresenter приличное количество элементов, если вы, конечно, хотите получить полноценную поддержку свойств класса Button и иметь возможность задавать такие свойства как выравнивание, перенос текста, и т.д.. ControlPresenter в составе стандартного шаблона кнопок выглядит примерно так:

<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}"/>

Связывание в шаблонах очень важно для свойства Content. Благодаря связыванию содержимое извлекается из Control’а и отображается в ContentPresenter. Зачастую можно не включать связывание для некоторых свойств шаблона, если вы не намерены их использовать.

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]