这是我的ViewModel:
namespace DietAndFitness.ViewModels
{
public class FoodItemsViewModel
{
private SQLiteAsyncConnection database;
public static ObservableCollection<GlobalFoodItem> FoodItems { get; set; }
public FoodItemsViewModel(SQLiteAsyncConnection _database)
{
database = _database;
}
public async void LoadList()
{
FoodItems = new ObservableCollection<GlobalFoodItem>(await database.Table<GlobalFoodItem>().ToListAsync());
}
public void Add()
{
FoodItems.Add(new GlobalFoodItem("Item"));
}
}
}
我想将此VM的实例绑定到我的视图中的列表,但我无法让它正常工作。我唯一能够成功的是:
<?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:local="clr-namespace:DietAndFitness.ViewModels"
x:Class="DietAndFitness.Views.FoodDatabasePage">
<ContentPage.Content>
<StackLayout>
<ListView ItemsSource="{Binding FoodItems}" RowHeight="120">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ContentView Padding="5">
<Frame OutlineColor="Accent" Padding="10">
<StackLayout>
<Grid HorizontalOptions="Center">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Label Text="{Binding Name}" FontSize="22" VerticalOptions="CenterAndExpand" HorizontalOptions="Center" Grid.Row="0" Grid.Column="0"/>
<Label Text="{Binding Calories}" FontSize="22" VerticalOptions="CenterAndExpand" HorizontalOptions="Center" Grid.Row="0" Grid.Column="1"/>
</Grid>
<Grid HorizontalOptions="Center">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Label Text="Carbohydrates" Grid.Row="1" Grid.Column="0" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand" FontSize="16"/>
<Label Text="Proteins" Grid.Row="1" Grid.Column="1" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand" FontSize="16"/>
<Label Text="Fats" Grid.Row="1" Grid.Column="2" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand" FontSize="16"/>
<Label Text="{Binding Carbohydrates}" Grid.Row="2" Grid.Column="0" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand" FontSize="16"/>
<Label Text="{Binding Proteins}" Grid.Row="2" Grid.Column="1" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand" FontSize="16"/>
<Label Text="{Binding Fats}" Grid.Row="2" Grid.Column="2" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand" FontSize="16"/>
</Grid>
</StackLayout>
</Frame>
</ContentView>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Grid HorizontalOptions="Center">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Button x:Name="AddFoodItemButton" BackgroundColor="LightGray" HorizontalOptions="CenterAndExpand" Text="Add" Grid.Row="0" Grid.Column="0" Clicked="AddFoodItemButton_Clicked" />
<Button x:Name="EditFoodItemButton" BackgroundColor="LightGray" HorizontalOptions="CenterAndExpand" Text="Edit" Grid.Row="0" Grid.Column="1" />
<Button x:Name="DeleteFoodItemButton" BackgroundColor="LightGray" HorizontalOptions="CenterAndExpand" Text="Delete" Grid.Row="0" Grid.Column="2" />
</Grid>
</StackLayout>
</ContentPage.Content>
但这也存在问题:
如何将ListView绑定到此VM?是否可以在不使我的ObservableCollection静态的情况下这样做? 我在我的应用程序中使用了Master-Detail页面,如果它有任何区别(这是其中一个详细页面)。
编辑:这是我在构造函数中所做的。 SQLiteConnection.Database只是一个包含与数据库连接的静态类。
public FoodDatabasePage ()
{
FoodDatabase = new FoodItemsViewModel(SQLiteConnection.Database);
FoodDatabase.LoadList();
InitializeComponent ();
}
答案 0 :(得分:0)
你有一些事情。
当绑定ViewModel时,它通常与整个Page
相对应,使ViewModel成为BindingContext
,特别是在您拥有想要稍后访问的方法的情况下。
所以要做到这一点,你需要做一些改变。
您的网页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:local="clr-namespace:DietAndFitness.ViewModels"
x:Class="DietAndFitness.Views.FoodDatabasePage">
<ContentPage.Content>
<StackLayout>
<ListView ItemsSource="{Binding FoodItems}"
RowHeight="120">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Frame OutlineColor="Accent" Padding="15">
<StackLayout>
<Grid HorizontalOptions="Center">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Label Text="{Binding Name}"
FontSize="22"
VerticalOptions="CenterAndExpand"
HorizontalOptions="Center"
Grid.Row="0"
Grid.Column="0"/>
</Grid>
</StackLayout>
</Frame>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</StackLayout>
</ContentPage.Content>
</ContentPage>
检查我ListView
中是否更改了ItemSource
FoodItemsViewModel
作为集合名称。
此外,你的部分XAML消失了,所以我无法完成它。
您的代码在课程背后:(FoodDatabasePage.xaml.cs)
public FoodItemsViewModel FoodDatabase {get; set;}
public FoodDatabasePage ()
{
InitializeComponent ();
FoodDatabase = new FoodItemsViewModel(SQLiteConnection.Database);
BindingContext = FoodDatabase;
}
public override void OnAppearing()
{
FoodDatabase.LoadList();
}
这是“神奇”发生的地方。我们正在创建和存储FoodItemsViewModel
的对象,以便您可以在以后根据需要访问它,然后我们将最近创建的此对象设置为页面的BindingContext
(如上所述)。将ViewModel设置为Page
的BindingContext,后者将能够访问FoodItemsViewModel
的任何公共属性。
另外,您会注意到LoadList()
方法已从构造函数中删除,这是因为Page
构造函数中不应存在任何繁重的事务(实际上我们应该避免任何事务)。我们将其移动到OnAppearing
将要显示的Page
执行的namespace DietAndFitness.ViewModels
{
public class FoodItemsViewModel
{
private SQLiteAsyncConnection database;
//You don't need it static
public ObservableCollection<GlobalFoodItem> FoodItems { get; set; }
public FoodItemsViewModel(SQLiteAsyncConnection _database)
{
database = _database;
}
public async void LoadList()
{
// separated it only for readability.
var items = await database.Table<GlobalFoodItem>().ToListAsync();
FoodItems = new ObservableCollection<GlobalFoodItem>(items);
}
public void Add()
{
FoodItems.Add(new GlobalFoodItem("Item"));
}
}
}
回调方法。
注意:每次在屏幕上显示页面时都会调用此方法,因此如果您离开并返回,它将再次被调用。
您的ViewModel:
static
这几乎是一样的。唯一的变化是将FoodItems
限定符移除到INotifiedPropertyChanged
属性,因为它不再需要它了。
以上只是Mvvm和DataBinding的基础。还需要考虑其他一些事项,例如Command
,gw.cloud.config.json
和其他重要事项。
您可以找到有关此here
的更多信息希望这会有所帮助.-
PS:我无法检查您的所有代码是否有任何错误。