使用 mvvm 在 xamarin 上绑定数据收集
Bind data collection on xamarin using mvvm
所以我开始学习 xamarin 并尝试从视图到模型的不同数据绑定方法。我正在使用 post 请求从服务中检索数据,在获取数据后我无法将它们绑定到视图。经过大量研究,我发现了一些有趣的解决方案,并尝试了不同的方法。
这是我到目前为止所取得的成就:
我的观点:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Ideas.Pages.IdeasSinglePage"
xmlns:vm="clr-namespace:Ideas.ViewModel;assembly=Ideas"
Title="My idea">
<ContentPage.BindingContext>
<vm:IdeasViewModel/>
</ContentPage.BindingContext>
<StackLayout>
<Button Command="{Binding GetIdeasCommand}"
Text="Bileta Ime"
TextColor="White"
FontSize="15"
BackgroundColor="#29abe2"/>
<Label Text="test"></Label>
<ListView ItemsSource="{Binding Ideas}"
HasUnevenRows="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Padding="20, 10">
<Label Text="{Binding IdeasName}"
FontSize="16"
TextColor="RoyalBlue"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
这是我的视图模型
public class IdeasViewModel : INotifyPropertyChanged
{
ApiServices _apiServices = new ApiServices();
public List<Ideas> Ideas
{
get { return Ideas; }
set
{
Ideas= value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
public ICommand GetIdeasCommand
{
get
{
return new Command(async () =>
{
Ideas= await _apiServices.GetIdeasAsync();
});
}
}
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
这是我的服务:
public async Task<List<Ideas>> GetIdeasAsync()
{
ListIdeasDetails ideas= null;
try {
var client = new HttpClient();
client.DefaultRequestHeaders.Add("parameter", "parameter");
client.DefaultRequestHeaders.Add("parameter", parameter);
HttpContent content = new StringContent("");
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var response = await client.PostAsync("https://heregoes/themethod", content);
response.EnsureSuccessStatusCode();
string json = await response.Content.ReadAsStringAsync();
ideas= JsonConvert.DeserializeObject<ListIdeasDetails>(json);
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message.ToString());
}
return ideas.Ideas;
}
}
这是我的两个模型:
public class Ideas
{
public string IdeasID { get; set; }
public string IdeasName { get; set; }
}
class ListIdeasDetails
{
public List<Ideas> Ideas{ get; set; }
public string ExceptionMessage { get; set; }
public bool HasException { get; set; }
}
非常感谢您的帮助!谢谢!!
似乎有问题
public List<Ideas> Ideas
{
get { return Ideas; }
set
{
Ideas= value; // Endless loop
OnPropertyChanged();
}
}
以这种方式添加支持字段:
List<Ideas> _ideas;
public List<Ideas> Ideas
{
get { return _ideas; }
set
{
if(value == _ideas) return;
_ideas = value;
OnPropertyChanged();
}
}
我建议使用 Fody.PropertyChanged 以减少与 INotifyPropertyChanged 相关的样板代码的数量。使用 Fody,您的 ViewModel 看起来就像:
public class IdeasViewModel : INotifyPropertyChanged
{
ApiServices _apiServices = new ApiServices();
public List<Ideas> Ideas { get;set; }
public event PropertyChangedEventHandler PropertyChanged;
public ICommand GetIdeasCommand
{
get
{
return new Command(async () =>
{
Ideas= await _apiServices.GetIdeasAsync();
});
}
}
}
P.S.: 除了你的主要问题,我想指出你的代码中接下来看起来不太好的地方。
- 使用POST从WEB下载数据。
- Class 姓名 'ApiServices'.
如果您需要进一步的帮助,可以通过评论告诉我。
所以我开始学习 xamarin 并尝试从视图到模型的不同数据绑定方法。我正在使用 post 请求从服务中检索数据,在获取数据后我无法将它们绑定到视图。经过大量研究,我发现了一些有趣的解决方案,并尝试了不同的方法。 这是我到目前为止所取得的成就: 我的观点:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Ideas.Pages.IdeasSinglePage"
xmlns:vm="clr-namespace:Ideas.ViewModel;assembly=Ideas"
Title="My idea">
<ContentPage.BindingContext>
<vm:IdeasViewModel/>
</ContentPage.BindingContext>
<StackLayout>
<Button Command="{Binding GetIdeasCommand}"
Text="Bileta Ime"
TextColor="White"
FontSize="15"
BackgroundColor="#29abe2"/>
<Label Text="test"></Label>
<ListView ItemsSource="{Binding Ideas}"
HasUnevenRows="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Padding="20, 10">
<Label Text="{Binding IdeasName}"
FontSize="16"
TextColor="RoyalBlue"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
这是我的视图模型
public class IdeasViewModel : INotifyPropertyChanged
{
ApiServices _apiServices = new ApiServices();
public List<Ideas> Ideas
{
get { return Ideas; }
set
{
Ideas= value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
public ICommand GetIdeasCommand
{
get
{
return new Command(async () =>
{
Ideas= await _apiServices.GetIdeasAsync();
});
}
}
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
这是我的服务:
public async Task<List<Ideas>> GetIdeasAsync()
{
ListIdeasDetails ideas= null;
try {
var client = new HttpClient();
client.DefaultRequestHeaders.Add("parameter", "parameter");
client.DefaultRequestHeaders.Add("parameter", parameter);
HttpContent content = new StringContent("");
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var response = await client.PostAsync("https://heregoes/themethod", content);
response.EnsureSuccessStatusCode();
string json = await response.Content.ReadAsStringAsync();
ideas= JsonConvert.DeserializeObject<ListIdeasDetails>(json);
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message.ToString());
}
return ideas.Ideas;
}
}
这是我的两个模型:
public class Ideas
{
public string IdeasID { get; set; }
public string IdeasName { get; set; }
}
class ListIdeasDetails
{
public List<Ideas> Ideas{ get; set; }
public string ExceptionMessage { get; set; }
public bool HasException { get; set; }
}
非常感谢您的帮助!谢谢!!
public List<Ideas> Ideas
{
get { return Ideas; }
set
{
Ideas= value; // Endless loop
OnPropertyChanged();
}
}
以这种方式添加支持字段:
List<Ideas> _ideas;
public List<Ideas> Ideas
{
get { return _ideas; }
set
{
if(value == _ideas) return;
_ideas = value;
OnPropertyChanged();
}
}
我建议使用 Fody.PropertyChanged 以减少与 INotifyPropertyChanged 相关的样板代码的数量。使用 Fody,您的 ViewModel 看起来就像:
public class IdeasViewModel : INotifyPropertyChanged
{
ApiServices _apiServices = new ApiServices();
public List<Ideas> Ideas { get;set; }
public event PropertyChangedEventHandler PropertyChanged;
public ICommand GetIdeasCommand
{
get
{
return new Command(async () =>
{
Ideas= await _apiServices.GetIdeasAsync();
});
}
}
}
P.S.: 除了你的主要问题,我想指出你的代码中接下来看起来不太好的地方。
- 使用POST从WEB下载数据。
- Class 姓名 'ApiServices'.
如果您需要进一步的帮助,可以通过评论告诉我。