繁体   English   中英

PopModalAsync将数据传递给父对象

[英]PopModalAsync pass data to parent

各位晚上好

在这里,我花了一段时间尝试使用Xamarin进行移动开发。 我设法创建一个包含数据的列表,并设法打开一个模态,该模态包含我用列表数据填充的字段。 我的问题是我想检索模式数据(我有输入)以更新列表。 但是我找不到如何将模态数据传递到列表中。 以下是我使用的不同元素。

我的清单检视

    <ContentPage.Content>
    <ListView x:Name="TableStock" RowHeight="40">
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <Grid Padding="5,0,5,0">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="5*"></ColumnDefinition>
                            <ColumnDefinition></ColumnDefinition>
                            <ColumnDefinition></ColumnDefinition>
                        </Grid.ColumnDefinitions>
                        <Label Grid.Column="0" Text="{Binding ProductLabel}" TextColor="Black" HorizontalTextAlignment="Start"/>
                        <Label Grid.Column="1"  Text="{Binding ProductUnit}" TextColor="Black" HorizontalTextAlignment="End"/>
                        <Label Grid.Column="2" Text="{Binding InitialStock}" FontAttributes="Bold" TextColor="Black" HorizontalTextAlignment="End" Margin="0,0,0,5"/>
                        <Entry Grid.Column="0" x:Name="NewRealStock" Text="{Binding NewStock}" IsVisible="False" />
                    </Grid>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</ContentPage.Content>

我列表中控制器的视图

public InputStock()
    {
        InitializeComponent();
        var listStock = Utils.Utils.GetStockByProduct();

        TableStock.ItemsSource = listStock;

        TableStock.ItemSelected += (sender, e) =>
        {
            if (TableStock.SelectedItem != null)
            {
                if (TableStock.SelectedItem is RealStock item)
                {
                    var productName = item.ProductLabel;
                    var stockProduit = item.InitialStock;
                    Navigation.PushModalAsync(new RealStockModal(productName, productStock, item.CodeProduct));
                }
                TableStock.SelectedItem = null;
            }
        };
    }

我的模态视图

    <ContentPage.Content>
    <StackLayout VerticalOptions="StartAndExpand">
        <Label HorizontalTextAlignment="Center" Margin="10,0" x:Name="productName"/>
        <Entry x:Name="PrCode" IsVisible="False"/>
        <Label HorizontalTextAlignment="Center" Margin="5,0" x:Name="newStock"/>
        <Entry HorizontalTextAlignment="Center" x:Name="realStock" Margin="25,0" Keyboard="Numeric"/>
        <Button Text="Enregistrer" VerticalOptions="End" Clicked="UpdateStock"/>
    </StackLayout>
</ContentPage.Content>

我应该在模态控制器中放置什么以发送列表中的数据? 谢谢

deanwilliammills要求提供一个示例,如下所示:(不使用数据库,仅使用模型类来存储项目,示例是显示将数据从模态显示的项目详细信息页面传递回模型视图的视图模型)。

这使用2种方式绑定,以便每当更改数据时,都会更新视图模型,而视图模型也会更新模型。 因此,当重新加载列表页面时,由于绑定,它已经具有新数据。

楷模:

Person.cs:

using System;
namespace MVVMListAndDetailExample.Models
{
    public class Person
    {
        static int nextId = 0;
        public Person()
        {
            Id = nextId++;
        }

        public int Id { get; private set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int Age { get; set; }
        public string City { get; set; }
        public string State { get; set; }

    }
}

People.cs(单例):

using System;
using System.Collections.Generic;

namespace MVVMListAndDetailExample.Models
{
    public class People
    {
        private static readonly object padlock = new object();

        static People instance = null;
        public static People Instance
        {
            get
            {
                lock (padlock)
                {
                    if (instance == null)
                    {
                        instance = new People();
                    }
                    return instance;
                }
            }
        }


        private People()
        {
            PeopleList = new List<Person>();
            PeopleList.Add(new Person
            {
                FirstName = "John",
                LastName = "Smith",
                Age = 25,
                City = "New York City",
                State = "NY"
            });
            PeopleList.Add(new Person
            {
                FirstName = "Frank",
                LastName = "Lee",
                Age = 35,
                City = "San Francisco",
                State = "CA"
            });
            PeopleList.Add(new Person
            {
                FirstName = "Jessie",
                LastName = "Lane",
                Age = 45,
                City = "Chicago",
                State = "IL"
            });
            PeopleList.Add(new Person
            {
                FirstName = "Susan",
                LastName = "Jones",
                Age = 55,
                City = "Seattle",
                State = "WA"
            });
            PeopleList.Add(new Person
            {
                FirstName = "Greg",
                LastName = "Franklin",
                Age = 65,
                City = "Atlanta",
                State = "GA"
            });
            PeopleList.Add(new Person
            {
                FirstName = "Howard",
                LastName = "Waters",
                Age = 75,
                City = "Tampa",
                State = "FL"
            });

        }

