0

背景:一个新的 Sketchflow / Silverlight 项目。Expression Blend 4(终极版)

我有下面的代码。我有一个带有 2 个 TabItem 的 TabControl。我还有 2 个“标注”(大气泡的东西)作为状态变化的快速视觉。

我创建了一个 VisualStateGroup 并添加到它下面的状态。当我从 NAVIGATE 窗口手动调用这些(在我运行项目之后)时,状态按预期工作。callout1 和 callout2 翻转它们的不透明度(在 100% 和 10% 之间)。因此,我对 State 及其运作方式有了基本的了解。

但是,当我向 TabItem 添加触发器事件时,触发器看起来不错,但不起作用。下面是一个剥离的例子,一直到裸露的骨头。

我尝试了 EventName="MouseLeftButtonDown" 和 EventName="Click" 却没有成功。

我还注释掉了 ObjectAnimationUsingKeyFrames 标签,那里也没有运气。

有人看到我错过了什么吗?

基本上,我无法获得(选择)一个 TabItem 来触发状态更改。

谢谢。

------------开始 XAML 代码

<UserControl 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
xmlns:data="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" 
xmlns:System="clr-namespace:System;assembly=mscorlib" 
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 
xmlns:pi="http://schemas.microsoft.com/prototyping/2010/interactivity"
xmlns:ed="http://schemas.microsoft.com/expression/2010/drawing"
    x:Class="MyProject.MyScreen"
    Width="640" Height="480" mc:Ignorable="d">

    <Grid x:Name="LayoutRoot" Background="White">

                <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="VisibleTabs">
                <VisualState x:Name="Tab1VisualState">
                    <Storyboard>
                        <DoubleAnimation Duration="0" To="1.0" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="callout1" d:IsOptimized="True"/>
                        <DoubleAnimation Duration="0" To="0.1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="callout2" d:IsOptimized="True"/>

                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(TabControl.SelectedIndex)" Storyboard.TargetName="tabControl">
                            <DiscreteObjectKeyFrame KeyTime="0">
                                <DiscreteObjectKeyFrame.Value>
                                    <System:Int32>0</System:Int32>
                                </DiscreteObjectKeyFrame.Value>
                            </DiscreteObjectKeyFrame>
                        </ObjectAnimationUsingKeyFrames>


                    </Storyboard>
                </VisualState>
                <VisualState x:Name="Tab2VisualState">
                    <Storyboard>

                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(TabControl.SelectedIndex)" Storyboard.TargetName="tabControl">
                            <DiscreteObjectKeyFrame KeyTime="0">
                                <DiscreteObjectKeyFrame.Value>
                                    <System:Int32>1</System:Int32>
                                </DiscreteObjectKeyFrame.Value>
                            </DiscreteObjectKeyFrame>
                        </ObjectAnimationUsingKeyFrames>

                        <DoubleAnimation Duration="0" To="0.1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="callout1" d:IsOptimized="True"/>
                        <DoubleAnimation Duration="0" To="1.0" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="callout2" d:IsOptimized="True"/>


                    </Storyboard>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>


        <data:TabControl x:Name="tabControl" Height="150" Margin="41,0,215,50" VerticalAlignment="Bottom" SelectedIndex="0">
            <data:TabItem Header="Tab Number One" Height="24" VerticalAlignment="Bottom">
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="MouseLeftButtonDown">
                        <pi:ActivateStateAction TargetState="Tab1VisualState"/>
                    </i:EventTrigger>
                </i:Interaction.Triggers>

            </data:TabItem>
            <data:TabItem Header="Tab Number Two">
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="MouseLeftButtonDown">
                        <pi:ActivateStateAction TargetState="Tab2VisualState"/>
                    </i:EventTrigger>
                </i:Interaction.Triggers>

            </data:TabItem>
        </data:TabControl>

        <ed:Callout x:Name="callout1" AnchorPoint="0,1.25" CalloutStyle="Oval" Content="Tab1 Rocks" Foreground="{StaticResource BaseForeground-Sketch}" Fill="{StaticResource BaseBackground-Sketch}" FontSize="{StaticResource SizeDouble-Sketch}" FontFamily="{StaticResource FontFamily-Sketch}" ed:GeometryEffect.GeometryEffect="Sketch" HorizontalAlignment="Left" Height="100" Margin="0,84,0,0" Stroke="{StaticResource BaseBorder-Sketch}" StrokeThickness="2" VerticalAlignment="Top" Width="200" Opacity="1.0"/>
        <ed:Callout x:Name="callout2" AnchorPoint="0,1.25" CalloutStyle="Oval" Content="Tab2 Rocks" Foreground="{StaticResource BaseForeground-Sketch}" Fill="{StaticResource BaseBackground-Sketch}" FontSize="{StaticResource SizeDouble-Sketch}" FontFamily="{StaticResource FontFamily-Sketch}" ed:GeometryEffect.GeometryEffect="Sketch" HorizontalAlignment="Left" Height="100" Margin="200,84,0,0" Stroke="{StaticResource BaseBorder-Sketch}" StrokeThickness="2" VerticalAlignment="Top" Width="200" Opacity="0.1"/>       


    </Grid>
