WinRT 中的 DataTrigger?

18

我能在WinRT参考资料中找到EventTrigger,但是我找不到DataTrigger。我也无法在应用程序中使用它。

有人能确认在WinRT中确实缺失了DataTrigger吗?EventTrigger是WinRT中唯一可用的触发器吗?


http://msdn.microsoft.com/zh-cn/library/windows/apps/br211377(v=VS.85).aspx ...你想要在事件上触发而不是数据元素上触发,这难道是一件坏事吗?同时需要重申的是,这甚至还没有进入测试阶段... - jcolebrand
1
这不是好或坏的事情,我只是想确认一下,以免在这条路上再投入更多时间。顺便说一句,我的问题确实与你指向我的同一参考资料有关。为了改变视图状态,我使用DataTrigger或Blend行为,例如GoToStateAction,但目前似乎都不可用,我只是想确定是否必须寻找解决方法。 - Murven
Silverlight 中由于 ViewStateManager 的出现而被 DataTriggers 抛弃。看起来他们在 WinRT 中采取了同样的方法 - Michael Brown
2
这是一个有趣的决定,我不认为VisualStateManager以任何方式替代数据触发器,只是巧合的是,开发人员正在使用这些触发器来执行与VisualStateManager相关的操作。然而,在WPF 4中,我充分利用了VisualStateManager和数据触发器。 - Murven
5个回答

20

目前WinRT XAML不支持DataTrigger。

Mike Brown的补充说明

DataTrigger API已被VisualStateManager替换,Blend SDK为Silverlight提供了类似于Data Triggers的API。由于附加行为模式在WinRT中有效,因此可以实现相同的功能。


1
我喜欢权威的答案。 - jcolebrand
7
我认为这是一个很大的遗漏。在最终版本中是否有计划加入? - svick
请记住,WinRT是以Silverlight为起点设计的。(在BUILD上,揭示了WinRT API设计团队已经检查了提交到市场的Windows Phone 7应用程序的MSIL,以查看哪些类/方法在现实世界的应用程序中常用。)就像System.Data在Silverlight和WinRT中都缺失一样,触发器也是如此。也许这些WPF功能中的一些将进入**Windows 9**,但对于Windows 8来说似乎有点不太可能。 - Tao Yue
5
我仍然没有看出VisualStateManager如何代替数据触发器。它们提供不同的功能,并且可以一起使用。您是否有关于为什么认为VisualStateManager可以作为DataTrigger的替代品的更多细节? - Murven

3

1
这个项目似乎也不支持DataTrigger。 - Murven
1
@Murven:请考虑使用“PropertyChangedTrigger”。 - Illidan

2
我不知道何时发生了改变,但我有 DataTriggerBehaviorGoToStateAction,将它们结合在一起应该可以解决你的问题...
命名空间导入
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" 
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 
xmlns:Interactivity="using:Microsoft.Xaml.Interactivity" 
xmlns:Core="using:Microsoft.Xaml.Interactions.Core"

将ViewSateManager放置在根元素上

<VisualStateManager.VisualStateGroups>
    <VisualStateGroup x:Name="Common">
        <VisualStateGroup.Transitions>
            <VisualTransition GeneratedDuration="0" To="Online">
                <Storyboard>
                    <ColorAnimation Duration="0" To="Lime" Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)" Storyboard.TargetName="Name" />
                </Storyboard>
            </VisualTransition>
            <VisualTransition GeneratedDuration="0" To="Offline">
                <Storyboard>
                    <ColorAnimation Duration="0" To="Red" Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)" Storyboard.TargetName="Name" />
                </Storyboard>
            </VisualTransition>
        </VisualStateGroup.Transitions>
        <VisualState x:Name="Online" />
        <VisualState x:Name="Offline" />
    </VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Interactivity:Interaction.Behaviors>
    <Core:DataTriggerBehavior Binding="{Binding Active}" Value="True">
        <Core:GoToStateAction StateName="Online" />
    </Core:DataTriggerBehavior>
    <Core:DataTriggerBehavior Binding="{Binding Active}" Value="False">
        <Core:GoToStateAction StateName="Offline" />
    </Core:DataTriggerBehavior>
</Interactivity:Interaction.Behaviors>

请问您能否添加一些关于Microsoft.Xaml.Interactions.Core命名空间的参考资料,它包含在哪个程序集中,属于哪个产品?谢谢! - Murven
我已经找到了参考资料:Microsoft.Xaml.Interactions.Core命名空间位于Microsoft.Xaml.Interactions.dll程序集中,该程序集包含在Behaviors SDK(XAML)中,适用于Visual Studio 2013,这是Visual Studio 2013的Blend的一部分。 - Murven

0

我实现了一种备用解决方案,可能适用于您。步骤如下:

  1. 创建一个UserControl(可以从头开始或继承)以便您可以在控件中编写一些代码后端C#。
  2. 在代码后台中为要触发的数据绑定创建一个DependencyProperty。
  3. 使用DependencyProperty的PropertyChangedCallback方法来实现在代码中对控件进行操作所需的操作。
  4. 在XAML中将DependencyProperty绑定到要触发的数据上。

它不像DataTrigger那样干净,但也不会太糟糕,并且它运行良好(至少对我而言)。

XAML中的声明(DataContext已设置为视图模型对象):

<local:PlayButton IsPlaying="{Binding IsPlaying}"/>

触发故事板更改状态的示例DependencyProperty:

// Use this to implement storyboard changing in W8 since triggers are not supported
public static readonly DependencyProperty IsPlayingProperty = DependencyProperty.Register(
      "IsPlaying",
      typeof(bool),
      typeof(PlayButton),
      new PropertyMetadata(null,
          new PropertyChangedCallback(OnIsPlayingChanged)
      ));

private static void OnIsPlayingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    PlayButton pb = (PlayButton)d;
    bool isPlaying = (bool)e.NewValue;

    if (isPlaying == false)
        pb.GotoPlay.Begin();
    else
        pb.GotoPause.Begin();
}

public bool IsPlaying
{
    get { return (bool)GetValue(IsPlayingProperty); }
    set { SetValue(IsPlayingProperty, value); }
}

是的,我同意这是解决缺乏DataTriggers的好方法。令人遗憾的是,在被认为是Windows应用程序未来技术的平台中,一些运作良好、提供便利和完全支持Blend的功能被删除了。WPF在许多方面仍然比Silverlight和WinRT更好、更优越。 - Murven

-1

在Windows 8中,您可以使用VisualState代替object.Triggers。以下是代码:

<ControlTemplate TargetType="Button">
  <Grid>
    <VisualStateManager.VisualStateGroups>
      <VisualStateGroup x:Name="CommonStates">
        <VisualStateGroup.Transitions>
          <!--Take one half second to transition to the PointerOver state.-->
          <VisualTransition To="PointerOver" GeneratedDuration="0:0:0.5"/>
        </VisualStateGroup.Transitions>

        <VisualState x:Name="Normal" />

        <VisualState x:Name="PointerOver">
          <Storyboard>
            <ColorAnimation Storyboard.TargetName="ButtonBrush"
                            Storyboard.TargetProperty="Color" To="Red" />
          </Storyboard>
        </VisualState>
      </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>
    <Grid.Background>
      <SolidColorBrush x:Name="ButtonBrush" Color="Green"/>
    </Grid.Background>
  </Grid>
</ControlTemplate>

3
请解释一下你认为这个可以替代DataTriggers的原因,我在你的示例中没有看到任何让我能够创建绑定到视图模型数据并且该绑定的更改会导致UI更改的内容。 - Murven

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接