Selected Card via Picker is not displaying data

huangapple go评论89阅读模式
英文:

Selected Card via Picker is not displaying data

问题

Here is the translated code:

  1. public partial class MenuPage : ContentPage, INotifyPropertyChanged
  2. {
  3. // Transactions
  4. private ObservableCollection<TransactionData> _transactions = new ObservableCollection<TransactionData>();
  5. public ObservableCollection<TransactionData> Transactions
  6. {
  7. get { return _transactions; }
  8. set
  9. {
  10. _transactions = value;
  11. OnPropertyChanged(nameof(Transactions));
  12. }
  13. }
  14. // Cards
  15. private ObservableCollection<CardData> _cards = new ObservableCollection<CardData>();
  16. public ObservableCollection<CardData> Cards
  17. {
  18. get { return _cards; }
  19. set
  20. {
  21. _cards = value;
  22. OnPropertyChanged(nameof(Cards));
  23. }
  24. }
  25. // Selected Card
  26. private CardData _selectedCard;
  27. public CardData SelectedCard
  28. {
  29. get { return _selectedCard; }
  30. set { _selectedCard = value; OnPropertyChanged(nameof(SelectedCard)); OnPropertyChanged(nameof(IsCardSelected)); }
  31. }
  32. public bool IsCardSelected
  33. {
  34. get { return SelectedCard != null; }
  35. }
  36. // Active Account
  37. public Account SelectedAccount { get; }
  38. // Account Balance
  39. public class AccountBalance
  40. {
  41. [JsonProperty("status")]
  42. public string status { get; set; }
  43. [JsonProperty("msg")]
  44. public string msg { get; set; }
  45. [JsonProperty("data")]
  46. public string data { get; set; }
  47. }
  48. public MenuPage(Account _selectedAccount)
  49. {
  50. InitializeComponent();
  51. Title = "Transactions";
  52. BindingContext = this;
  53. SelectedAccount = _selectedAccount;
  54. }
  55. // When the screen appears
  56. protected override async void OnAppearing()
  57. {
  58. base.OnAppearing();
  59. await GetTransactionsAsync();
  60. await GetBalanceAsync();
  61. await GetCardsAsync();
  62. }
  63. // Confirm you want to go back
  64. protected override bool OnBackButtonPressed()
  65. {
  66. MainThread.BeginInvokeOnMainThread(async () =>
  67. {
  68. var result = await this.DisplayAlert("Alert!", "Do you really want to choose another account?", "Yes", "No");
  69. if (result) await this.Navigation.PopAsync();
  70. });
  71. return true;
  72. }
  73. // Get Transactions from Account
  74. private async Task GetTransactionsAsync()
  75. {
  76. string iban = App.ActiveAccount.iban;
  77. string url = "https://example";
  78. HttpClient client = new HttpClient();
  79. HttpResponseMessage response = await client.GetAsync(url);
  80. if (response.IsSuccessStatusCode)
  81. {
  82. string json = await response.Content.ReadAsStringAsync();
  83. TransactionsResponse responseObj = Newtonsoft.Json.JsonConvert.DeserializeObject<TransactionsResponse>(json);
  84. Transactions = responseObj.data;
  85. }
  86. else
  87. {
  88. Debug.WriteLine("Error: Unable to get transactions data.");
  89. }
  90. }
  91. // Get Account Balance
  92. private async Task GetBalanceAsync()
  93. {
  94. string iban = App.ActiveAccount.iban;
  95. string url = "https://example";
  96. HttpClient client = new HttpClient();
  97. HttpResponseMessage response = await client.GetAsync(url);
  98. var responseString = await response.Content.ReadAsStringAsync();
  99. if (response.IsSuccessStatusCode)
  100. {
  101. string json = await response.Content.ReadAsStringAsync();
  102. JObject resultX = JObject.Parse(responseString);
  103. JObject data = (JObject)resultX["data"];
  104. string account_balance = (string)data["account_balance"];
  105. balanceLabel.Text = account_balance + "€";
  106. }
  107. else
  108. {
  109. Debug.WriteLine("Error: Unable to get balance data.");
  110. }
  111. }
  112. // Get Client Cards
  113. private async Task GetCardsAsync()
  114. {
  115. int id_client = App.ActiveAccount.id_client_account;
  116. string url = "https://example";
  117. HttpClient client = new HttpClient();
  118. HttpResponseMessage response = await client.GetAsync(url);
  119. if (response.IsSuccessStatusCode)
  120. {
  121. string json = await response.Content.ReadAsStringAsync();
  122. CardsResponse responseObj = Newtonsoft.Json.JsonConvert.DeserializeObject<CardsResponse>(json);
  123. Cards = responseObj.data;
  124. }
  125. else
  126. {
  127. Debug.WriteLine("Error: Unable to get Card data.");
  128. }
  129. }
  130. // More Transactions -> Updates
  131. public new event PropertyChangedEventHandler PropertyChanged;
  132. protected override void OnPropertyChanged(string propertyName)
  133. {
  134. base.OnPropertyChanged(propertyName);
  135. if (propertyName == "Transactions")
  136. {
  137. PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Transactions"));
  138. }
  139. else
  140. {
  141. PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
  142. }
  143. }
  144. public class TransactionsResponse
  145. {
  146. public ObservableCollection<TransactionData> data { get; set; }
  147. }
  148. public class CardsResponse
  149. {
  150. public ObservableCollection<CardData> data { get; set; }
  151. }
  152. private void GotoTransactionPage(object sender, EventArgs e)
  153. {
  154. Navigation.PushAsync(new MakeTransactionPage());
  155. }
  156. private void GotoLoanPage(object sender, EventArgs e)
  157. {
  158. Navigation.PushAsync(new LoansPage(SelectedAccount));
  159. }
  160. }

