Ранее у меня был шаблон UserControl, настроенный напрямую, а не через стиль, и все работало хорошо: доступ к корню содержимого можно получить с помощью this.Template.LoadContent () или this.Template.FindName ("MyControlName", это), оба вызова выполняются в OnApplyTemplate, после вызова base.OnApplyTemplate ().Теперь мне нужен стиль, потому что я использую два DataTriggers для отображения типа Control или другого в функции значения Binding.
После отладки с помощью XAML ниже, я вижу, что после base.OnApplyTemplate вызывается this.Template.LoadContent () возвращает Border с установленным дочерним элементом для пустого ContentPresenter.Я хочу получить элемент wpf: TimeSpanPicker.
Я прочитал этот ответ, и он не помогает мне из-за результата отладки, представленного выше.То же самое с этим ответом .
Раньше мой UserControl имел это непосредственно внутри (в своем файле XAML):
<UserControl.Template>
<ControlTemplate>
<wpf:TimeSpanPicker
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch"
Name="MyTimeSpanPicker"
Margin="0,0,7,0"/>
</ControlTemplate>
</UserControl.Template>
Теперь у меня есть это:
<UserControl.Style>
<Style TargetType="UserControl">
<Style.Triggers>
<DataTrigger Binding="{Binding Mode=OneWay, Converter={StaticResource ClockToType}}"
Value="TimerData">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="UserControl">
<wpf:TimeSpanPicker
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch"
Name="MyTimeSpanPicker"
Margin="0,0,7,0"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding Mode=OneWay, Converter={StaticResource ClockToType}}"
Value="AlarmData">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="UserControl">
<Button>Not yet implemented</Button>
</ControlTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</UserControl.Style>
Код включает в себя:
internal wpf_timespanpicker.TimeSpanPicker GetMyTimeSpanPicker()
{
return (wpf_timespanpicker.TimeSpanPicker)Template.LoadContent();
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
GetMyTimeSpanPicker().TimeSpanValueChanged += MyTimeSpanPicker_TimeSpanValueChanged;
}
private void MyTimeSpanPicker_TimeSpanValueChanged(object sender, EventArgs e)
{
CurrentValue = GetMyTimeSpanPicker().TimeSpan;
}
Преобразователь значений ClockToType просто преобразует один из экземпляров моих классов Clock в их имя типа.
Update
Теперь это частично работает из-за ответа, но мне нужно установить свойство зависимостей TimeSpan TimeSpanPicker, когда свойство зависимости CurrentValue UserControl изменяется, а свойство зависимости CurrentValue можно изменить, когда средство выбора промежутка времени еще не загружено.,Каков наилучший способ отложить этот параметр?Кажется, что выполнение вызова ApplyTemplate до установки не работает, поскольку переменная класса, в которой я сохраняю ссылку на TimeSpanPicker, равна нулю:
private static void OnCurrentValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var o = d as ClockValueScreen;
o.ApplyTemplate();
o.MyTimeSpanPicker.TimeSpan = (TimeSpan)e.NewValue; // but here o.MyTimeSpanPicker is null
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate(); // execution reaches this point from the ApplyTemplate call above
}
private void MyTimeSpanPicker_Loaded(object sender, RoutedEventArgs e)
{
MyTimeSpanPicker = (wpf_timespanpicker.TimeSpanPicker)sender;
MyTimeSpanPicker.TimeSpanValueChanged += MyTimeSpanPicker_TimeSpanValueChanged;
}