簡體   English   中英

如何在自定義控件中訪問內部控件模板中的控件

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM