Search code examples
c#uwpflipview

How to dynamic add FlipView item (text content) when swipe?


I want to dynamically add new flip view item in UWP. So that I can add infinite items to my flip view. For example, to fetch hot news and show them one by one in flip view.

I find some similar code from Internet and modify it a little. Below is the xaml code and cs code behind. As you can see, I want to use FlipView_SelectionChanged() to dynamic add new flip view item but failed. I expect to add new flip view item with text content like Name new 3, Name new 4...

XAML:

<Grid Name="grid">
    <FlipView Name="flipView" ItemsSource="{Binding ModelItems}">
        <FlipView.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Vertical">
                    <TextBlock Text="{Binding Name}" FontSize="60" />
                </StackPanel>
            </DataTemplate>
        </FlipView.ItemTemplate>
    </FlipView>
</Grid>

C#:

public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();
        flipView.SelectionChanged += FlipView_SelectionChanged;
    }

    private void FlipView_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        Debug.WriteLine("flipview selection changed...index = " + flipView.SelectedIndex);

        BaseViewModel bv = new BaseViewModel();
        bv.ModelItems.Add(new BaseViewModelItem() { Name = "Name new " + flipView.SelectedIndex });

        //grid.DataContext = bv;

        Debug.WriteLine("flipview selection changed...count = " + bv.ModelItems.Count);
    }

    protected async override void OnNavigatedTo(NavigationEventArgs e)
    {
        grid.DataContext = new BaseViewModel();
    }

    public class BaseViewModelItem
    {
        public string Name { get; set; }
    }

    public class BaseViewModel
    {
        public ObservableCollection<BaseViewModelItem> ModelItems { get; set; }
        public BaseViewModel()
        {
            ModelItems = new ObservableCollection<BaseViewModelItem>();
            ModelItems.Add(new BaseViewModelItem() { Name = "Name 1" });
            ModelItems.Add(new BaseViewModelItem() { Name = "Name 2" });
            ModelItems.Add(new BaseViewModelItem() { Name = "Name 3" });
        }
    }
}

Solution

  • I have modified the code that you have shared. I suggest you to use data binding instead of FlipView_SelectionChanged(), whenever item added to the ModelItems it update the element which it is bounded. I hope this will be helpful.

    <Grid Name="grid">
        <Grid.RowDefinitions>
            <RowDefinition Height="20"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
    
        <Grid Grid.Row="0">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="250"/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <Button Grid.Column="0" Content="Add New FlipView Item" Click="Button_Click"/>
            <DockPanel Grid.Column="1">
                <TextBlock>Flipview Item Count : </TextBlock>
                <TextBlock Text="{Binding ModelItems.Count}"/>
            </DockPanel>
        </Grid>
    
        <FlipView Grid.Row="1" Name="flipView" ItemsSource="{Binding ModelItems,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}">
            <FlipView.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Vertical">
                        <DockPanel>
                            <TextBlock Text="Index:" FontSize="20"/>
                            <TextBlock Text="{Binding Index}" FontSize="60" />
                        </DockPanel>
                        <DockPanel>
                            <TextBlock Text="Name:" FontSize="20"/>
                            <TextBlock Text="{Binding Name}" FontSize="60" />
                        </DockPanel>
                    </StackPanel>
                </DataTemplate>
            </FlipView.ItemTemplate>
        </FlipView>
    </Grid>
    

    Logical Part code

    //Interaction logic for MainWindow.xaml
    public partial class MainWindow : Window
    {
        public BaseViewModel ViewModel { get; set; } = new BaseViewModel();
    
        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = ViewModel;
        }
    
        static int k = 3;
        private void Button_Click(object sender, RoutedEventArgs e) //can also implement using ICommand instead of event
        {
            this.ViewModel.ModelItems.Add(new BaseModelItem { Index = k, Name = "Name" + ++k });
        }
    }
    
    //--------Model------------
    public class NotifyPropertyChanged : System.ComponentModel.INotifyPropertyChanged
    {
        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyRaised(string propertyname)
        {
            PropertyChanged?.Invoke(this, new System.ComponentModel.PropertyChangedEventArgs(propertyname));
        }
    }
    
    public class BaseModelItem : NotifyPropertyChanged
    {
        string _name = string.Empty;
        public string Name
        {
            get { return _name; }
            set { _name = value; OnPropertyRaised("Name"); }
        }
    
        int _index = 0;
        public int Index
        {
            get { return _index; }
            set { _index = value; OnPropertyRaised("Index"); }
        }
    }
    
    //--------ViewModel------------
    public class BaseViewModel:NotifyPropertyChanged
    {
        System.Collections.ObjectModel.ObservableCollection<BaseModelItem> _modelItems = new System.Collections.ObjectModel.ObservableCollection<BaseModelItem>();
        public System.Collections.ObjectModel.ObservableCollection<BaseModelItem> ModelItems
        {
            get { return _modelItems; }
            set { _modelItems = value; OnPropertyRaised("ModelItems"); }
        }
    
        public BaseViewModel()
        {
            ModelItems = new System.Collections.ObjectModel.ObservableCollection<BaseModelItem>();
            ModelItems.Add(new BaseModelItem() { Name = "Name 1", Index = 0 });
            ModelItems.Add(new BaseModelItem() { Name = "Name 2", Index = 1 });
            ModelItems.Add(new BaseModelItem() { Name = "Name 3", Index = 2 });
        }
    }