简体   繁体   English

由于绑定到在模板布局之前触发的事件,因此命名范围问题

[英]Name scope issues due to binding to event that gets fired before template layout

Based on some standard web searching, I have narrowed down my problem to this: I believe the event that fires my storyboard gets invoked prior to the template being expanded. 基于一些标准的网络搜索,我已经将我的问题缩小到这个:我相信在模板扩展之前调用触发我的故事板的事件。 Thus, names are meaningless, and name references made by the storyboard's animations are null. 因此,名称毫无意义,故事板动画制作的名称引用为空。

This would not be an issue if I were not working with a ControlTemplate. 如果我不使用ControlTemplate,这不会是一个问题。 I could just bind to the event after the layout is updated, then manually invoke it the first time around. 我可以在更新布局后绑定到事件,然后在第一次手动调用它。 Problem solved. 问题解决了。 However, since this is a ControlTemplate in its own resource dictionary XAML file, I can't use C# to solve this problem. 但是,由于这是自己的资源字典XAML文件中的ControlTemplate,我无法使用C#来解决此问题。

(Update: I can definitively say that this is not an ordering issue--in other words, it has nothing to do with having defined the contents before ControlTemplate.Resources or similar. However, similar problems can be caused by such ordering issues, so this matter is worth investigating if you are encountering similar problems. See one of the answers below made before this update for a more detailed explanation.) (更新:我可以肯定地说这不是一个排序问题 - 换句话说,它与在ControlTemplate.Resources或类似之前定义内容无关。但是,类似的问题可能是由这样的排序问题引起的,所以如果您遇到类似的问题,这个问题值得研究。请参阅此更新前的以下答案之一,以获得更详细的解释。)

Then again, I could be on the wrong track entirely. 然后,我可能完全走错了轨道。 This is just my understanding of what is going on behind the curtain. 这只是我对窗帘背后发生的事情的理解。 So that you can judge for yourself, here is the actual exception: 所以你可以自己判断,这是实际的例外:

System.InvalidOperationException: System.InvalidOperationException:
{"'PART_UnderlineBrush' name cannot be found in the name scope of 'System.Windows.Controls.ControlTemplate'."} {''PART_UnderlineBrush'名称在'System.Windows.Controls.ControlTemplate'的名称范围内找不到。“}

Here is the style/template for reference, with all the extra stuff (storyboards, properties, etc.) removed. 这是参考的样式/模板,删除了所有额外的东西(故事板,属性等)。

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Style x:Key="MetroTabItem" TargetType="{x:Type TabItem}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type TabItem}">
                    <Border>
                        <Border.BorderBrush>
                            <!-- This is the element that I need to reference, but I am unable to do so. -->
                            <SolidColorBrush Color="#00ffffff" x:Name="PART_UnderlineBrush" />
                        </Border.BorderBrush>
                        <ContentPresenter Content="{TemplateBinding Header}"
                                          ContentTemplate="{TemplateBinding HeaderTemplate}" />
                    </Border>
                    <ControlTemplate.Resources>
                        <Storyboard x:Key="SelectTab">
                            <!-- This is the animation that will always fail, due to the name reference. -->
                            <ColorAnimation BeginTime="0:0:0"
                                            Duration="0:0:0.5"
                                            Storyboard.TargetProperty="Color"
                                            Storyboard.TargetName="PART_UnderlineBrush"
                                            To="#ddffffff" />
                        </Storyboard>
                    </ControlTemplate.Resources>
                    <ControlTemplate.Triggers>
                        <EventTrigger RoutedEvent="Selector.Selected">
                            <BeginStoryboard Name="BeginSelected" Storyboard="{StaticResource SelectTab}" />
                        </EventTrigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

I don't know if this will do exactly what you want, but if you replace your EventTrigger with a Trigger for the IsSelected property of the TabItem it might work: 我不知道这是否会完全符合您的要求,但如果您使用TabItem的IsSelected属性的Trigger替换EventTrigger ,它可能会起作用:

<ControlTemplate.Triggers>
    <Trigger Property="IsSelected" Value="True">
        <Trigger.EnterActions>
            <BeginStoryboard Name="BeginSelected" Storyboard="{StaticResource SelectTab}" />
        </Trigger.EnterActions>
    </Trigger>
</ControlTemplate.Triggers>

There does seem to be some timing issue going on with the original code. 原始代码似乎确实存在一些时序问题。 The Selector.Selected event seems to be fired before the control has loaded. Selector.Selected事件似乎在控件加载之前被触发。

Put your 把你的

<ControlTemplate.Resources>

before the 之前

<Border>

Full code: 完整代码:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="MetroTabItem" TargetType="{x:Type TabItem}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TabItem}">
                <ControlTemplate.Resources>
                    <Storyboard x:Key="SelectTab">
                        <!-- This is the animation that will always fail, due to the name reference. -->
                        <ColorAnimation BeginTime="0:0:0"
                                        Duration="0:0:0.5"
                                        Storyboard.TargetProperty="Color"
                                        Storyboard.TargetName="PART_UnderlineBrush"
                                        To="#ddffffff" />
                    </Storyboard>
                </ControlTemplate.Resources>
                <ControlTemplate.Triggers>
                    <EventTrigger RoutedEvent="Selector.Selected">
                        <BeginStoryboard Name="BeginSelected" Storyboard="{StaticResource SelectTab}" />
                    </EventTrigger>
                </ControlTemplate.Triggers>
                <Border>
                    <Border.BorderBrush>
                        <!-- This is the element that I need to reference, but I am unable to do so. -->
                        <SolidColorBrush Color="#00ffffff" x:Name="PART_UnderlineBrush" />
                    </Border.BorderBrush>
                    <ContentPresenter Content="{TemplateBinding Header}"
                                      ContentTemplate="{TemplateBinding HeaderTemplate}" />
                </Border>               
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM