[WPF] Как сделать контрол
От: dmitry_npi Россия  
Дата: 13.11.09 12:39
Оценка:
Заранее извиняюсь за глупый вопрос новичка...

Нашел в интернете туториал, как сделать специфичный ItemControl. Там это сделано так: прямо в окне (XAML) объявляется ItemsControl и модифицирутся некоторые его свойства, например ItemTemplate и ItemsPanel.
Теперь я хочу сделать отдельный custom control, унаследованный от ItemsControl и эти установки свойств перенести в стиль. Создал библиотеку контролов, добавил контрол, унаследовал его от ItemsControl, в ResourceDictionary (Generic.xaml) добавил style setter'ы. В окне теперь инстанцирую этот контрол.


Но эффект не тот же самый! Как мне кажется, в силу того, что в конструкторе контрола прописано
DefaultStyleKeyProperty.OverrideMetadata(typeof(Band), new FrameworkPropertyMetadata(typeof(Band)));

ВСЕ элементы стиля ItemsControl'а заменяются моим стилем. А там видать очень еще много всего, и мой контрол выглядит в итоге пустым. Подскажите, как правильно сделать, чтобы мой контрол сохранял стили своего предка, и при этом добавлял свой. Есть атрибут BasedOn, но не врубился как его использовать...
Атмосферная музыка — www.aventuel.net
Re: [WPF] Как сделать контрол
От: DmitryMS  
Дата: 13.11.09 16:06
Оценка:
Что конкретно вы переопределяете? — ItemTemplate & ItemPanel? Вы айтемы видите свои? Есть две причины, по которым айтемов не видно:
1. Неверно определен ItemTemplate
2. Неверно задан источник данных.
Как проявляется проблема.
Re[2]: [WPF] Как сделать контрол
От: dmitry_npi Россия  
Дата: 14.11.09 14:02
Оценка:
Здравствуйте, DmitryMS, Вы писали:

DMS>Что конкретно вы переопределяете? — ItemTemplate & ItemPanel? Вы айтемы видите свои? Есть две причины, по которым айтемов не видно:

DMS>1. Неверно определен ItemTemplate
DMS>2. Неверно задан источник данных.
DMS>Как проявляется проблема.

Если в статическом конструкторе убираю OverrideMetadata, то вижу обычный ItemsControl. То есть, типа item.GetType().ToString(). Если переопределяю, то не вижу вообще ничего.
Атмосферная музыка — www.aventuel.net
Re: [WPF] Как сделать контрол
От: MxKazan Португалия  
Дата: 14.11.09 16:16
Оценка: 2 (1)
Здравствуйте, dmitry_npi, Вы писали:

_>Заранее извиняюсь за глупый вопрос новичка...


_>Нашел в интернете туториал, как сделать специфичный ItemControl. Там это сделано так: прямо в окне (XAML) объявляется ItemsControl и модифицирутся некоторые его свойства, например ItemTemplate и ItemsPanel.

_>Теперь я хочу сделать отдельный custom control, унаследованный от ItemsControl и эти установки свойств перенести в стиль. Создал библиотеку контролов, добавил контрол, унаследовал его от ItemsControl, в ResourceDictionary (Generic.xaml) добавил style setter'ы. В окне теперь инстанцирую этот контрол.


_>Но эффект не тот же самый! Как мне кажется, в силу того, что в конструкторе контрола прописано

_>DefaultStyleKeyProperty.OverrideMetadata(typeof(Band), new FrameworkPropertyMetadata(typeof(Band)));
_>ВСЕ элементы стиля ItemsControl'а заменяются моим стилем. А там видать очень еще много всего, и мой контрол выглядит в итоге пустым. Подскажите, как правильно сделать, чтобы мой контрол сохранял стили своего предка, и при этом добавлял свой. Есть атрибут BasedOn, но не врубился как его использовать...

Скорее всего в стиле просто не хватает следующей строчки:
BasedOn="{StaticResource {x:Type ItemsControl}}"


Если же не помогло, то покажи нам стиль.
Re: [WPF] Как сделать контрол
От: Vladek Россия Github
Дата: 14.11.09 18:39
Оценка: 2 (1)
Здравствуйте, dmitry_npi, Вы писали:

_>Теперь я хочу сделать отдельный custom control, унаследованный от ItemsControl и эти установки свойств перенести в стиль. Создал библиотеку контролов, добавил контрол, унаследовал его от ItemsControl, в ResourceDictionary (Generic.xaml) добавил style setter'ы. В окне теперь инстанцирую этот контрол.

_>Но эффект не тот же самый! Как мне кажется, в силу того, что в конструкторе контрола прописано
_>
_>DefaultStyleKeyProperty.OverrideMetadata(typeof(Band), new FrameworkPropertyMetadata(typeof(Band)));
_>

_>ВСЕ элементы стиля ItemsControl'а заменяются моим стилем. А там видать очень еще много всего, и мой контрол выглядит в итоге пустым. Подскажите, как правильно сделать, чтобы мой контрол сохранял стили своего предка, и при этом добавлял свой. Есть атрибут BasedOn, но не врубился как его использовать...

Как создать базовый стиль для нового контрола, пять простых шагов:

  1. В статическом конструкторе контрола разместить следующий код:
    DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomControl), new FrameworkPropertyMetadata(typeof(CustomControl)));

    Это значит, что базовый стиль для контрола должен искаться по ключу {x:Type my:CustomControl}, если стиль не задан явно.
  2. В файле AssemblyInfo.cs разместить следующий аттрибут:
    [assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]

    Это значит: None — что стилей для конкретных тем оформления Windows нет (если есть заменить на SourceAssembly, если они в этой же сборке, или на ExternalAssembly, если они в сборках с шаблоном имени <SourceAssemblyName>.<Theme-Name>.dll), SourceAssembly — базовый стиль контрола находится в текущей сборке.
  3. Создать в проекте с контролом папку Themes, в которой разместить файл Generic.xaml с базовым стилем контрола. Стили для конкретных тем оформления размещаются в файлах с шаблоном имени <Theme-Name>.<Color-Scheme>.xaml, например Aero.NormalColor.xaml, Classic.xaml — исключение.
  4. Ключи для всех ресурсов должны иметь следующий вид:
    x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type my:CustomControl}, ResourceId=StringResourceName}"

    Это нужно для того, чтобы не было совпадений с ключами из других сборок, поэтому обычный строковый идентификатор StringResourceName дополняется ссылкой на тип контрола {x:Type my:CustomControl} — это обеспечивает уникальность ключа для ресурса.
  5. Стиль контрола оформляется так:
    <Style x:Key="{x:Type my:CustomControl}" TargetType="{x:Type my:CustomControl}"/>
enum Bool { True, False, FileNotFound }
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.