Please note that the code you provided contains HTML-encoded characters (e.g., &quot;), which should be replaced with their actual characters (e.g., "). The code I provided assumes that these HTML-encoded characters have been corrected.

英文:

What I'm trying to do:
API retrieves an array of cards. However, only 1 is displayed. The user chooses whichever card he wants to use via a Picker. After selecting a card, the card data is displayed (Card Number, Valid Month and Year, etc.)

What is happening:
Picker is getting populated with the data from the API. After selecting a card, no data is displayed.

Things that I have checked:
Feedback is that the code is fine. Visual Studio is not reporting any data binding errors. Debugging runs fine, no exceptions, no nothing. API is running and data is being retrieved.

MenuPage.xaml

  1. xmlns:x=&quot;http://schemas.microsoft.com/winfx/2009/xaml&quot;
  2. xmlns:local=&quot;clr-namespace:BankingApp&quot;
  3. xmlns:res=&quot;clr-namespace:BankingApp.Resources&quot;
  4. xmlns:toolkit=&quot;http://schemas.microsoft.com/dotnet/2022/maui/toolkit&quot;
  5. x:Class=&quot;BankingApp.MenuPage&quot;
  6. Title=&quot;MenuPage&quot;
  7. BackgroundColor=&quot;#041014&quot;
  8. Shell.NavBarIsVisible=&quot;False&quot; NavigationPage.HasBackButton=&quot;False&quot;&gt;
  9. &lt;ScrollView&gt;
  10. &lt;VerticalStackLayout&gt;
  11. &lt;Label HorizontalOptions=&quot;Center&quot; Margin=&quot;0,20,0,20&quot; Text=&quot;{x:Static res:LanguageResources.YourAccount}&quot; FontSize=&quot;32&quot;/&gt;
  12. &lt;!--Account Bank Card--&gt;
  13. &lt;Grid Margin=&quot;25,0,25,0&quot; &gt;
  14. &lt;!--&lt;Image Source=&quot;bankcardesb.svg&quot; Aspect=&quot;AspectFill&quot;/&gt;--&gt;
  15. &lt;StackLayout x:Name=&quot;selectedCardLayout&quot;
  16. IsVisible=&quot;{Binding IsCardSelected}&quot;&gt;
  17. &lt;Label Text=&quot;{Binding SelectedCard.card_number}&quot;
  18. FontAttributes=&quot;Bold&quot;/&gt;
  19. &lt;Label Text=&quot;{Binding SelectedCard.card_type}&quot; /&gt;
  20. &lt;Label Text=&quot;{Binding SelectedCard.valid_month}&quot;/&gt;
  21. &lt;/StackLayout&gt;
  22. &lt;Frame&gt;
  23. &lt;Label x:Name=&quot;balanceLabel&quot; FontSize=&quot;Medium&quot; /&gt;
  24. &lt;/Frame&gt;
  25. &lt;/Grid&gt;
  26. &lt;Picker x:Name=&quot;CardPicker&quot;
  27. Margin=&quot;0,0,20,20&quot;
  28. BackgroundColor=&quot;#5fb3f9&quot;
  29. HorizontalTextAlignment=&quot;Center&quot;
  30. HeightRequest=&quot;50&quot;
  31. WidthRequest=&quot;150&quot;
  32. HorizontalOptions=&quot;End&quot;
  33. SelectedItem=&quot;{Binding SelectedCard}&quot;
  34. ItemsSource=&quot;{Binding Cards}&quot;
  35. SelectedIndex=&quot;0&quot;
  36. ItemDisplayBinding=&quot;{Binding card_number}&quot; /&gt;
  37. &lt;Button HorizontalOptions=&quot;Center&quot; Margin=&quot;10&quot; WidthRequest=&quot;200&quot; HeightRequest=&quot;50&quot; BackgroundColor=&quot;#00B2FF&quot;
  38. Text=&quot;{x:Static res:LanguageResources.MakeTransaction}&quot; TextColor=&quot;White&quot; FontFamily=&quot;AgeoBold&quot; FontSize=&quot;18&quot; Clicked=&quot;GotoTransactionPage&quot;/&gt;
  39. &lt;Button HorizontalOptions=&quot;Center&quot; Margin=&quot;10&quot; WidthRequest=&quot;200&quot; HeightRequest=&quot;50&quot; BackgroundColor=&quot;#00B2FF&quot;
  40. Text=&quot;{x:Static res:LanguageResources.GoToLoans}&quot; TextColor=&quot;White&quot; FontFamily=&quot;AgeoBold&quot; FontSize=&quot;18&quot; Clicked=&quot;GotoLoanPage&quot;/&gt;
  41. &lt;!--TransactionList--&gt;
  42. &lt;StackLayout Margin=&quot;50,10,50,0&quot; VerticalOptions=&quot;EndAndExpand&quot; BindableLayout.ItemsSource=&quot;{Binding Transactions}&quot;&gt;
  43. &lt;BindableLayout.ItemTemplate&gt;
  44. &lt;DataTemplate&gt;
  45. &lt;toolkit:Expander BackgroundColor=&quot;#5fb3f9&quot; Margin=&quot;0,0,0,5&quot; Padding=&quot;10&quot;&gt;
  46. &lt;toolkit:Expander.Header&gt;
  47. &lt;StackLayout Orientation=&quot;Horizontal&quot;&gt;
  48. &lt;Label FontFamily=&quot;OpenSansSemibold&quot; Text=&quot;{Binding date_time}&quot; FontSize=&quot;Small&quot; HorizontalOptions=&quot;StartAndExpand&quot; /&gt;
  49. &lt;Label FontFamily=&quot;OpenSansSemibold&quot; Text=&quot;{Binding amount}&quot; FontSize=&quot;Small&quot; HorizontalOptions=&quot;End&quot; /&gt;
  50. &lt;Label FontFamily=&quot;OpenSansSemibold&quot; Text=&quot;{Binding currency}&quot; FontSize=&quot;Small&quot; HorizontalOptions=&quot;End&quot; /&gt;
  51. &lt;/StackLayout&gt;
  52. &lt;/toolkit:Expander.Header&gt;
  53. &lt;StackLayout IsVisible=&quot;{Binding IsExpanded}&quot;&gt;
  54. &lt;StackLayout Orientation=&quot;Horizontal&quot;&gt;
  55. &lt;Label FontFamily=&quot;AgeoBold&quot; Text=&quot;{x:Static res:LanguageResources.RecipientName} &quot; FontSize=&quot;Small&quot; /&gt;
  56. &lt;Label Text=&quot;{Binding name_recipient}&quot; FontSize=&quot;Small&quot; /&gt;
  57. &lt;/StackLayout&gt;
  58. &lt;StackLayout Orientation=&quot;Horizontal&quot; &gt;
  59. &lt;Label FontFamily=&quot;AgeoBold&quot; Text=&quot;{x:Static res:LanguageResources.IBANPayer}&quot; FontSize=&quot;Small&quot; /&gt;
  60. &lt;Label Text=&quot;{Binding iban_payer}&quot; FontSize=&quot;Small&quot; /&gt;
  61. &lt;/StackLayout&gt;
  62. &lt;StackLayout Orientation=&quot;Horizontal&quot; &gt;
  63. &lt;Label FontFamily=&quot;AgeoBold&quot; Text=&quot;{x:Static res:LanguageResources.IBANRecipient}&quot; FontSize=&quot;Small&quot; /&gt;
  64. &lt;Label Text=&quot;{Binding iban_recipient}&quot; FontSize=&quot;Small&quot; /&gt;
  65. &lt;/StackLayout&gt;
  66. &lt;StackLayout Orientation=&quot;Horizontal&quot;&gt;
  67. &lt;Label FontFamily=&quot;AgeoBold&quot; Text=&quot;{x:Static res:LanguageResources.PaymentDescription}&quot; FontSize=&quot;Small&quot; /&gt;
  68. &lt;Label Text=&quot;{Binding payment_description}&quot; FontSize=&quot;Small&quot; /&gt;
  69. &lt;/StackLayout&gt;
  70. &lt;StackLayout Orientation=&quot;Horizontal&quot; &gt;
  71. &lt;Label FontFamily=&quot;AgeoBold&quot; Text=&quot;{x:Static res:LanguageResources.ReferenceNumber}&quot; FontSize=&quot;Small&quot; /&gt;
  72. &lt;Label Text=&quot;{Binding reference_number}&quot; FontSize=&quot;Small&quot; /&gt;
  73. &lt;/StackLayout&gt;
  74. &lt;/StackLayout&gt;
  75. &lt;/toolkit:Expander&gt;
  76. &lt;/DataTemplate&gt;
  77. &lt;/BindableLayout.ItemTemplate&gt;
  78. &lt;/StackLayout&gt;
  79. &lt;/VerticalStackLayout&gt;
  80. &lt;/ScrollView&gt;
  81. &lt;/ContentPage&gt;

MenuPage.xaml.cs

  1. using System.Collections.Generic;
  2. using System.Diagnostics;
  3. using System.Net.Http;
  4. using BankingApp.Models;
  5. using Microsoft.Maui.Controls;
  6. using BankingApp.Services;
  7. using Microsoft.Maui.Controls.Xaml;
  8. using Newtonsoft.Json.Linq;
  9. using System.Collections.ObjectModel;
  10. using System.ComponentModel;
  11. using System.Xml;
  12. using BankingApp.Views;
  13. using Newtonsoft.Json;
  14. using System.Runtime.CompilerServices;
  15. namespace BankingApp
  16. {
  17. public partial class MenuPage : ContentPage, INotifyPropertyChanged
  18. {
  19. //Transactions
  20. private ObservableCollection&lt;TransactionData&gt; _transactions = new ObservableCollection&lt;TransactionData&gt;();
  21. public ObservableCollection&lt;TransactionData&gt; Transactions
  22. {
  23. get { return _transactions; }
  24. set
  25. {
  26. _transactions = value;
  27. OnPropertyChanged(nameof(Transactions));
  28. }
  29. }
  30. //Cards
  31. private ObservableCollection&lt;CardData&gt; _cards = new ObservableCollection&lt;CardData&gt;();
  32. public ObservableCollection&lt;CardData&gt; Cards
  33. {
  34. get { return _cards; }
  35. set
  36. {
  37. _cards = value;
  38. OnPropertyChanged(nameof(Cards));
  39. }
  40. }
  41. //Selected Card
  42. private CardData _selectedCard;
  43. public CardData SelectedCard
  44. {
  45. get { return _selectedCard; }
  46. set { _selectedCard = value; OnPropertyChanged(nameof(SelectedCard)); OnPropertyChanged(nameof(IsCardSelected)); }
  47. }
  48. public bool IsCardSelected
  49. {
  50. get { return SelectedCard != null; }
  51. }
  52. //Active Account
  53. public Account SelectedAccount { get; }
  54. //Account Balance
  55. public class AccountBalance
  56. {
  57. [JsonProperty(&quot;status&quot;)]
  58. public string status { get; set; }
  59. [JsonProperty(&quot;msg&quot;)]
  60. public string msg { get; set; }
  61. [JsonProperty(&quot;data&quot;)]
  62. public string data { get; set; }
  63. }
  64. public MenuPage(Account _selectedAccount)
  65. {
  66. InitializeComponent();
  67. Title = &quot;Transactions&quot;;
  68. BindingContext = this;
  69. SelectedAccount = _selectedAccount;
  70. }
  71. //When the screen appears
  72. protected override async void OnAppearing()
  73. {
  74. base.OnAppearing();
  75. await GetTransactionsAsync();
  76. await GetBalanceAsync();
  77. await GetCardsAsync();
  78. }
  79. //Confirm you want to go back
  80. protected override bool OnBackButtonPressed()
  81. {
  82. MainThread.BeginInvokeOnMainThread(async () =&gt; {
  83. var result = await this.DisplayAlert(&quot;Alert!&quot;, &quot;Do you really want to choose another account?&quot;, &quot;Yes&quot;, &quot;No&quot;);
  84. if (result) await this.Navigation.PopAsync();
  85. });
  86. return true;
  87. }
  88. //Get Transactions from Account
  89. private async Task GetTransactionsAsync()
  90. {
  91. string iban = App.ActiveAccount.iban;
  92. string url = $&quot;https://example&quot;;
  93. HttpClient client = new HttpClient();
  94. HttpResponseMessage response = await client.GetAsync(url);
  95. if (response.IsSuccessStatusCode)
  96. {
  97. string json = await response.Content.ReadAsStringAsync();
  98. TransactionsResponse responseObj = Newtonsoft.Json.JsonConvert.DeserializeObject&lt;TransactionsResponse&gt;(json);
  99. Transactions = responseObj.data;
  100. }
  101. else
  102. {
  103. Debug.WriteLine(&quot;Error: Unable to get transactions data.&quot;);
  104. }
  105. }
  106. //Get Account Balance
  107. private async Task GetBalanceAsync()
  108. {
  109. string iban = App.ActiveAccount.iban;
  110. string url = $&quot;https://example&quot;;
  111. HttpClient client = new HttpClient();
  112. HttpResponseMessage response = await client.GetAsync(url);
  113. var responseString = await response.Content.ReadAsStringAsync();
  114. if (response.IsSuccessStatusCode)
  115. {
  116. string json = await response.Content.ReadAsStringAsync();
  117. JObject resultX = JObject.Parse(responseString);
  118. JObject data = (JObject)resultX[&quot;data&quot;];
  119. string account_balance = (string)data[&quot;account_balance&quot;];
  120. balanceLabel.Text = account_balance + &quot;€&quot;;
  121. }
  122. else
  123. {
  124. Debug.WriteLine(&quot;Error: Unable to get balance data.&quot;);
  125. }
  126. }
  127. //Get Client Cards
  128. private async Task GetCardsAsync()
  129. {
  130. int id_client = App.ActiveAccount.id_client_account;
  131. string url = $&quot;https://example&quot;;
  132. HttpClient client = new HttpClient();
  133. HttpResponseMessage response = await client.GetAsync(url);
  134. if (response.IsSuccessStatusCode)
  135. {
  136. string json = await response.Content.ReadAsStringAsync();
  137. CardsResponse responseObj = Newtonsoft.Json.JsonConvert.DeserializeObject&lt;CardsResponse&gt;(json);
  138. Cards = responseObj.data;
  139. }
  140. else
  141. {
  142. Debug.WriteLine(&quot;Error: Unable to get Card data.&quot;);
  143. }
  144. }
  145. //More Transactions -&gt; Updates
  146. public new event PropertyChangedEventHandler PropertyChanged;
  147. protected override void OnPropertyChanged(string propertyName)
  148. {
  149. base.OnPropertyChanged(propertyName);
  150. if (propertyName == &quot;Transactions&quot;)
  151. {
  152. PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(&quot;Transactions&quot;));
  153. }
  154. else
  155. {
  156. PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
  157. }
  158. }
  159. public class TransactionsResponse
  160. {
  161. public ObservableCollection&lt;TransactionData&gt; data { get; set; }
  162. }
  163. public class CardsResponse
  164. {
  165. public ObservableCollection&lt;CardData&gt; data { get; set; }
  166. }
  167. private void GotoTransactionPage(object sender, EventArgs e)
  168. {
  169. Navigation.PushAsync(new MakeTransactionPage());
  170. }
  171. private void GotoLoanPage(object sender, EventArgs e)
  172. {
  173. Navigation.PushAsync(new LoansPage(SelectedAccount));
  174. }
  175. }
  176. }