</UserControl>
4

2 回答 2

2

这是一个简单的触发器,您可以使用它来触发基于选项卡选择的操作。将此添加到您的项目中,编译并将行为触发器设置为此触发器类型的实例。该行为必须附加到 TabControl 本身。然后将触发器的 TabIndex 设置为要触发操作的索引。触发器侦听选项卡控件的选择更改事件并将其与您提供的 TabIndex 值匹配。

public class TabSelectedTrigger : TriggerBase<TabControl>
{
    public static readonly DependencyProperty TabIndexProperty = DependencyProperty.Register("TabIndex", typeof (int),
                                                                                             typeof (TabSelectedTrigger),
                                                                                             new PropertyMetadata(-1));
    public int TabIndex
    {
        get { return (int)this.GetValue(TabIndexProperty); }
        set { this.SetValue(TabIndexProperty, value); }
    }


    protected override void OnAttached()
    {
        base.OnAttached();

        this.AssociatedObject.SelectionChanged += AssociatedObject_SelectionChanged;
    }

    void AssociatedObject_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if(this.TabIndex == this.AssociatedObject.SelectedIndex)
        {
            this.InvokeActions(null);
        }
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        this.AssociatedObject.SelectionChanged -= AssociatedObject_SelectionChanged;
    }
}

示例用法:

<sdk:TabControl Margin="59,49,67,81">
        <i:Interaction.Triggers>
            <local:TabSelectedTrigger TabIndex="1">
                <ei:GoToStateAction StateName="VisualState1"/>
            </local:TabSelectedTrigger>
            <local:TabSelectedTrigger TabIndex="0">
                <ei:GoToStateAction StateName="VisualState"/>
            </local:TabSelectedTrigger>
        </i:Interaction.Triggers>
        <sdk:TabItem Header="TabItem">
            <Grid Background="#FFE5E5E5"/>
        </sdk:TabItem>
        <sdk:TabItem Header="TabItem">
            <Grid Background="#FFE5E5E5"/>
        </sdk:TabItem>
    </sdk:TabControl>
于 2011-02-10T14:51:11.530 回答
0

一些想法,但没有确定的:

  1. 可能需要告知 stateActions 视觉状态的位置(请注意,此代码周围应该有通常的 < />,但如果我包含这些,则代码根本不会显示)

    pi:ActivateStateAction TargetState="Tab2VisualState" TargetObject="{Binding ElementName=LayoutRoot}"
    
  2. 你可以尝试一个GoToStateAction(我知道这是混合方式而不是草图流,但它们非常相似)

  3. 尝试将 aControlStoryBoardAction作为触发器,为此您需要为故事板命名。

如果上述方法都不起作用,这可能有助于缩小问题范围,但从根本上讲,您的代码看起来不错。

于 2011-02-09T23:45:43.853 回答