Xamarin.Forms中CollectionView Footer绑定数据实现借贷列合计显示
你之前的实现失效主要有三个核心原因:
- XAML仅支持绑定公共属性,你定义的
total等都是字段,无法被识别 - Footer的绑定源设置错误,没有将合计对象单独绑定给Footer属性
- 没有实现
INotifyPropertyChanged接口,异步加载完合计数据后UI无法收到更新通知
具体修复步骤
1. 定义页脚数据模型
确保所有绑定字段都是公共属性:
public class AccountFooter { public string Total { get; set; } public decimal Totjvdebit { get; set; } public decimal Totjvcredit { get; set; } public decimal Totbalance { get; set; } }
2. 实现带通知的ViewModel
继承INotifyPropertyChanged,同时包含列表和页脚两个数据源:
using System.ComponentModel; using System.Runtime.CompilerServices; using System.Collections.ObjectModel; public class AccountViewModel : INotifyPropertyChanged { // 明细列表数据源,用ObservableCollection支持自动UI刷新 public ObservableCollection<accountdetails> AccountItems { get; set; } = new ObservableCollection<accountdetails>(); private AccountFooter _footerData; // 页脚合计数据源,变更时触发通知 public AccountFooter FooterData { get => _footerData; set { _footerData = value; OnPropertyChanged(); } } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
3. 修改XAML绑定配置
调整CollectionView的绑定,将Footer绑定到ViewModel的FooterData属性:
<!-- 把原来的CollectionView标签替换成下面的内容 --> <CollectionView x:Name="accountdetailslst" ItemsSource="{Binding AccountItems}" Footer="{Binding FooterData}"> <!-- 其余Header、ItemTemplate、FooterTemplate内容保持不变 --> </CollectionView>
4. 调整后台逻辑赋值
修改xaml.cs的代码,将加载后的数据赋值给ViewModel的对应属性:
public partial class account_details : ContentPage { AccountViewModel _viewModel; public account_details(string acc, string cur, string accname) { InitializeComponent(); _viewModel = new AccountViewModel(); BindingContext = _viewModel; // 保留原有图片资源初始化逻辑 imgAdd.Source = ImageSource.FromResource("isc_alphaApp.remove_ic.png"); imgfilter.Source = ImageSource.FromResource("isc_alphaApp.filter_ic.png"); imgshare.Source = ImageSource.FromResource("isc_alphaApp.share_icon.png"); loadData(acc,cur,accname); } async private void loadData(string account, string curr,string acc_name ) { acc_curlabel.Text = account + " - " + curr + " - " + acc_name; popupLoadingView.IsVisible = true; activityIndicator.IsRunning = true; HttpClient client = new HttpClient(); string url = "http://192.168.43.99/siteisc/api/values"; string uri = url + "/getaccountdetails"; try { HttpResponseMessage response = await client.GetAsync(uri); if (response.IsSuccessStatusCode) { string content = await response.Content.ReadAsStringAsync(); var listacc_details = JsonConvert.DeserializeObject<List<allaccountdetails>>(content); var list_filtered = listacc_details.FindAll(x => x.JvAccount == account && x.CurrencyCode == curr); decimal blnce_row = 0; List<String> l = new List<String>(); for (int i = 0; i < list_filtered.Count; i++) { blnce_row = decimal.Parse(list_filtered[i].JvDebit.ToString()) - decimal.Parse(list_filtered[i].Jvcredit.ToString()) + blnce_row; decimal rnd_blnce = Math.Round(blnce_row, 2); l.Add(rnd_blnce.ToString()); } List<accountdetails> listacc_collection = new List<accountdetails>(); for (int i = 0; i < list_filtered.Count; i++) { listacc_collection.Add(new accountdetails { desc = list_filtered[i].JvDescription, jvnbr = list_filtered[i].jvnbr.ToString(), jvcredit = list_filtered[i].Jvcredit.ToString(), jvdate = DateTime.Parse(list_filtered[i].JvDate).ToString(("dd-M-yyyy")), jvdebit = list_filtered[i].JvDebit.ToString(), jvref = list_filtered[i].jvref1, balance = l[i] }); } // 给ViewModel的明细列表赋值 _viewModel.AccountItems.Clear(); foreach (var item in listacc_collection) { _viewModel.AccountItems.Add(item); } // 计算合计并赋值给FooterData var totalDebit = listacc_collection.Sum(x => decimal.Parse(x.jvdebit)); var totalCredit = listacc_collection.Sum(x => decimal.Parse(x.jvcredit)); _viewModel.FooterData = new AccountFooter { Total = $"Total in {curr}", Totjvdebit = totalDebit, Totjvcredit = totalCredit, Totbalance = totalDebit - totalCredit }; popupLoadingView.IsVisible = false; activityIndicator.IsRunning = false; } else { await DisplayAlert("Operation Failed", "Response Failed!", "Cancel"); } } catch (System.Net.WebException exp) { await DisplayAlert("Connection Failed", "Please Check Your Internet Connection!", "Cancel"); } } }
额外注意事项
- 不要手动给
accountdetailslst.ItemsSource赋值,绑定已经关联了AccountItems属性 - 如果后续需要修改合计值,直接更新
FooterData属性即可,UI会自动刷新 - 可以在FooterTemplate里给数值添加格式化绑定,比如
Text="{Binding Totjvdebit, StringFormat='{0:F2}'}"统一显示两位小数
内容的提问来源于stack exchange,提问作者rana hd
相关产品推荐
相关产品推荐

