FindName 在 TabItem 上失败

FindName failing on TabItem

我创建了一个应用了 XAML 模板的自定义控件。在自定义控件中,我需要操作图像。为此,我尝试使用 FindName 在 OnApplyTemplate 中查找图像。但是,FindName 返回 null。代码:

public class QaTabItem : TabItem
{
    public static readonly DependencyProperty HotKeyProperty = DependencyProperty.Register("HotKey", typeof(string), typeof(QaTabItem));
    public static readonly DependencyProperty TabImageProperty = DependencyProperty.Register("TabImage", typeof(ImageSource), typeof(QaTabItem));
    public static readonly DependencyProperty TitleProperty = DependencyProperty.Register("Title", typeof(string), typeof(QaTabItem));
    public static readonly DependencyProperty CaptionProperty = DependencyProperty.Register("Caption", typeof(string), typeof(QaTabItem));
    public static readonly DependencyProperty OrientationProperty = DependencyProperty.Register("Orientation", typeof(TabOrientation), typeof(QaTabItem));
    public static readonly DependencyProperty IndexProperty = DependencyProperty.Register("Index", typeof(double), typeof(QaTabItem));
    private Image arrowImage;

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        arrowImage = base.Template.FindName("ArrowImage", this) as Image;
    }
}

模板:

    <Style TargetType="{x:Type Image}" x:Key="ImageRotater">
    <Setter Property="RenderTransformOrigin" Value="0.5, 0.5" />
    <Setter Property="RenderTransform">
        <Setter.Value>
            <RotateTransform Angle="90" />
        </Setter.Value>
    </Setter>
</Style>
<Style TargetType="{x:Type controls:QaTabItem}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type controls:QaTabItem}">                 
                <Border x:Name="ContentBorder"
                Margin="0"
                Background="{DynamicResource AiButtonGreyBrush}"
                BorderBrush="{DynamicResource AiWhiteBrush}"
                BorderThickness="0,.1,0,0">
                    <Grid HorizontalAlignment="Center" VerticalAlignment="Center">
                        <Grid.RowDefinitions>
                            <RowDefinition />
                            <RowDefinition Height="auto" />
                            <RowDefinition />
                        </Grid.RowDefinitions>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="33*" />
                            <ColumnDefinition Width="33*" />
                            <ColumnDefinition Width="33*" />
                        </Grid.ColumnDefinitions>
                        <Label 
                            Grid.Row="0" 
                            Grid.Column="3" 
                            VerticalAlignment="Top" 
                            HorizontalAlignment="Right" 
                            Foreground="{DynamicResource AiGreyBrush}" 
                            FontFamily="Segoe UI"
                            Content="{TemplateBinding HotKey}" />
                        <StackPanel 
                            Grid.Row="1" 
                            Grid.Column="0" 
                            Grid.ColumnSpan="2" 
                            Orientation="Horizontal" 
                            HorizontalAlignment="Center">
                            <Image  
                                Grid.RowSpan="2" 
                                Grid.Column="0" 
                                Stretch="Uniform" 
                                Width="25" 
                                HorizontalAlignment="Left" 
                                Source="{TemplateBinding TabImage}" />
                            <TextBlock 
                                TextWrapping="Wrap" 
                                Margin="20,0,0,0" 
                                Width="75" 
                                Foreground="{DynamicResource AiWhiteBrush}" 
                                FontSize="14"
                                Text="{TemplateBinding Title}" />
                        </StackPanel>
                        <Label 
                            Grid.Row="2" 
                            Content="{TemplateBinding Caption}" 
                            Grid.Column="0" 
                            Grid.ColumnSpan="2" 
                            VerticalAlignment="Top" 
                            FontSize="10" 
                            FontFamily="Segoe UI" 
                            FontWeight="Bold" 
                            Foreground="{DynamicResource AiGreyBrush}" />
                        <Image 
                            x:Name="ArrowImage" 
                            Grid.Row="1" 
                            Grid.Column="2" 
                            Source="{DynamicResource TabItemHeaderArrowIcon}" 
                            HorizontalAlignment="Right" 
                            VerticalAlignment="Center" 
                            Width="20" 
                            Height="20" />
                    </Grid>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

知道为什么当我尝试创建此控件的实例时 OnApplyTemplate 中的 arrowImage 为空吗?

编辑: 我之前没有提到我正在使用此控件作为其他控件的基础 class。当我开始使用它时,我将一个 WPF UserControl 添加到我的项目并将其基础 class 从 UserControl 更改为 QaTabItem。我实际上还没有尝试 运行 代码,因为设计器中发生了故障。

编辑 2: 哎呀。在我的 class.

中忘记了我的依赖属性

德鲁,

不幸的是,如果您使用的 setter 是密封的,则无法以编程方式在模板或样式中使用 FindName。

来自 MSDN https://msdn.microsoft.com/en-uS/office/office365/windows.ui.xaml.setter.property.aspx

如果您使用代码访问 Setter 实例,则不能更改 Setter 实例的任何 属性 的值,如果 IsSealed 属性 在父样式上是 trueIsSealed 属性 也对个人 Setter 进行了报告。当运行时将样式应用于 UI 元素并将它们显示在 UI 中时,系统会将这些属性设置为 true。尝试更改密封的 Setter 会引发运行时错误。

然而,并非一无所有。我注意到在您的模板中,控件 ArrowImage 的来源是 DynamicResource。您是否考虑过在代码中将资源设置为 App Resource 并对其进行操作的可能性?

要在代码中设置为应用程序资源,请将以下行添加到 App.xaml.cs 文件构造函数

App.Current.Resources.Add("TabItemHeaderArrowIcon",null); // <-- Could replace null with a proper image source

那么在你的代码中,你可以如下引用App Resource,

App.Current.Resources["TabItemHeaderArrowIcon"] = your image source

在应用程序关闭时,确保使用

清理应用程序资源(因为它是在内存中分配的)
App.Current.Resources.Remove("TabItemHeaderArrowIcon")

这是一种过去对我有用的方法。希望对你也有帮助。