[WPF]: Контрол с возможностью подмены части template?
От: Sinix  
Дата: 30.11.10 09:11
Оценка:
Дано: свой UserControl с крайне сложным template.
Требуется: подменить часть контрола, переиспользуя стили из ресурсов самого template.
аля
<local:SomeControl>
  <local:SomeControl.SomePartTemplate>
   <ControlTemplate>
     <TextBox Style = {DynamicResource {x:static local:SomeControl.SomePartStyleKey}}/>
   </ControlTemplate>
  </local:SomeControl.SomePartTemplate>
</local:SomeControl>

Ещё не пробовал, но причин по которым оно не будет работать не вижу.

В идеале хотелось бы использовать StaticResource, да ещё и не заводить второго инстанса стиля (придётся, если вынести ресурсы в ResourceDictionary).

Как такие вещи принято делать?
Re: [WPF]: Контрол с возможностью подмены части template?
От: MxMsk Португалия  
Дата: 30.11.10 10:25
Оценка: 8 (1)
Здравствуйте, Sinix, Вы писали:

S>Как такие вещи принято делать?

Я стараюсь не тащить никакие стили в Template. И вообще не пользоваться ресурсами шаблонов по двум причинам:
1. Ресурсы шаблона создаются по отдельности для каждого элемента, к которому применяется шаблон.
2. Был опыт, когда стиль, заданный в ресурсе шаблона, не подхватывался через TargetType.
3. Ухудшается читабельность XAML-а.
Re[2]: [WPF]: Контрол с возможностью подмены части template?
От: Sinix  
Дата: 30.11.10 11:01
Оценка:
Здравствуйте, MxMsk, Вы писали:


S>>Как такие вещи принято делать?

MM>Я стараюсь не тащить никакие стили в Template. И вообще не пользоваться ресурсами шаблонов по двум причинам:
MM>1. Ресурсы шаблона создаются по отдельности для каждого элемента, к которому применяется шаблон.
MM>2. Был опыт, когда стиль, заданный в ресурсе шаблона, не подхватывался через TargetType.
MM>3. Ухудшается читабельность XAML-а.

Тут выбора другого нет. Контрол в себе содержит TreeView с весьма нетривиальным биндингом/видом элементов. Иногда требуется целиком заменить template для самого дерева (тут ничего сложного), или подправить item template. С последним всё не так легко. Например, в элементе всегда присутствует пара изображений. ImageSource определяется триггером с кучей условий, но сами изображения могут располагаться как им удобно; в одном из вариантов изображение используется как кисть.

В прототипах обошёлся копипастом, в продакшн тащить такой кошмар не хочу.

Я конечно могу создать наследников от ImageSource и спрятать всю логику там. Осталось придумать как переиспользовать остальные ресурсы шаблона — градиенты, стили на определённые надписи и т.п.
Re[3]: [WPF]: Контрол с возможностью подмены части template?
От: MxMsk Португалия  
Дата: 30.11.10 11:19
Оценка: 16 (1)
Здравствуйте, Sinix, Вы писали:

S>Тут выбора другого нет. Контрол в себе содержит TreeView с весьма нетривиальным биндингом/видом элементов. Иногда требуется целиком заменить template для самого дерева (тут ничего сложного), или подправить item template. С последним всё не так легко. Например, в элементе всегда присутствует пара изображений. ImageSource определяется триггером с кучей условий, но сами изображения могут располагаться как им удобно; в одном из вариантов изображение используется как кисть.

S>В прототипах обошёлся копипастом, в продакшн тащить такой кошмар не хочу.
S>Я конечно могу создать наследников от ImageSource и спрятать всю логику там. Осталось придумать как переиспользовать остальные ресурсы шаблона — градиенты, стили на определённые надписи и т.п.
Так что мешает вынести все стили и ресурсы в отдельный словарь? Или оставить всё в одном словаре с контролом и замерджить его потом в словарь с другим стилем контрола?
Re[4]: [WPF]: Контрол с возможностью подмены части template?
От: Sinix  
Дата: 30.11.10 11:54
Оценка:
Здравствуйте, MxMsk, Вы писали:

MM>Так что мешает вынести все стили и ресурсы в отдельный словарь? Или оставить всё в одном словаре с контролом и замерджить его потом в словарь с другим стилем контрола?


