【UWP】FlipView綁定ItemsSource,Selectedindex的問題


最近在做列表頭部的Carousel展示,Carousel使用的是FlipView展示,另外使用ListBox顯示當前頁,如下圖

 

我們先設置一個綁定的數據源

    public class GlobalResource : INotifyPropertyChanged
    {
        private ObservableCollection<string> _items; 
        public ObservableCollection<string> Items
        {
            get
            {
                return _items = _items ?? new ObservableCollection<string>
                {
                    Guid.NewGuid().ToString(),
                    Guid.NewGuid().ToString(),
                    Guid.NewGuid().ToString(),
                    Guid.NewGuid().ToString(),
                };
            }
            set
            {
                _items = value;
                OnPropertyChanged(nameof(Items));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

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

Items作為數據源綁定在FlipView和ListBox上,布局代碼如下

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

    <Page.Resources>
        <local:GlobalResource x:Key="GlobalResource" />
        <Style x:Key="DotListBoxItemStyle" TargetType="ListBoxItem">
            <Setter Property="Background" Value="Transparent" />
            <Setter Property="TabNavigation" Value="Local" />
            <Setter Property="Padding" Value="12,11,12,13" />
            <Setter Property="HorizontalContentAlignment" Value="Left" />
            <Setter Property="Margin" Value="5" />
            <Setter Property="UseSystemFocusVisuals" Value="True" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ListBoxItem">
                        <Grid x:Name="LayoutRoot"
                              Background="{TemplateBinding Background}"
                              BorderThickness="{TemplateBinding BorderThickness}">
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="CommonStates">
                                    <VisualState x:Name="Normal" />
                                    <VisualState x:Name="Disabled" />
                                    <VisualState x:Name="PointerOver" />
                                    <VisualState x:Name="Pressed" />
                                    <VisualState x:Name="Selected">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="dotEllipse" Storyboard.TargetProperty="Fill">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="Blue" />
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="SelectedUnfocused">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="dotEllipse" Storyboard.TargetProperty="Fill">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="Blue" />
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="SelectedPointerOver">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="dotEllipse" Storyboard.TargetProperty="Fill">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="Blue" />
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="SelectedPressed">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="dotEllipse" Storyboard.TargetProperty="Fill">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="Blue" />
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>
                            <Ellipse x:Name="dotEllipse"
                                     Width="10"
                                     Height="10"
                                     Control.IsTemplateFocusTarget="True"
                                     Fill="White" />
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Page.Resources>

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <ListView>
            <ListView.Header>
                <Grid Height="200">
                    <FlipView x:Name="flipView" ItemsSource="{Binding Source={StaticResource GlobalResource}, Path=Items}">
                        <FlipView.ItemTemplate>
                            <DataTemplate>
                                <Rectangle Height="200"
                                           Margin="5,0"
                                           Fill="Red" />
                            </DataTemplate>
                        </FlipView.ItemTemplate>
                    </FlipView>

                    <ListBox x:Name="listBox"
                             Margin="0,0,0,8"
                             HorizontalAlignment="Center"
                             VerticalAlignment="Bottom"
                             Background="Transparent"
                             ItemContainerStyle="{StaticResource DotListBoxItemStyle}"
                             ItemsSource="{Binding Source={StaticResource GlobalResource},
                                                   Path=Items}"
                             SelectedIndex="{Binding ElementName=flipView,
                                                     Path=SelectedIndex,
                                                     Mode=TwoWay}">
                        <ListBox.ItemsPanel>
                            <ItemsPanelTemplate>
                                <StackPanel HorizontalAlignment="Center" Orientation="Horizontal" />
                            </ItemsPanelTemplate>
                        </ListBox.ItemsPanel>

                        <ListBox.ItemTemplate>
                            <DataTemplate>
                                <Ellipse Width="10"
                                         Height="10"
                                         Fill="White" />
                            </DataTemplate>
                        </ListBox.ItemTemplate>

                    </ListBox>
                </Grid>

            </ListView.Header>
            <Button Click="ButtonBase_OnClick">test</Button>
        </ListView>
    </Grid>
</Page>
MainPage.xaml

一切正常顯示

問題:

  下面我們需要修改數據源

    var globalResource = (GlobalResource) Resources["GlobalResource"]; globalResource.Items.Clear(); for (var i = 0; i < 10; i++) { globalResource.Items.Add(Guid.NewGuid().ToString()); } Debug.WriteLine("flipView.SelectedIndex = {0}", flipView.SelectedIndex); Debug.WriteLine("listBox.SelectedIndex = {0}", listBox.SelectedIndex);

  雖然數據源變了,但是並沒有選中當前頁(第一個點不為藍色),通過輸出信息發現SelectedIndex都是0,並沒有改變

  跟蹤發現,調用ObservableCollection.Clear方法的時候SelectedIndex都被設為了-1,Add第一個的時候SelectedIndex被置為0,數據源和相關數據都改變了,不知道為什么樣式沒有出發(VisualState)由於不知道ListView內部實現,我們無法得知具體原因是啥

解決:

  對於上面問題,可以通過下面方式解決

  重新改變SelectedIndex讓ListBox更新樣式

    var globalResource = (GlobalResource) Resources["GlobalResource"];
    globalResource.Items.Clear();
    for (var i = 0; i < 10; i++)
    {
        globalResource.Items.Add(Guid.NewGuid().ToString());
    }

    flipView.SelectedIndex = -1;
    flipView.SelectedIndex = 0;

 

Demo:

  http://files.cnblogs.com/files/bomo/CarouselDemo.zip

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM