Как динамически добавить элемент FlipView (текстовое содержимое) при смахивании? - PullRequest
0 голосов
/ 08 июня 2019

Я хочу динамически добавить новый элемент в режиме UWP.Так что я могу добавить бесконечные элементы в моем флип-вид.Например, чтобы получать горячие новости и показывать их одну за другой в режиме переворачивания.Я нахожу из Интернета похожий код и немного его модифицирую.Ниже приведен код xaml и код cs.Как вы можете видеть, я хочу использовать FlipView_SelectionChanged() для динамического добавления нового флип-представления, но не получилось.Я ожидаю, что добавлю новый флип-вид с текстовым содержимым, таким как 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" });
        }
    }
}

Ответы [ 2 ]

0 голосов
/ 10 июня 2019

Я изменил код, которым вы поделились. Я предлагаю вам использовать привязку данных вместо FlipView_SelectionChanged (), всякий раз, когда элемент, добавленный в ModelItems, обновляет элемент, с которым он связан. Я надеюсь, что это будет полезно.

<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>

Код логической части

//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 });
    }
}
0 голосов
/ 10 июня 2019

Здесь есть две вещи.Во-первых, вам не нужно назначать новый экземпляр всей модели вида для внесения изменений - вместо этого вы можете просто извлечь существующую модель вида и добавить новый элемент:

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

Тогда естьпроблема, когда событие прикреплено.Если вы прикрепите его прямо в конструкторе, он будет запущен немедленно, когда DataContext установлен в первый раз, и элементы добавляются в ObservableCollection - и попытка добавить элемент в этот момент заставит вас завершитьс катастрофической неудачей.Вместо этого вы должны прикрепить событие только после установки DataContext - поэтому удалите flipView.SelectionChanged += FlipView_SelectionChanged; из конструктора в OnNavigatedTo после , установив контекст данных:

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    grid.DataContext = new BaseViewModel();
    flipView.SelectionChanged += FlipView_SelectionChanged;
}

Таким образом, элементы будут правильно добавлены при изменении выбора.

...