Два нюанса (я не уверен, что тут будут какие-то проблемы):
1. Будет как минимум 2 инстанса каждого ресурса, часть ресурсов — тяжёлые объекты.
2. (некритично) Желательно, чтобы шаблон подхватывал стили, если они переопределены в шаблоне/ресурсах самого контрола.
Re[5]: [WPF]: Контрол с возможностью подмены части template?
От: Codechanger Россия  
Дата: 30.11.10 12:21
Оценка: 16 (1)
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, MxMsk, Вы писали:


MM>>Так что мешает вынести все стили и ресурсы в отдельный словарь? Или оставить всё в одном словаре с контролом и замерджить его потом в словарь с другим стилем контрола?


S>Два нюанса (я не уверен, что тут будут какие-то проблемы):

S>1. Будет как минимум 2 инстанса каждого ресурса, часть ресурсов — тяжёлые объекты.
S>2. (некритично) Желательно, чтобы шаблон подхватывал стили, если они переопределены в шаблоне/ресурсах самого контрола.

Пункт 2 вроде автоматом будет делаться.
Re[5]: [WPF]: Контрол с возможностью подмены части template?
От: MxMsk Португалия  
Дата: 30.11.10 12:49
Оценка:
Здравствуйте, Sinix, Вы писали:

MM>>Так что мешает вынести все стили и ресурсы в отдельный словарь? Или оставить всё в одном словаре с контролом и замерджить его потом в словарь с другим стилем контрола?


S>Два нюанса (я не уверен, что тут будут какие-то проблемы):

S>1. Будет как минимум 2 инстанса каждого ресурса, часть ресурсов — тяжёлые объекты.
Инстансов будет по количеству несвязанных мерджей. Если замерджить словари в ресурсы приложения или generic.xaml, то всё будет пучком.
Re[5]: [WPF]: Контрол с возможностью подмены части template?
От: notacat  
Дата: 30.11.10 13:06
Оценка: 16 (1)
S>1. Будет как минимум 2 инстанса каждого ресурса, часть ресурсов — тяжёлые объекты.
где и почему два?

Я советую все запчасти складывать в один ResourceDictionary вместе с темплейтом контрола. Либо запчасти в отдельном ResourceDictionary, который мержится в ResourceDictionary со темплейтом контрола.
В ресурсы стиля и ресурсы темплейта складывать нехорошо по нескольким причинам:
— xaml будет парситься столько раз, сколько раз вы контрол создаете
— у MS встречаются разные баги на эту тему. Наверняка сейчас не скажу, помню что именно пришлось избавляться от объявления таких вещей in-line или в ресурсах чего-нибудь. Когда оно все на одном уровне без вложенности — это самый стабильный вариант.

StaticResource будет работать только если вы переопределяете одновременно сам ресурс и то место, из которого он используется.
Т.е. с DynamicResource вы можете подменить только запчасти и все, а со StaticResource придется менять и темплейт контрола.
Первое удобней — второе может в рантайме быстрее работать. Мне в одном месте пришлось дублировать стили, только для того, чтобы StaticResource использовать, именно из-за производительности.
й
Re[6]: [WPF]: Контрол с возможностью подмены части template?
От: Sinix  
Дата: 30.11.10 13:14
Оценка:
Здравствуйте, MxMsk, Вы писали:

MM>Инстансов будет по количеству несвязанных мерджей. Если замерджить словари в ресурсы приложения или generic.xaml, то всё будет пучком.


Кажется, то что нужно
Единственный вопрос:
<Window.Resources>
   <ControlTemplate x:key="aaa">
     <TextBox Style = {DynamicResource {x:static local:SomeControl.SomePartStyleKey}}/>
   </ControlTemplate>
</Window.Resources>
<local:SomeControl SomePartTemplate="{DynamicResource aaa}">
</local:SomeControl>

Будет нормально работать если ресурс с ключом SomePartStyleKey определён в generic.xaml сборки с SomeControl?
Re[7]: [WPF]: Контрол с возможностью подмены части template?
От: notacat  
Дата: 30.11.10 13:20
Оценка:
что-то я сомневаюсь. Но если не будет, то надо будет в Window.Resources добавлять этот generic.xaml как MergedDictionary.

