簡體   English   中英

Xamarin表單MVVM UWP ListView綁定不起作用

[英]Xamarin Forms MVVM UWP ListView Binding doesn't work

我正在嘗試使用需要綁定到ViewModel中XML模型對象的已填充通用列表的ListView來實現MVVM ContentPage,但是綁定失敗。 顯示的代碼調用一個API,該API確實返回XML數據的有效列表。 當直接在XAML Xamarin內容頁面后面的代碼中進行綁定(通過在代碼后面設置ItemSource)時,相同的代碼可以正常工作。 如前所述,僅當嘗試通過分配給內容頁的ViewModel傳遞ListView時,才會發生此問題。 我已經逐步完成了ViewModel中的代碼,並且成功填充了ListView,但是綁定不起作用。 我在模型綁定確實適用的頁面上還有其他控件,但是唯一無效的控件是ListView。 代碼如下所示:

視圖模型:

 using RestDemo.Model; using RestDemo.Views; using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Text; using System.Threading.Tasks; using System.Xml.Linq; using Xamarin.Forms; using Xamarin.Forms.Xaml; using System.ComponentModel; using System.Windows.Input; using System.Collections.ObjectModel; namespace RestDemo.ViewModel { public class ViewModel : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; public ViewModel () { GetRequest(); } List<XmlPizzaDetails> _objPizzaList; string _selectedDescription = "Descriptions: "; bool _progress; string _cusButtonText = "Hello"; public bool Progress { get { return _progress; } set { _progress = value; } } public string CusButtonText { get { return _cusButtonText; } set { _cusButtonText = value; } } public string SelectedDescription { get { return _selectedDescription; } set { _selectedDescription = value; } } public List<XmlPizzaDetails> ObjPizzaList { get { return _objPizzaList; } set { if (_objPizzaList != value) { _objPizzaList = value; OnPropertyChanged("ObjPizzaList"); } } } public string Description { get { return _selectedDescription; } set { _selectedDescription = value; } } public ICommand SelectedCommand => new Command(() => { CusButtonText = "Goodby"; }); event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged { add { } remove { } } public async void GetRequest() { if (NetworkCheck.IsInternet()) { Uri geturi = new Uri("http://api.androidhive.info/pizza/?format=xml"); //replace your xml url HttpClient client = new HttpClient(); HttpResponseMessage responseGet = await client.GetAsync(geturi); string response = await responseGet.Content.ReadAsStringAsync(); //Xml Parsing ObjPizzaList = new List<XmlPizzaDetails>(); XDocument doc = XDocument.Parse(response); foreach (var item in doc.Descendants("item")) { XmlPizzaDetails ObjPizzaItem = new XmlPizzaDetails(); ObjPizzaItem.ID = item.Element("id").Value.ToString(); ObjPizzaItem.Name = item.Element("name").Value.ToString(); ObjPizzaItem.Cost = item.Element("cost").Value.ToString(); ObjPizzaItem.Description = item.Element("description").Value.ToString(); ObjPizzaList.Add(ObjPizzaItem); } Progress = false; } } protected virtual void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } } } 

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:xlocal="clr-namespace:RestDemo.ViewModel" xmlns:local="clr-namespace:RestDemo" xmlns:Views="clr-namespace:RestDemo.Views" x:Class="RestDemo.XmlParsingPageBehavior"> <ContentPage.BindingContext> <xlocal:ViewModel /> </ContentPage.BindingContext> <Grid> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Grid Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> <ColumnDefinition Width="*" /> <ColumnDefinition Width="*" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Views:CustomButton Grid.Row="0" Grid.Column="0" Text="HOME" /> <Views:CustomButton Grid.Row="0" Grid.Column="1" Text="Administrative Maintence" /> <Views:CustomButton Grid.Row="0" Grid.Column="2" Text="User Maintence" /> <Views:CustomButton Grid.Row="0" Grid.Column="3" Text="About" /> </Grid> <Grid Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" /> </Grid.ColumnDefinitions> <Views:CustomButton Grid.Row="0" Grid.Column="0" Text="{Binding CusButtonText, Mode=TwoWay}"> <Views:CustomButton.Behaviors> <local:ItemSelectedToCommandBehavior /> </Views:CustomButton.Behaviors> </Views:CustomButton> </Grid> <Frame Margin="5, 5, 5, 5" Grid.Row="2" Grid.Column="1" BackgroundColor = "Cyan"> <ListView x:Name="PizzaListView" ItemsSource="{Binding ObjPizzaList}" Margin="5, 0, 5, 0" Grid.Row="2" Grid.Column="1" HorizontalOptions="FillAndExpand" HasUnevenRows="True"> <ListView.ItemTemplate> <DataTemplate> <ViewCell> <Grid HorizontalOptions="FillAndExpand" Margin="0,0,0,0" Padding="20"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <Label Text="{Binding Name}" HorizontalOptions="StartAndExpand" Grid.Row="0" TextColor="Blue" FontAttributes="Bold"/> <Label Text="{Binding Cost}" HorizontalOptions="StartAndExpand" Grid.Row="1" TextColor="Orange" FontAttributes="Bold"/> <Label Text="{Binding Description}" HorizontalOptions="StartAndExpand" Grid.Row="2" TextColor="Gray" FontAttributes="Bold"/> <BoxView HeightRequest="2" Margin="0,10,10,0" BackgroundColor="Gray" Grid.Row="3" HorizontalOptions="Fill" /> </Grid> </ViewCell> </DataTemplate> </ListView.ItemTemplate> </ListView> </Frame> </Grid> <ActivityIndicator x:Name="ProgressLoader" IsVisible="{Binding Progress}" IsRunning="True"/> </Grid> </ContentPage> 

我有工作。 是的,ObservableCollections是可行的方法,但是通用列表也可以。 問題在於,當綁定模型時,WebService調用尚未完成,因此,當綁定列表屬性時,它仍然為null。 即使此時更新,ObservableCollection也將無法工作,因為它尚未被植入。 解決方案是在Page的OnAppearing事件上植入ObservableCollection或List,並在此事件中將ViewModel綁定為BindingContext。 我的解決方案如下:

 protected override async void OnAppearing() { var vm = new ViewModel.ViewModel(); if (vm == null) return; HttpClient client = new HttpClient(); HttpResponseMessage responseGet = await client.GetAsync(vm.Geturi); string response = await responseGet.Content.ReadAsStringAsync(); //Xml Parsing var _objPizzaList = new ObservableCollection<XmlPizzaDetails>(); XDocument doc = XDocument.Parse(response); vm.GetRequest(doc); this.BindingContext = vm; } 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM