gpt4 book ai didi

xamarin - 1 属性未更新 Xamarin 表单绑定(bind)

转载 作者:行者123 更新时间:2023-12-03 10:25:18 24 4
gpt4 key购买 nike

一处房产 [ 总行程] 我在 Xamarin Forms 中的 ContentPage 上的标签绑定(bind)在屏幕上未更新。我去了属性 setter ,发现它是 'Notifying' 请参阅下面的 Console.WriteLine($"{TripTotal}") 语句它确实在启动时更新 OneTime。至 $99.0 这里有什么问题?

From Application output

TripTotal 100

TripTotal 101

TripTotal 102

TripTotal 103

TripTotal 104

TripTotal 105

TripTotal 106

TripTotal 107

TripTotal 108

TripTotal 109

TripTotal 110



<?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:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" x:Class="TripCalculator.Views.ExpensePage"
Title="{Binding Title}" x:Name="BrowseItemsPage">
<ContentPage.ToolbarItems>
<ToolbarItem Text="Add" Clicked="AddItem_Clicked" />
</ContentPage.ToolbarItems>
<StackLayout Padding="10">
<StackLayout Orientation="Horizontal" >
<Label Text="TripTotal:" FontSize="Title"/>
<Label Text="{Binding TripTotal, Mode=TwoWay, StringFormat ='${0:F2}'}" x:Name="trip_total" FontSize="Title" HorizontalOptions="End"/>
<Label Text="{Binding TripTotal_str, Mode=TwoWay}" FontSize="Title" HorizontalOptions="End"/>
</StackLayout>
<BoxView BackgroundColor="Black" HeightRequest="2" WidthRequest="500"/>
<ListView x:Name="ItemsListView"
ItemsSource="{Binding SubTotals}"
VerticalOptions="FillAndExpand"
HasUnevenRows="true"
RefreshCommand="{Binding LoadItemsCommand}"
IsPullToRefreshEnabled="true"
IsRefreshing="{Binding IsBusy, Mode=OneWay}"
CachingStrategy="RecycleElement"
ItemSelected="OnItemSelected">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Padding="10">
<Label Text="{Binding StudentName}"
LineBreakMode="NoWrap"
Style="{DynamicResource ListItemTextStyle}"
FontSize="Subtitle" />
<Label Text="{Binding Amount, StringFormat ='${0:F2}'}"
Style="{DynamicResource ListItemDetailTextStyle}"
FontSize="Subtitle" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>

enter image description here

这是 View 模型
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using TripCalculator.Models;
using Newtonsoft.Json;
using Xamarin.Forms;
using System.Windows.Input;
using TripCalculator.Helpers;
using TripCalculator.Views;