        public List<Person> PeopleList { get; private set; }

    }
}

查看模型:

BaseViewModel.cs:

using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace MVVMListAndDetailExample.ViewModels
{
    public class BaseViewModel : INotifyPropertyChanged
    {
        protected BaseViewModel()
        {
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
                handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

MainPageViewModel.cs:

using System;
using System.Collections.ObjectModel;

namespace MVVMListAndDetailExample.ViewModels
{
    public class MainPageViewModel : BaseViewModel
    {
        ObservableCollection<PersonViewModel> peopleList = new ObservableCollection<PersonViewModel>();
        public ObservableCollection<PersonViewModel> PeopleList
        {
            get { return peopleList; }
            set
            {
                if (peopleList != value)
                {
                    peopleList = value;
                    OnPropertyChanged();
                }
            }
        }

        public MainPageViewModel()
        {
            foreach(Models.Person person in Models.People.Instance.PeopleList)
            {
                peopleList.Add(new PersonViewModel(person));
            }
        }
    }
}

PersonViewModel.cs:

using System;
using System.Runtime.CompilerServices;

namespace MVVMListAndDetailExample.ViewModels
{
    public class PersonViewModel : BaseViewModel
    {
        public PersonViewModel(Models.Person person)
        {
            this.person = person;
            firstName = person.FirstName;
            lastName = person.LastName;
            age = person.Age;
            city = person.City;
            state = person.State;
        }

        Models.Person person;
        string firstName;
        string lastName;
        int age;
        string city;
        string state; 

        public string FirstName
        {
            get { return firstName; }
            set
            {
                if (firstName != value)
                {
                    firstName = value;
                    OnPropertyChanged();

                }
            }

        }
        public string LastName
        {
            get { return lastName; }
            set
            {
                if (lastName != value)
                {
                    lastName = value;
                    OnPropertyChanged();
                }
            }

        }
        public int Age
        {
            get { return age; }
            set
            {
                if (age != value)
                {
                    age = value;
                    OnPropertyChanged();
                }
            }

        }
        public string City
        {
            get { return city; }
            set
            {
                if (city != value)
                {
                    city = value;
                    OnPropertyChanged();
                }
            }

        }
        public string State
        {
            get { return state; }
            set
            {
                if (state != value)
                {
                    state = value;
                    OnPropertyChanged();
                }
            }

        }

        protected override void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            base.OnPropertyChanged(propertyName);
            Models.People.Instance.PeopleList[Models.People.Instance.PeopleList.FindIndex(ind=>ind.Equals(person))] = person;
        }
    }
}

浏览次数:

MainPage.xaml中:

<?xml version="1.0" encoding="utf-8"?>
<ContentPage 
   xmlns="http://xamarin.com/schemas/2014/forms" 
   xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
   xmlns:d="http://xamarin.com/schemas/2014/forms/design" 
   xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
   mc:Ignorable="d" 
   x:Class="MVVMListAndDetailExample.Views.MainPage"
   Title="Main Page"
   Padding="0,50,0,0">
   <ListView ItemsSource="{Binding PeopleList}" HasUnevenRows="true" ItemTapped="Handle_ItemTapped">
      <ListView.ItemTemplate>
         <DataTemplate>
            <ViewCell>
               <StackLayout Padding="10,10,10,10">
                  <Label Text="{Binding FirstName}" />
                  <Label Text="{Binding LastName}" />
                  <Label Text="{Binding Age}" />
                  <Label Text="{Binding City}" />
                  <Label Text="{Binding State}" />
               </StackLayout>
            </ViewCell>
         </DataTemplate>
      </ListView.ItemTemplate>
   </ListView>
</ContentPage>

MainPage.xaml.cs中:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;

namespace MVVMListAndDetailExample.Views
{
    // Learn more about making custom code visible in the Xamarin.Forms previewer
    // by visiting https://aka.ms/xamarinforms-previewer
    [DesignTimeVisible(false)]
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
            BindingContext = new ViewModels.MainPageViewModel();
        }

        async void Handle_ItemTapped(object sender, Xamarin.Forms.ItemTappedEventArgs e)
        {
            await Navigation.PushModalAsync(new Views.PersonDetailPage(e.Item as ViewModels.PersonViewModel));
        }
    }
}

PersonDetailPage.xaml:

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage 
   xmlns="http://xamarin.com/schemas/2014/forms" 
   xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
   x:Class="MVVMListAndDetailExample.Views.PersonDetailPage"
   Title="Person Detail Page"
   Padding="0,50,0,0">
   <ContentPage.Content>
      <StackLayout>
         <Entry Text="{Binding FirstName, Mode=TwoWay}" />
         <Entry Text="{Binding LastName, Mode=TwoWay}" />
         <Entry Text="{Binding Age, Mode=TwoWay}" />
         <Entry Text="{Binding City, Mode=TwoWay}" />
         <Entry Text="{Binding State, Mode=TwoWay}" />
         <Button Text="Save" Clicked="Handle_Clicked" />
      </StackLayout>
   </ContentPage.Content>
</ContentPage>

PersonDetailPage.xaml.cs:

using System;
using System.Collections.Generic;

using Xamarin.Forms;

namespace MVVMListAndDetailExample.Views
{
    public partial class PersonDetailPage : ContentPage
    {
        public PersonDetailPage(ViewModels.PersonViewModel personViewModel)
        {
            InitializeComponent();
            BindingContext = personViewModel;
        }

        async void Handle_Clicked(object sender, System.EventArgs e)
        {
            await Navigation.PopModalAsync();
        }
    }
}

完整的源代码在这里: https : //github.com/jgold6/XamarinSupportSamples/tree/master/MVVMListAndDetailExample

一个好的方法是使用一个Action并将其传递给模式页面的构造函数。 就像是 ...

Public class ItemPage(Action<Someclass> callback)

该动作及其定义是在listview页面上下文中定义的。

然后,当您想从模式页面返回列表时,调用将要返回的数据集返回列表的动作,然后从该动作中弹出模式页面。

这意味着您是从列表页面上下文中弹出模式页面,而不是模式页面本身。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM