[WPF] шаблоны: кастомизация динамических эелементов
От: Neco  
Дата: 30.07.11 07:51
Оценка:
По сути два вопроса.
Первый: делаю я, например, контрол и хочу дать возможность пользователю в будущем менять внешний вид его частей. Тогда я именую части как PART_ и следуя описанным в книжках инструкциям всё вроде должно получиться. Но я не могу понять, как быть с теми элементами, которые появляются в моём контроле динамически и не могут иметь заранее определённого имени. Вижу три варианта:
1. делать составные элементы всегда отдельными полноценными контролами. Тогда для них можно будет сделать отдельный шаблон или применить стиль. Однако, что смущает, так это трудозатраты. Т.е. если я например делаю Pager для грида и внутри него динамически будут рисоваться цифры с номерами страниц. По-простому можно было бы просто делать их обычными Label'ами или кнопками, а так придётся делать новый элемент управления PageNumber, что мне кажется более трудоёмким.
2. поместить внутри элемента какой-нибудь именованный элемент, сделать его невидимым, а потом брать копию с него при рисовании своих динамических элементов. Тут во-первых это выглядит как грязный хак да и не уверен, что это вовсе будет работать.
3. смутно подозреваю, что можно это сделать через стили как-то. Т.е. назначить динамическому элементу какой-то особый стиль и потом этот стиль пользователь сможет переопределить. Но это реально смутно, поскольку не представляю как это сделать пока.

Направьте, пожалуйста, на путь истинный — как это грамотно делается, чтоб не тыкаться лишний раз в ненужном направлении?

Второй вопрос как раз по стилям: можно ли как-то сделать так, чтобы стиль применялся, например, только к кнопкам внутри определённого контрола? Т.е. есть некий контрол (не мой), а у него внутри кнопки. Можно ли поменять внешний вид этих кнопок без переопределения всего шаблона данного контрола (ибо сложно)?
всю ночь не ем, весь день не сплю — устаю
Re: [WPF] шаблоны: кастомизация динамических эелементов
От: Ilya81  
Дата: 01.08.11 05:22
Оценка:
Здравствуйте, Neco, Вы писали:

N>По сути два вопроса.

N>Первый: делаю я, например, контрол и хочу дать возможность пользователю в будущем менять внешний вид его частей. Тогда я именую части как PART_ и следуя описанным в книжках инструкциям всё вроде должно получиться. Но я не могу понять, как быть с теми элементами, которые появляются в моём контроле динамически и не могут иметь заранее определённого имени. Вижу три варианта:
N>1. делать составные элементы всегда отдельными полноценными контролами. Тогда для них можно будет сделать отдельный шаблон или применить стиль. Однако, что смущает, так это трудозатраты. Т.е. если я например делаю Pager для грида и внутри него динамически будут рисоваться цифры с номерами страниц. По-простому можно было бы просто делать их обычными Label'ами или кнопками, а так придётся делать новый элемент управления PageNumber, что мне кажется более трудоёмким.
N>2. поместить внутри элемента какой-нибудь именованный элемент, сделать его невидимым, а потом брать копию с него при рисовании своих динамических элементов. Тут во-первых это выглядит как грязный хак да и не уверен, что это вовсе будет работать.
N>3. смутно подозреваю, что можно это сделать через стили как-то. Т.е. назначить динамическому элементу какой-то особый стиль и потом этот стиль пользователь сможет переопределить. Но это реально смутно, поскольку не представляю как это сделать пока.

N>Направьте, пожалуйста, на путь истинный — как это грамотно делается, чтоб не тыкаться лишний раз в ненужном направлении?


N>Второй вопрос как раз по стилям: можно ли как-то сделать так, чтобы стиль применялся, например, только к кнопкам внутри определённого контрола? Т.е. есть некий контрол (не мой), а у него внутри кнопки. Можно ли поменять внешний вид этих кнопок без переопределения всего шаблона данного контрола (ибо сложно)?


Я в своём проекте делаю так: объявляю DependencyProperty (ибо только такое свойство позволяет использовать стили), например (у меня):
[Category("Appearance")]
        public Brush ModuleArrowLineBrush
        {
            get { return (Brush)GetValue(ModuleArrowLineBrushProperty); }
            set { SetValue(ModuleArrowLineBrushProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ModuleArrowLineBrush.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ModuleArrowLineBrushProperty =
            DependencyProperty.Register("ModuleArrowLineBrush", typeof(Brush), typeof(ModuleInputOutputControl), new UIPropertyMetadata(Brushes.Black));

Затем в динамически создаваемой стрелке назначаю кисть из свойства ModuleArrowLineBrush. Есть файл со стилями для этого компонента, в котором написано
<Setter Property="ModuleArrowLineBrush" Value="{StaticResource ResourceKey=ModuleInterfaceArrowLineBrush}"/>

А дальше остаётся указать в другом словаре ресурсов эту кисть ModuleInterfaceArrowLineBrush, причём последний словарь можно менять на ходу. Что касается сторонних компонентов, то если они сделаны по тому ж принципу, то нужно назначить аналогичные свойства. Например, для AvalonDock это будет
<SolidColorBrush x:Key="ManagedContentTabItemNormalBackground" Color="Transparent"/>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.