【问题标题】:How to access controls in inside Control Template in a Custom control如何在自定义控件中访问控件模板内部的控件
【发布时间】:2015-10-21 09:40:50
【问题描述】:

我正在开发一个 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);

【问题讨论】:

    标签: c# wpf xaml controls


    【解决方案1】:

    这可能是因为当您尝试在里面找到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);
        }
    }
    

    【讨论】:

    • 嗨,Almulo 我尝试了你的建议。它仍然给null。非常感谢
    【解决方案2】:

    使用 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>
    

    【讨论】:

      猜你喜欢
      • 2015-09-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-05
      • 1970-01-01
      • 2023-03-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多