Не вижу причин, почему бы в следующем фрагменте не использовать StaticResource:
S>
S><local:SomeControl SomePartTemplate="{DynamicResource aaa}">
S></local:SomeControl>
S>
Re[6]: [WPF]: Контрол с возможностью подмены части template?
От: Sinix  
Дата: 30.11.10 13:22
Оценка:
Здравствуйте, notacat, Вы писали:

S>>1. Будет как минимум 2 инстанса каждого ресурса, часть ресурсов — тяжёлые объекты.

N>где и почему два?
По числу мержей — уже ответил MxMsk выше.

N>Я советую все запчасти складывать в один ResourceDictionary вместе с темплейтом контрола. Либо запчасти в отдельном ResourceDictionary, который мержится в ResourceDictionary со темплейтом контрола.


Не-не, так и сделано — всё в generic.xaml. Очевидно, неправильно описал

N>StaticResource будет работать только если вы переопределяете одновременно сам ресурс и то место, из которого он используется.

Ничего страшного: наследоваться от этих стилей я не буду, с производительностью проблем (тьху-тьху) нет, а для всего остального Static|Dynamic некритично.

Смешно — всякие теоретические нюансы не забыл, а стоит на пару-тройку месяцев оторваться от wpf и приходится перевспоминать самые детские вопросы

Спасибо!
Re: [WPF]: Контрол с возможностью подмены части template?
От: DmitryMS  
Дата: 30.11.10 13:23
Оценка: 8 (1)
Интереснaя, выстраданная тема Я тут
Автор: DmitryMS
Дата: 19.10.10
публиковал код, позволяющий делать 'template injection', в зависимости от свойств элемента. Это можно сделать еще красивей, используя Behavior<T> и стейты, просто недосуг было.
Re[8]: [WPF]: Контрол с возможностью подмены части template?
От: Sinix  
Дата: 30.11.10 13:24
Оценка:
Здравствуйте, notacat, Вы писали:

N>что-то я сомневаюсь. Но если не будет, то надо будет в Window.Resources добавлять этот generic.xaml как MergedDictionary.


Ок, проверю — отпишусь.

N>Не вижу причин, почему бы в следующем фрагменте не использовать StaticResource

Издержки копипаста — прямо в браузере писал.
Re[7]: [WPF]: Контрол с возможностью подмены части template?
От: MxMsk Португалия  
Дата: 30.11.10 13:24
Оценка: 24 (1)
Здравствуйте, Sinix, Вы писали:

S>Будет нормально работать если ресурс с ключом SomePartStyleKey определён в generic.xaml сборки с SomeControl?

Будет. По крайней мере, у нас так стиль окон задается. Лежит в отдельной сборке и назначается окну через StaticResourceExtension.
Re[8]: [WPF]: Контрол с возможностью подмены части template?
От: MxMsk Португалия  
Дата: 30.11.10 13:43
Оценка:
Здравствуйте, notacat, Вы писали:

N>что-то я сомневаюсь. Но если не будет, то надо будет в Window.Resources добавлять этот generic.xaml как MergedDictionary.

Это приведет к тому, что для каждого Window будет своя копия словаря. Та самая проблема с множественными инстансами одного и того же ресурса предстанет во всей красе.
Re[9]: [WPF]: Контрол с возможностью подмены части template?
От: notacat  
Дата: 30.11.10 17:16
Оценка:
N>>что-то я сомневаюсь. Но если не будет, то надо будет в Window.Resources добавлять этот generic.xaml как MergedDictionary.
MM>Это приведет к тому, что для каждого Window будет своя копия словаря. Та самая проблема с множественными инстансами одного и того же ресурса предстанет во всей красе.
это понятно, но если вдруг в приложении не куча окон, то никакой разницы. Просто я навскидку не могу сказать, как будет происходить поиск динамического ресурса в темплейте, который объявлен в ресурсах окна, попадет ли в поиск тот самый generic.xaml из другой сборки.
Re[10]: [WPF]: Контрол с возможностью подмены части template
От: Sinix  
Дата: 01.12.10 03:17
Оценка:
Здравствуйте, notacat, Вы писали:

N>это понятно, но если вдруг в приложении не куча окон, то никакой разницы. Просто я навскидку не могу сказать, как будет происходить поиск динамического ресурса в темплейте, который объявлен в ресурсах окна, попадет ли в поиск тот самый generic.xaml из другой сборки.


Проверил
Автор: Sinix
Дата: 01.12.10
— всё работает из коробки. Приятно
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.