Вот пример использования передового опыта с тем типом управления, который, я думаю, вы пытаетесь построить (см. Примечания в конце для некоторых объяснений): -
[TemplatePart(Name = DatePicker.ElementStartDate, Type = typeof(RadDatePicker))]
[TemplatePart(Name = DatePicker.ElementEndDate, Type = typeof(RadDatePicker))]
public class DatePicker : Control
{
public DatePicker()
{
this.DefaultStyleKey = typeof(DatePicker);
}
#region Template Part Names
private const string ElementStartDate = "startDate";
private const string ElementEndDate = "endDate";
#endregion
#region Template Parts
private RadDatePicker _StartDate;
internal RadDatePicker StartDate
{
get { return _StartDate; }
private set
{
if (_StartDate != null)
{
_StartDate.SelectionChanged -= StartDate_SelectionChanged;
}
_StartDate = value;
if (_StartDate != null)
{
_StartDate.SelectionChanged += StartDate_SelectionChanged;
}
}
}
private RadDatePicker _EndDate;
internal RadDatePicker EndDate
{
get { return _EndDate; }
private set
{
if (_EndDate!= null)
{
_EndDate.SelectionChanged -= EndDate_SelectionChanged;
}
_EndDate= value;
if (_EndDate!= null)
{
_EndDate.SelectionChanged += EndDate_SelectionChanged;
}
}
}
#endregion
public static readonly DependencyProperty StartDateSelectedDateProperty =
DependencyProperty.Register(
"StartDateSelectedDateProperty",
typeof(DateTime?),
typeof(DatePicker),
new PropertyMetaData(new DateTime(2010, 01, 01)));
public DateTime? StartDateSelectedDate
{
get { return (DateTime?)GetValue(StartDateSelectedDateProperty); }
set { SetValue(StartDateSelectedDateProperty)}
}
public static readonly DependencyProperty EndDateSelectedDateProperty =
DependencyProperty.Register(
"EndDateSelectedDateProperty",
typeof(DateTime?),
typeof(DatePicker),
new PropertyMetaData(new DateTime(2010, 01, 01)));
public DateTime? EndDateSelectedDate
{
get { return (DateTime?)GetValue(EndDateSelectedDateProperty); }
set { SetValue(EndDateSelectedDateProperty)}
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
StartDate = GetTemplateChild(ElementStartDate) as RadDatePicker;
EndDate = GetTemplateChild(ElementEndDate) as RadDatePicker;
}
void StartDate_SelectionChanged(object sender, Telerik.Windows.Controls.SelectionChangedEventArgs e)
{
// Do stuff with StartDate here
}
void EndDate_SelectionChanged(object sender, Telerik.Windows.Controls.SelectionChangedEventArgs e)
{
// Do stuff with EndDate here
}
}
Шаблон Xaml должен выглядеть следующим образом:-
<Style TargetType="local:DatePicker">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:DatePicker">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" x:Name="myDatePickerContentArea">
<StackPanel Orientation="Vertical">
<Button x:Name="myTestButton" Content="Test button" />
<telerik:RadDatePicker x:Name="startDate"
Style="{StaticResource VisitsReportTextBoxStyle}"
Foreground="#FFFFFF"
DateTimeWatermarkContent="Start Date"
SelectedDate="{TemplateBinding StartDateSelectedDate}"
/>
<telerik:RadDatePicker x:Name="endDate"
Style="{StaticResource VisitsReportTextBoxStyle}"
DateTimeWatermarkContent="End Date"
SelectedDate="{TemplateBinding EndDateSelectedDate}"
/>
</StackPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Некоторые пояснения
- Ключевая проблема вашего исходного кода заключалась в том, что он неправильно реализовал свойства зависимостей.Обратите внимание, что в свойствах теперь используются
GetValue
и SetValue
, а также что метаданные свойства используются для назначения значения по умолчанию, а не для попытки установки в onapplytemplate. - При правильно реализованных свойствах привязка шаблона должна работатьи на самом деле мы закончили с получением того, что кажется вашим первоначальным намерением, поэтому я упустил любой фактический код в обработчиках событий.
- Создание констант в коде для хранения имен ключейчасти шаблона, с которыми вы хотите взаимодействовать, это позволяет сделать изменения имен менее дорогостоящими.
- Добавьте
TemplatePart
атрибутов к классу, чтобы указать ключевые элементы, которые код ожидает найти, каковы их именадолжно быть и какой базовый тип они должны иметь.Это позволяет дизайнеру повторно шаблонировать существующий элемент управления, пока присутствуют объявленные части шаблона, когда элемент управления должен работать правильно, даже если его пользовательский интерфейс радикально изменен. - Если вам необходимо подключить обработчики событий для некоторыхэлементы создают поле для хранения ссылки на элемент, а затем создают свойство для его обтекания.Затем установщик свойства должен отсоединить и прикрепить обработчики событий, как вы видите в коде.
- Убедитесь, что bae.OnApplyTemplate вызывается в переопределении OnApplyTemplate, так как вы можете видеть его довольно простым для назначения созданного выше.properties.
- У меня нет RadDatePicker, поэтому я не могу проверить, единственное, что меня беспокоит, это то, где
DateTime?
- правильный тип для свойства SelectedDate.Конечно, если это улучшение по сравнению с предложением Microsoft, которое, похоже, не соответствует этому типичному требованию ввода данных.