2010-01-02 1 views
1

Я подклассифицировал элемент ItemsControl (назовем его EnhancedItemsControl), и я хотел бы показать свойство зависимостей ScrollViewerTemplate, которое позволит пользователю дополнительно указать свой собственный шаблон для используемого ScrollViewer. Я делаю это так:WPF: свойство зависимости с типом шаблона - где получить шаблон по умолчанию (для установки в качестве значения по умолчанию)?

public ControlTemplate ScrollViewerTemplate 
{ 
    get { return (ControlTemplate)GetValue(ScrollViewerTemplateProperty); } 
    set { SetValue(ScrollViewerTemplateProperty, value); } 
} 

public static readonly DependencyProperty ScrollViewerTemplateProperty = 
    DependencyProperty.Register(
    "ScrollViewerTemplate", 
    typeof(ControlTemplate), 
    typeof(EnhancedItemsControl), 
    new UIPropertyMetadata(new ScrollViewer().GetValue(ScrollViewer.TemplateProperty))); //This doesn't work for me 

В моем стиле по умолчанию для моего EnhancedItemsControl, я тогда включить ScrollViewer так:

<ScrollViewer 
    Template="{TemplateBinding ScrollViewerTemplate}" 
    ... 
> 
    <ItemsPresenter 
    ... 
    /> 
</ScrollViewer> 

Это работает, когда пользователь указывает ScrollViewerTemplate, но когда он уходит он по умолчанию, ScrollViewer не отображается (по-видимому, потому, что он Template пуст). Как я могу сказать WPF Использовать шаблон только в том случае, если он не является нулевым, в противном случае используется значение по умолчанию? (мне показалось, что я могу использовать триггеры для установки шаблона только тогда, когда он не равен нулю, но мне не нравится идея запуска триггера для каждого пользовательского свойства в каждом из моих элементов управления ...)

Аналогичная проблема возникает со стилями - если я хочу, чтобы пользователь указывал стиль ScrollViewer, но пользователь не указал его, значение ScrollViewerStyle было бы равно null (равное <ScrollViewer Style="{x:Null}" />), что остановило бы стиль по умолчанию для применения!

Как это решить? Спасибо!

ответ

1

Вы делаете все правильно, кроме одного немного, значение по умолчанию вы указываете в вашем UIPropertyMetadata фактически нулевой, потому что нуль в этом новом ScrollViewer а по умолчанию.

Вместо определения ScrollViewerTemplate собственности, определить ScrollViewerStyle свойство:

public Style ScrollViewerStyle 
{ 
    get { return (Style)GetValue(ScrollViewerTemplateProperty); } 
    set { SetValue(ScrollViewerTemplateProperty, value); } 
} 

public static readonly DependencyProperty ScrollViewerTemplateProperty = 
    DependencyProperty.Register(
     "ScrollViewerStyle", 
     typeof(Style), 
     typeof(EnhancedItemsControl), 
     new UIPropertyMetadata(null)); 

И в вашем стиле по умолчанию для элемента управления, задать значение по умолчанию для стиля, как, например:

<Setter Property="ScrollViewerStyle" Value="{StaticResource {x:Type ScrollViewer}}"/> 

Это фактически по умолчанию будет соответствовать стилю ScrollViewer, определенному текущей темой.

+0

Спасибо, ты мужчина! Я не знал, что могу получить стиль по умолчанию из словаря ресурсов, индексированного по типу, это довольно неинтуитивно - спасибо снова за то, что показал мне, это намного лучше, чем назначать стиль/шаблон с помощью триггера, когда они не равны нулю. –

+1

Пока все остальное неясно, одно несомненно, я человек :) –

1

Вместо использования TemplateBinding вы можете использовать привязку с RelativeSource TemplatedParent. Таким образом, вы сможете использовать конвертер в своем Binding. Теперь объявите конвертер (IValueConverter) для вашего привязки и верните шаблон по умолчанию, пока свойство ScrollViewerTemplate равно null.

More Information

+0

Спасибо, я знаю о возможности замены TemplateBinding нормальным связыванием, но без сообщения Aviad я все равно не знаю, как получить значение по умолчанию шаблона. –

Смежные вопросы