WPF DataTrigger在未满足时不会恢复到之前的值

时间:2015-07-29 03:49:40

标签: wpf datatrigger

当WPF DataTrigger变换不满足时,DataTrigger已更改的属性值将恢复为先前的状态。我想知道是否有可能覆盖DataTrigger行为并阻止恢复?

在我的UI上,我有三个控件:A,B和C. C是一个TabControl。我正在寻找的行为是让控件A和B激活控件C中的选定选项卡:

  • 如果KeyboardFocus在控件A内,请将SelectedIndex设置为0 C;
  • 如果KeyboardFocus在控件B内,则在C上将SelectedIndex设置为1;
  • 但是如果KeyboardFocus不在A或B之内,我想要 SelectedIndex保持不变。这很重要,因为用户可以 也可以手动单击控件C上的选项卡。

修改 我最终尝试了这个:

<TabControl>
  <TabControl.Style>
    <Style TargetType="TabControl">
      <Style.Triggers>
        <DataTrigger 
         Binding="{Binding IsKeyboardFocusWithin, ElementName=MyControl1}" 
         Value="True">
          <DataTrigger.EnterActions>
            <BeginStoryboard>
              <Storyboard>
                <Int32AnimationUsingKeyFrames Storyboard.TargetProperty="SelectedIndex" Duration="0">
                  <DiscreteInt32KeyFrame KeyTime="0" Value="1"/>
                </Int32AnimationUsingKeyFrames>
              </Storyboard>
            </BeginStoryboard>
          </DataTrigger.EnterActions>  

        </DataTrigger>

   <DataTrigger 
        Binding="{Binding IsKeyboardFocusWithin, ElementName=MyControl2}" 
        Value="True">

          <DataTrigger.EnterActions>
            <BeginStoryboard>
              <Storyboard>
                <Int32AnimationUsingKeyFrames Storyboard.TargetProperty="SelectedIndex" Duration="0">
                  <DiscreteInt32KeyFrame KeyTime="0" Value="1"/>
                </Int32AnimationUsingKeyFrames>
              </Storyboard>
            </BeginStoryboard>
          </DataTrigger.EnterActions>

        </DataTrigger>                      
      </Style.Triggers>
    </Style>
  </TabControl.Style>
  <TabItem Header="Tab1">...<TabItem>
  <TabItem Header="Tab2">...<TabItem>
</TabControl>

这就是我用这种方法面临的问题:

  1. 看起来每个StoryBoard只能触发一次:我可以单击MyControl1激活Tab1,然后单击MyControl2激活Tab2,但是如果我再次单击任何MyControls,则没有任何反应
  2. 触发任何StoryBoard后,我无法手动切换标签。我有一个例外:

    System.InvalidCastException:指定的强制转换无效。  在System.Windows.Controls.Primitives.Selector.get_SelectedIndex()  在System.Windows.Controls.TabControl.UpdateSelectedContent()  在System.Windows.Controls.TabControl.OnSelectionChanged(SelectionChangedEventArgs e)

1 个答案:

答案 0 :(得分:0)

答案是EventTriggers

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <TextBox Name="txtA" Text="Control: A" Grid.Row="0"/>
        <TextBox Name="txtB" Text="Control: B" Grid.Row="1"/>
        <TabControl Name="tbC" Grid.Row="2">
            <TabItem Header="1st" Name="ti1"/>
            <TabItem Header="2nd" Name="ti2"/>
            <TabItem Header="3rd" Name="ti3"/>
        </TabControl>
        <Grid.Triggers>
            <EventTrigger RoutedEvent="TextBox.GotKeyboardFocus" SourceName="txtA">
                <BeginStoryboard Name="Select1">
                    <Storyboard >
                        <BooleanAnimationUsingKeyFrames
                    Storyboard.TargetName="ti1"
                    Storyboard.TargetProperty="(TabItem.IsSelected)">
                            <DiscreteBooleanKeyFrame
                        KeyTime="00:00:00"
                        Value="True" />
                        </BooleanAnimationUsingKeyFrames>
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>
            <EventTrigger RoutedEvent="TextBox.GotKeyboardFocus" SourceName="txtB">
                <BeginStoryboard Name="Select2">
                    <Storyboard >
                        <BooleanAnimationUsingKeyFrames
                    Storyboard.TargetName="ti2"
                    Storyboard.TargetProperty="(TabItem.IsSelected)">
                            <DiscreteBooleanKeyFrame
                        KeyTime="00:00:00"
                        Value="True" />
                        </BooleanAnimationUsingKeyFrames>
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>
        </Grid.Triggers>
    </Grid>

根据MSDN

  

触发器对象根据特定状态应用更改或操作   属性,而EventTrigger对象在a时启动一组Actions   发生指定的路由事件。因此不像Trigger,   EventTrigger没有终止状态的概念,所以动作   一旦提出事件的条件为否,将不会撤消   更长的时间。