2017-03-08 50 views
1

我在我的ListView ItemTemplate上添加ColorAnimationVisualStateManager时遇到问题。 VisualStateManager似乎没有改变它的视觉状态。UWP - ListView.ItemTemplate中的StateTrigger

我想在这里做的是开始一个StoryBoard将开始尽快顺利改变对ListViewItemRectangle.Fill颜色,作为其底层视图模型的的isReady属性值的变化。

我在做什么错?以及如何正确地做到这一点(最好没有无意义的UserControl)?

这里的XAML:

<Page 
    x:Class="App1.MainPage" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="using:App1" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d"> 

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> 
     <ListView ItemsSource="{x:Bind MyList}"> 
      <ListView.ItemTemplate> 
       <DataTemplate x:DataType="local:B"> 
        <UserControl> 
         <Grid> 
          <VisualStateManager.VisualStateGroups> 
           <VisualStateGroup x:Name="group"> 
            <VisualState x:Name="state1"> 
             <VisualState.StateTriggers> 
              <StateTrigger IsActive="{x:Bind IsReady, Mode=OneWay}"/> 
             </VisualState.StateTriggers> 
             <Storyboard> 
              <ColorAnimation Duration="0:0:1.8" To="Red" Storyboard.TargetProperty="(Rectangle.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="rect" /> 
             </Storyboard> 
            </VisualState> 
           </VisualStateGroup> 
          </VisualStateManager.VisualStateGroups> 
          <Rectangle x:Name="rect" Fill="Blue" Width="20" Height="20" /> 
         </Grid> 
        </UserControl> 
       </DataTemplate> 
      </ListView.ItemTemplate> 
     </ListView> 
     <Button Click="Button_Click">Test</Button> 
    </Grid> 
</Page> 

这里是后面的代码:

using System.Collections.ObjectModel; 
using System.ComponentModel; 
using System.Runtime.CompilerServices; 
using Windows.UI.Xaml; 
using Windows.UI.Xaml.Controls; 

namespace App1 
{ 
    public abstract class NotifyPropertyChangedBase : INotifyPropertyChanged 
    { 
     protected NotifyPropertyChangedBase() 
     { 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 

     protected virtual void RaisePropertyChanged([CallerMemberName]string propertyName = null) 
     { 
      this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

    public class B : NotifyPropertyChangedBase 
    { 
     private bool isReady; 
     public bool IsReady 
     { 
      get { return isReady; } 
      set { if (isReady != value) { isReady = value; RaisePropertyChanged(); } } 
     } 
    } 

    public sealed partial class MainPage : Page 
    { 
     public ObservableCollection<B> MyList { get; private set; } = new ObservableCollection<B>(); 

     public MainPage() 
     { 
      this.InitializeComponent(); 

      for (int i = 0; i < 10; i++) 
      { 
       MyList.Add(new B()); 
      } 
     } 

     private void Button_Click(object sender, RoutedEventArgs e) 
     { 
      MyList[2].IsReady = !MyList[2].IsReady; 
     } 
    } 
} 
+0

你的问题是什么?我用你的代码进行了测试,它在我身边效果很好。 –

+0

@ JayZuo-MSFT,没有使用'UserControl',我在MainPage.g.cs的Set_Windows_UI_Xaml_StateTrigger_IsActive中收到'NullReferenceException' – Vitaly

回答

0

这里,UserControl是必要的。没有它,我们可能会遇到你所看到的错误。为了管理视觉状态,我们需要一个Control子类,但是,Grid不是Control的子类,它继承自Panel

视觉状态有时是要改变UI的一些区域立即不是一个Control子类的状态情况下非常有用。您不能直接执行此操作,因为GoToState(Control, String, Boolean)方法的控件参数需要Control子类,该子类引用VisualStateManager所执行的对象。

我们建议您将自定义UserControl定义为Content根,或者是您想要将状态应用于其他内容的容器(例如Panel)。然后,您可以在UserControl上致电GoToState(Control, String, Boolean)并应用状态,而不管其余内容是否为Control

欲了解更多信息,请参阅视觉状态为不在控制VisualStateManager ClassRemarks下的元素。