[英]Binding to view from viewModel in MVVM
I'm working on a stacklayout in a contentView binded to a ViewModel holding some API data.我正在处理绑定到包含一些 API 数据的 ViewModel 的 contentView 中的堆栈布局。 However, the stack appears two (2) times as the API returns just 2 items.
但是,堆栈出现两 (2) 次,因为 API 仅返回 2 个项目。 but the details are not displaying on the view.
但细节没有显示在视图上。 I've tried "this.bindingContext", and "BindingContext".
我试过“this.bindingContext”和“BindingContext”。 None is working.
没有一个在工作。
Here is my model...这是我的模型...
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;
namespace AstraPolarisApp.Models
{
// Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse);
public class AccountDetails
{
[JsonProperty("accountNumber")]
public string AccountNumber { get; set; }
[JsonProperty("accountName")]
public string AccountName { get; set; }
public string phoneNumber { get; set; }
public string email { get; set; }
[JsonProperty("accountType")]
public string AccountType { get; set; }
}
public class AcctUserDetails
{
public string userId { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
public string email { get; set; }
public string phoneNumber { get; set; }
}
public class LinkedBy
{
public string linkedById { get; set; }
public string name { get; set; }
public string email { get; set; }
}
public class MyAccount
{
public string linkerId { get; set; }
public AccountDetails accountDetails { get; set; }
public AcctUserDetails acctUserDetails { get; set; }
public LinkedBy linkedBy { get; set; }
public string requestTimestamp { get; set; }
}
public class Account
{
[JsonProperty("payload")]
public List<MyAccount> Accounts { get; set; }
}
}
here is my ViewModel...这是我的视图模型...
using AstraPolarisApp.Helpers;
using AstraPolarisApp.Models;
using AstraPolarisApp.ViewModel;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Net.Http;
using System.Text;
namespace AstraPolarisApp.ViewModels
{
public class AccountsViewModel : BaseVM
{
#region Properties
private bool isBusy { get; set; }
public bool IsBusy
{
get => isBusy;
set
{
isBusy = value;
OnPropertyChanged(nameof(IsBusy));
}
}
private ObservableCollection<MyAccount> accountsData;
public ObservableCollection<MyAccount> AccountsData
{
get => accountsData;
set
{
accountsData = value;
OnPropertyChanged(nameof(AccountsData));
}
}
#endregion
#region constructor
public AccountsViewModel()
{
LoadMyAccounts();
}
#endregion
#region Functions
private async void LoadMyAccounts()
{
IsBusy = true;
HttpClient client = new HttpClient();
var url = Constant.GetLinkedAccountsUrl;
var response = await client.GetAsync(url);
var json = await response.Content.ReadAsStringAsync();
Account userAccounts = JsonConvert.DeserializeObject<Account>(json);
var sorted = userAccounts.Accounts;
//getTrans = userTransactions
var allAccounts = new ObservableCollection<MyAccount>(sorted);
AccountsData = allAccounts;
IsBusy = false;
}
#endregion
}
}
And here is my view (Xaml)这是我的观点(Xaml)
<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:pv="clr-namespace:Xamarin.Forms.PancakeView;assembly=Xamarin.Forms.PancakeView"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
x:Class="AstraPolarisApp.Utils.OverlayView">
<ContentView.Content>
<StackLayout>
<StackLayout
x:Name="OverLayStack"
BindableLayout.ItemsSource="{Binding AccountsData}"
Orientation="Horizontal"
Spacing="10">
<BindableLayout.ItemTemplate>
<DataTemplate>
<StackLayout>
<Frame x:Name="OverStack" HasShadow="True" Margin="10,-40,10,10"
CornerRadius="5" Padding="10,0,0,10" BackgroundColor="#1B0E7A">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackLayout Grid.Row="0">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackLayout Orientation="Vertical" Margin="0,8,0,0" Grid.Column="0" HorizontalOptions="Start">
<Label Text="{Binding AccountType}" x:Name="AcctLbl" FontSize="13" TextColor="#E7E8F0"
HorizontalOptions="Start"/>
<Label Text="{Binding AccountNumber}" x:Name="AcctNo" TextColor="#E7E8F0" FontSize="8"
HorizontalOptions="Start"/>
</StackLayout>
<StackLayout Grid.Column="1" Margin="0,-10,0,0"
HorizontalOptions="End" VerticalOptions="Center">
<pv:PancakeView HasShadow="True" CornerRadius="0,0,5,0"
Opacity="0.75" HeightRequest="35"
HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<pv:PancakeView.BackgroundGradientStops>
<pv:GradientStopCollection>
<pv:GradientStop Color="#00FFFFFF" Offset="0"/>
<pv:GradientStop Color="#90D3CA9C" Offset="1"/>
</pv:GradientStopCollection>
</pv:PancakeView.BackgroundGradientStops>
<Label Text="Default" Margin="55,0,10,0" FontSize="Subtitle" HorizontalOptions="End" VerticalOptions="Center" TextColor="Accent"/>
</pv:PancakeView>
</StackLayout>
</Grid>
</StackLayout>
<StackLayout Grid.Row="1">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackLayout Grid.Column="0" Orientation="Vertical" HorizontalOptions="Start">
<Label Text="NGN 10,000.00" x:Name="AcctBal" TextColor="White"
FontSize="16" FontFamily="{StaticResource font_bold}" FontAttributes="Bold"/>
<Label Text="Available Balance" TextColor="White" FontSize="8"/>
</StackLayout>
<!--<pv:PancakeView Grid.Column="1" Margin="0,0,15,0" CornerRadius="5" HasShadow="False" HeightRequest="35" Padding="10,5,10,5"
HorizontalOptions="End" VerticalOptions="Center" BackgroundColor="{StaticResource PrimaryDark}" BorderIsDashed="True">
<ImageButton Grid.Column="1" BackgroundColor="Transparent" Source="tune.png"
WidthRequest="25" HeightRequest="25" Clicked="OnSettingBtn_Clicked" Aspect="AspectFit"/>
</pv:PancakeView>-->
</Grid>
</StackLayout>
</Grid>
</Frame>
</StackLayout>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
</StackLayout>
</ContentView.Content>
</ContentView>
here is my Xaml Code behind...这是我的 Xaml 代码后面...
using AstraPolarisApp.PopUps;
using AstraPolarisApp.ViewModels;
using Rg.Plugins.Popup.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace AstraPolarisApp.Utils
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class OverlayView : ContentView
{
public OverlayView()
{
InitializeComponent();
//BindingContext = new TransactionViewModel();
this.BindingContext = new AccountsViewModel();
}
}
}
AccountType
and AccountNumber
are properties of AccountDetails
, but you are binding to a collection of MyAccount
. AccountType
和AccountNumber
是AccountDetails
属性,但您绑定到MyAccount
的集合。
EDIT:编辑:
AccountDetails
is already a member of MyAccount
, so you just bind to it like anything else: AccountDetails
已经是一员MyAccount
,所以你只要给它绑定任何事情一样:
<Label Text="{Binding accountDetails.AccountType}"
x:Name="AcctLbl" FontSize="13" TextColor="#E7E8F0" HorizontalOptions="Start"/>
<Label Text="{Binding accountDetails.AccountNumber}"
x:Name="AcctNo" TextColor="#E7E8F0" FontSize="8" HorizontalOptions="Start"/>
ps.附:
accountDetails
should really start with a capital letter since it's a property. accountDetails
应该真正以大写字母开头,因为它是一个属性。 I appreciate it will clash with the class name, but you could just call it Details
or something, since it's already a member of a MyAccount, so you know it relates to accounts.我很欣赏它会与类名冲突,但您可以将其称为
Details
或其他名称,因为它已经是 MyAccount 的成员,因此您知道它与帐户有关。
Based on @GazTheDestroyer reply, i was able to find my answer.根据@GazTheDestroyer 的回复,我找到了答案。 So, after using the method he gave and realizing its not working for me, I decided to add 'path' to the binding.
因此,在使用他提供的方法并意识到它对我不起作用之后,我决定在绑定中添加“路径”。 here is the final copy...
这是最终副本...
<Label Text="{Binding Path=Details.AccountType}"
x:Name="AcctLbl" FontSize="13" TextColor="#E7E8F0" HorizontalOptions="Start"/>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.