namespace TripCalculator.ViewModels
{
public class ExpenseVM : BaseVM
{
public ExpenseVM()
{
Title = "Students";
Expenses = new ObservableCollection<Expense>();
Messages = new ObservableCollection<string>();
SubTotals = new ObservableCollection<SubTotal>();
StudentTotals = new ObservableDictionary<string, double>();
Expenses.CollectionChanged += (s, e) => TripTotal += 1;
MessagingCenter.Subscribe<NewExpensePage, Expense>
(this, "AddItem", async (obj, item) =>
{
var newItem = item as Expense;

await DataSource.AddItemAsync(newItem);

await this.ExecuteLoadItemsCommand();
});

}

#region OBSERVABLES
public ICommand LoadItemsCommand
{
get
{
return new Command (async() => await ExecuteLoadItemsCommand());
}
}

public ICommand UpdateItemCommand
{
get
{
return new Command<object>(async (id) => await ExecuteUpdateItemCommand(id));
}
}

public Command DeleteCommand
{
get
{
return new Command (async () => await ExecuteDeleteCommand());
}
}

private Expense selectedItem;
public Expense SelectedItem { get => selectedItem;
set => SetProperty(ref selectedItem, value); }
private ObservableCollection<Expense> expenses;
public ObservableCollection<Expense> Expenses
{
get => expenses;
set => SetProperty(ref expenses, value);
}

private ObservableCollection<SubTotal> subtotals;
public ObservableCollection<SubTotal> SubTotals
{
get => subtotals;
set => SetProperty(ref subtotals, value);
}

public ObservableCollection<string> Students { get { return QueryDistinctNames(); } }

public ObservableCollection<string> Messages;

private ObservableDictionary<string, double> studentTotals;
public ObservableDictionary<string, double> StudentTotals
{
get => studentTotals;
internal set => SetProperty(ref studentTotals, value);
}

double tripTotal = 99;
public double TripTotal
{
get => tripTotal;
set => SetProperty(ref tripTotal, value);

}

public List<string> ExpenseIds { get { return queryAllExpenseIds(); } }

private void reQueryStudents()
{
var studList = Students;
foreach (string student in studList)
{
studentTotals[student] = QueryStudentTotal(student);
}
//set Notification cyccle
this.SubTotals.Clear();
foreach (var k in studentTotals.Keys)
{
subtotals.Add(new SubTotal { Amount = studentTotals[k], StudentName = k });

}
//TripTotal = QueryTotal();
SubTotals = subtotals;

StudentTotals = studentTotals;

}

public double QueryStudentTotal(string student)
{
return (from exp in Expenses select exp)
.Where(e => e.StudentName == student)
.Sum(e => e.Amount);
}

internal List<string> queryAllExpenseIds()
{
var lst = Expenses.ToList<Expense>();
// Left As Distinct() although there should be no redundant Id's
return lst.Select(x => x.Id).Distinct().ToList();
}

private double QueryTotal()
{
return (from exp in Expenses select exp).Sum(e => e.Amount);
}

private ObservableCollection<string> QueryDistinctNames()
{
var lst = Expenses.ToList<Expense>();
List<string> myStudents = lst.Select(x => x.StudentName).Distinct().ToList();
return myStudents.ToObservableCollection<string>();

}
#endregion

#region CMDS_AND_DATASTORE_OPS
async Task ExecuteLoadItemsCommand()
{
if (IsBusy)
return;

IsBusy = true;

try
{
Expenses.Clear();
if (DataSource != null)
{
var items = await DataSource.GetItemsAsync(true);
double sum = 0;
foreach (var item in items)
{
Expenses.Add(item);
sum += item.Amount;
}
reQueryStudents();
tripTotal = sum;
OnPropertyChanged(nameof(TripTotal));
}else
{ Console.WriteLine("null Data Store"); }
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
finally
{
IsBusy = false;
}
}

async Task ExecuteUpdateItemCommand(object newAmt)
{
if (IsBusy)
return;

IsBusy = true;
try
{
double newCost = (double)newAmt;

Expense newExpense = new Expense
{
Amount = newCost,
StudentName = SelectedItem.StudentName
};


var didUpdate = await DataSource.UpdateItemAsync(SelectedItem, newExpense);
if (didUpdate)
{
await ExecuteLoadItemsCommand();
}
}
catch
{

}
}

private async Task ExecuteDeleteCommand()
{
await DataSource.DeleteItemAsync(SelectedItem.Id);
await ExecuteLoadItemsCommand();
}
#endregion

#region UTIL
public override string ToString()
{
var serializedItem = JsonConvert.SerializeObject(Expenses);
return serializedItem;
}

public void FromString(string json)
{
// Hold your hat a bunch of conversions ahead :)
Expenses = JsonConvert.DeserializeObject<IEnumerable<Expense>>(json)
.ToList()
.ToObservableCollection<Expense>();

}
#endregion
}
}

这是 BaseViewModel
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;

using TripCalculator.Models;
using TripCalculator.Services;

namespace TripCalculator.ViewModels
{
public class BaseVM
{
protected static IDataSource<Expense> DataSource
{
get { return App.DataSource; }
}

bool isBusy = false;
public bool IsBusy
{
get { return isBusy; }
set { SetProperty(ref isBusy, value); }
}

string title = string.Empty;
public string Title
{
get { return title; }
set { SetProperty(ref title, value); }
}

#region INotifyPropertyChanged

protected bool SetProperty<T>(ref T backingStore, T value,
[CallerMemberName]string propertyName = "",
Action onChanged = null)
{
if (EqualityComparer<T>.Default.Equals(backingStore, value))
return false;

backingStore = value;
onChanged?.Invoke();
OnPropertyChanged(propertyName);
if (propertyName=="TripTotal")
{
Console.WriteLine($"TripTotal {value}");
}
return true;
}

public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
var changed = PropertyChanged;
if (changed == null)
return;

changed.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
}

最佳答案

在 ExecuteLoadItemsCommand() 你需要这样做 TripTotal = sum;而不是这个tripTotal = sum;

关于xamarin - 1 属性未更新 Xamarin 表单绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60814809/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com