GetCards.cs

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. namespace BankingApp.Services
  7. {
  8. public class CardData
  9. {
  10. [JsonProperty(&quot;id_client_account&quot;)]
  11. public string id_client_account { get; set; }
  12. [JsonProperty(&quot;card_number&quot;)]
  13. public string card_number { get; set; }
  14. [JsonProperty(&quot;valid_month&quot;)]
  15. public int valid_month { get; set; }
  16. [JsonProperty(&quot;valid_year&quot;)]
  17. public int valid_year { get; set; }
  18. [JsonProperty(&quot;card_type&quot;)]
  19. public string card_type { get; set; }
  20. }
  21. }

答案1

得分: 0

根据您提供的代码,Grid布局中,Frame包裹着StackLayout,所以您可能无法看到数据。您可以通过设置Grid布局中的RowDefinitionColumnDefinition来安排子元素,或者使用其他布局方式。

此外,目前Picker的SelectedIndex属性存在问题,您可以在代码中设置SelectedIndex,而不是在XAML中设置:

  1. public MainPage()
  2. {
  3. InitializeComponent();
  4. ...
  5. CardPicker.SelectedIndex = 0;
  6. }

更多信息,请参考Grid文档。希望对您有所帮助。

英文:
  1. &lt;Grid Margin=&quot;25,0,25,0&quot; &gt;
  2. &lt;StackLayout x:Name=&quot;selectedCardLayout&quot;&gt;
  3. &lt;Label Text=&quot;{Binding SelectedCard.card_number}&quot;&gt;
  4. ......
  5. &lt;/StackLayout&gt;
  6. &lt;Frame &gt;
  7. &lt;Label x:Name=&quot;balanceLabel&quot; FontSize=&quot;Medium&quot; /&gt;
  8. &lt;/Frame&gt;
  9. &lt;/Grid&gt;

According to your code above, in the Grid layout, the Frame shelters the StackLayout. So you cannot see the data. You could set the RowDefinition RowDefinition and ColumnDefinition to arrange the children in Grid layout or use other layout.

Also, there is an issue about SelectedIndex for Picker now : Picker SelectedIndex property not working. A workaround is to set SelectedIndex in the code behind instead of xaml:

  1. public MainPage()
  2. {
  3. InitializeComponent();
  4. ...
  5. CardPicker.SelectedIndex = 0;
  6. }

For more info, you could refer to Grid

Hope it works.

huangapple
  • 本文由 发表于 2023年5月8日 01:31:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/76195358.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定