![](/img/trans.png)
[英]How to apply a custom style to a control inside of a custom control template?
[英]How to access controls in inside Control Template in a Custom control
我正在开发一个 WPF 自定义控件
<ResourceDictionary xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MultiSelectComboBox">
<Style TargetType="{x:Type local:MultiSelectComboBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:MultiSelectComboBox}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions >
<telerik:RadComboBox x:Name="PART_ComboBox"
Grid.Column="0"
ItemsSource="{Binding ItemsSource,RelativeSource={RelativeSource TemplatedParent}}" >
<telerik:RadComboBox.Template>
<ControlTemplate>
<TextBlock x:Name="PART_ComboText"/>
</ControlTemplate>
</telerik:RadComboBox.Template>
<telerik:RadComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox x:Name="PART_ItemCheckBox"/>
<TextBlock x:Name="PART_ItemText"/>
</StackPanel>
</DataTemplate>
</telerik:RadComboBox.ItemTemplate>
</telerik:RadComboBox>
<CheckBox Grid.Column="1" x:Name="PART_SelectAllCheckBox" VerticalAlignment="Center" IsChecked="{TemplateBinding IsAllSelected}" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
我想访问 PART_ComboText
我可以使用 GetTempalteChild 方法访问在那里定义的控件
part_comboBox = GetTemplateChild("PART_ComboBox") as RadComboBox;
但我无法访问控制模板中的控件。 例如,控制模板中的示例无法访问它。 我知道我们无法从背后的代码访问控制模板。
我试过这个方法。 它也不起作用。
part_comboBox = GetTemplateChild("PART_ComboBox") as RadComboBox;
var comboBoxTemplate = part_comboBox.Template;
part_comboText = (TextBlock) comboBoxTemplate.FindName("PART_ComboText", part_comboBox);
这可能是因为当您尝试在其中查找TextBlock
时, RadComboBox
未完全加载。
检查它的IsLoaded
属性以了解它是否准备就绪。 如果不是,则必须推迟代码的执行,直到引发其Loaded
事件。
part_comboBox = GetTemplateChild("PART_ComboBox") as RadComboBox;
if (part_comboBox.IsLoaded)
{
part_comboText = part_comboBox.FindName("PART_ComboText");
DoStuffWithComboText(part_comboText);
}
else
{
part_comboBox.Loaded = new RoutedEventHandler((o, e) =>
{
part_comboText = part_comboBox.FindName("PART_ComboText");
// Or... part_comboText = part_comboBox.Template.FindName("PART_ComboText", part_comboBox); ... can't remember which one was correct in this case
DoStuffWithComboText(part_comboText);
}
}
使用 OnApplyTemplate() 操作子控件并在静态方法 PropertyChangedCallback 中调用它:
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
if (Template != null)
{
Image partImage = Template.FindName("PART_Image", this) as Image;
if (partImage != null)
{
if (String.IsNullOrEmpty(Picture))
{
partImage.Visibility = Visibility.Hidden;
partImage.Width = 0;
}
else
{
partImage.Visibility = Visibility.Visible;
partImage.Width = 16;
}
}
}
}
public string Picture
{
get => (string)GetValue(PictureProperty);
set => SetValue(PictureProperty, value);
}
private static void OnPictureChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
ButtonUI control = d as ButtonUI;
control.OnApplyTemplate();
}
主题中的通用很简单:
<Style TargetType="{x:Type local:ButtonUI}" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="Height" Value="24" />
<Setter Property="Width" Value="100" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:ButtonUI}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<WrapPanel VerticalAlignment="Center" HorizontalAlignment="Center">
<Image Name="PART_Image" Source="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type local:ButtonUI}},Path=Picture}" Height="16" Width="16" Margin="2,0,2,0" />
<TextBlock Name="PART_Caption" Text="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type local:ButtonUI}},Path=Caption}" Margin="2,0,2,0" />
</WrapPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.