【问题标题】:UWP - StateTrigger in ListView.ItemTemplateUWP - ListView.ItemTemplate 中的 StateTrigger
【发布时间】:2017-03-08 21:59:11
【问题描述】:

在我的 ListView ItemTemplate 上将 ColorAnimation 添加到 VisualStateManager 时遇到问题。 VisualStateManager 似乎没有改变它的视觉状态。

我在这里要做的是启动一个StoryBoard,一旦其底层视图模型的 IsReady 属性值发生变化,它就会开始平滑地更改ListViewItem 上的Rectangle.Fill 颜色。

我做错了什么?以及如何正确地做到这一点(最好没有毫无意义的 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;
        }
    }
}

【问题讨论】:

  • 你的问题是什么?我用你的代码进行了测试,它在我这边运行良好。
  • @JayZuo-MSFT,不使用 UserControl,我在 MainPage.g.cs 中的 Set_Windows_UI_Xaml_StateTrigger_IsActive 中得到一个 NullReferenceException

标签: c# xaml uwp uwp-xaml visualstatemanager


【解决方案1】:

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

视觉状态有时对于您想要更改不是Control 子类的某些 UI 区域的状态的情况很有用。您不能直接这样做,因为GoToState(Control, String, Boolean) 方法的control 参数需要Control 子类,它引用VisualStateManager 所作用的对象。

我们建议您将自定义 UserControl 定义为 Content 根,或者作为您要对其应用状态的其他内容的容器(例如 Panel)。然后您可以在您的UserControl 上调用GoToState(Control, String, Boolean) 并应用状态,无论其余内容是否为Control

有关详细信息,请参阅RemarksVisualStateManager Class 下的非控件元素的视觉状态

【讨论】:

    猜你喜欢
    • 2011-09-18
    • 2017-08-24
    • 1970-01-01
    • 2015-08-22
    • 1970-01-01
    • 2021-07-25
    • 1970-01-01
    • 2021-08-30
    • 1970-01-01
    相关资源
    最近更新 更多