[英]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.