大家晚上好
在这里,我尝试使用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>
我应该在模态控制器中放入什么以发送列表中的数据? 谢谢
答案 0 :(得分:0)
一个好的方法是使用一个Action并将其传递给模式页面的构造函数。像...
Public class ItemPage(Action<Someclass> callback)
该操作及其定义是在列表视图页面上下文中定义的。
然后,当您想从模式页面返回列表时,调用将要返回到列表的任何数据集传递给动作的操作,然后从该动作中弹出模式页面。
这意味着您是从列表页面上下文中弹出模式页面,而不是模式页面本身。
答案 1 :(得分:0)
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