Databound Flipview删除ViewModel.ItemAt(0)会导致翻转过渡

时间:2013-11-29 17:33:02

标签: c# windows-store-apps winrt-xaml flipview

我正在撰写文章阅读应用程序(类似于Bing新闻应用程序),我正在使用FlipView来介绍文章。 FlipView将其ItemsSource数据绑定设为保留文章内容的ObservableCollection<T>

由于内存和性能方面的原因,我只想在ObservableCollection<T>中保留3篇文章,因此我订阅flipView_SelectionChanged事件并删除Length - 1处的项目以便返回(到{右边)和0处的项目向前(向左)

我遇到的问题是,当我在使用触摸手势翻转后删除0处的项目时,动画会再次播放。

如何阻止过渡动画再次播放?

这是一个例子。创建一个新的空白商店应用程序,并添加以下内容:

public sealed partial class MainPage : Page
{
    public ObservableCollection<int> Items { get; set; }

    private Random _random = new Random(123);

    public MainPage()
    {
        this.InitializeComponent();

        Items = new ObservableCollection<int>();

        Items.Add(1);
        Items.Add(1);
        Items.Add(1);

        flipview.ItemsSource = Items;
    }

    private void flipview_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (this.flipview.SelectedIndex == 0)
        {
            Items.Insert(0, 1);
            Items.RemoveAt(Items.Count - 1);
        }
        else if (this.flipview.SelectedIndex == this.flipview.Items.Count - 1)
        {
            Items.Add(1);
            Items.RemoveAt(0);
        }
    }
}

这是在.xaml

<Page.Resources>
    <DataTemplate x:Key="DataTemplate">
        <Grid>
            <Grid.Background>
                <LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5">
                    <GradientStop Color="Black"/>
                    <GradientStop Color="White" Offset="1"/>
                </LinearGradientBrush>
            </Grid.Background>
        </Grid>
    </DataTemplate>
</Page.Resources>

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <FlipView x:Name="flipview"
        SelectionChanged="flipview_SelectionChanged"
        ItemsSource="{Binding}" ItemTemplate="{StaticResource DataTemplate}"/>
</Grid>

1 个答案:

答案 0 :(得分:4)

最简单的解决方案是使用UseTouchAnimationsForAllNavigation,以便视图模型中的项目操作不会导致动画发生。

<FlipView UseTouchAnimationsForAllNavigation="False" />

如果动画对您很重要,那么您只需在视图模型中绑定UseTouchAnimationsForAllNavigation的值,如下所示:

<FlipView UseTouchAnimationsForAllNavigation="{Binding ShowAnimations}" />

这有意义吗?如果你在视图模型中执行它(选项2),你可以在操作集合时简单地禁用它,然后重新启用它以便获得动画。

这是一个样本。

使用此代码:

public class MyColorModel : BindableBase
{
    Color _Color = default(Color);
    public Color Color { get { return _Color; } set { SetProperty(ref _Color, value); } }

    Visibility _Selected = Visibility.Collapsed;
    public Visibility Selected { get { return _Selected; } set { SetProperty(ref _Selected, value); } }

    public event EventHandler RemoveRequested;
    public void RemoveMe()
    {
        if (RemoveRequested != null)
            RemoveRequested(this, EventArgs.Empty);
    }

    public event EventHandler SelectRequested;
    public void SelectMe()
    {
        if (SelectRequested != null)
            SelectRequested(this, EventArgs.Empty);
    }
}

public class MyViewModel : BindableBase
{
    public MyViewModel()
    {
        this.Selected = this.Colors[1];
        foreach (var item in this.Colors)
        {
            item.RemoveRequested += (s, e) =>
            {
                this.ShowAnimations = false;
                this.Colors.Remove(s as MyColorModel);
                this.ShowAnimations = true;
            };
            item.SelectRequested += (s, e) => this.Selected = s as MyColorModel;
        }
    }

    ObservableCollection<MyColorModel> _Colors = new ObservableCollection<MyColorModel>(new[]
    {
      new MyColorModel{ Color=Windows.UI.Colors.Red }, 
      new MyColorModel{ Color=Windows.UI.Colors.Green }, 
      new MyColorModel{ Color=Windows.UI.Colors.Yellow }, 
      new MyColorModel{ Color=Windows.UI.Colors.Blue }, 
      new MyColorModel{ Color=Windows.UI.Colors.White }, 
      new MyColorModel{ Color=Windows.UI.Colors.Brown }, 
      new MyColorModel{ Color=Windows.UI.Colors.SteelBlue }, 
      new MyColorModel{ Color=Windows.UI.Colors.Goldenrod },
    });
    public ObservableCollection<MyColorModel> Colors { get { return _Colors; } }

    MyColorModel _Selected = default(MyColorModel);
    public MyColorModel Selected
    {
        get { return _Selected; }
        set
        {
            if (_Selected != null)
                _Selected.Selected = Visibility.Collapsed;
            value.Selected = Visibility.Visible;
            SetProperty(ref _Selected, value);
        }
    }

    bool _ShowAnimations = true;
    public bool ShowAnimations { get { return _ShowAnimations; } set { SetProperty(ref _ShowAnimations, value); } }
}

public abstract class BindableBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected void SetProperty<T>(ref T storage, T value, [System.Runtime.CompilerServices.CallerMemberName] String propertyName = null)
    {
        if (!object.Equals(storage, value))
        {
            storage = value;
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    protected void RaisePropertyChanged([System.Runtime.CompilerServices.CallerMemberName] String propertyName = null)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

试试这个XAML:

<Page.DataContext>
    <local:MyViewModel/>
</Page.DataContext>

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition Height="150" />
    </Grid.RowDefinitions>
    <FlipView ItemsSource="{Binding Colors}" SelectedItem="{Binding Selected, Mode=TwoWay}" UseTouchAnimationsForAllNavigation="{Binding ShowAnimations}">
        <FlipView.ItemTemplate>
            <DataTemplate>
                <Rectangle>
                    <Rectangle.Fill>
                        <SolidColorBrush Color="{Binding Color}" />
                    </Rectangle.Fill>
                </Rectangle>
            </DataTemplate>
        </FlipView.ItemTemplate>
    </FlipView>
    <ItemsControl ItemsSource="{Binding Colors}" Grid.Row="1" VerticalAlignment="Top" HorizontalAlignment="Center">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Horizontal" />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <Grid>
                        <Rectangle Height="100" Width="100" Margin="10">
                            <Rectangle.Fill>
                                <SolidColorBrush Color="{Binding Color}" />
                            </Rectangle.Fill>
                            <Interactivity:Interaction.Behaviors>
                                <Core:EventTriggerBehavior EventName="PointerPressed">
                                    <Core:CallMethodAction MethodName="SelectMe" TargetObject="{Binding}"/>
                                </Core:EventTriggerBehavior>
                            </Interactivity:Interaction.Behaviors>
                        </Rectangle>
                        <TextBlock Text="X" VerticalAlignment="Top" HorizontalAlignment="Right" FontSize="50" Margin="20,10" Foreground="Wheat">
                            <Interactivity:Interaction.Behaviors>
                                <Core:EventTriggerBehavior EventName="PointerPressed">
                                    <Core:CallMethodAction MethodName="RemoveMe" TargetObject="{Binding}"/>
                                </Core:EventTriggerBehavior>
                            </Interactivity:Interaction.Behaviors>
                        </TextBlock>
                    </Grid>
                    <Rectangle Height="10" Width="100" Margin="10" 
                               Fill="White" Visibility="{Binding Selected}" />
                </StackPanel>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Grid>

看起来像这样:

enter image description here

祝你好运!