Xamarin,xaml 中的标签文本不会随着 MVVM Helpers 的属性更改而更改
Posted
技术标签:
【中文标题】Xamarin,xaml 中的标签文本不会随着 MVVM Helpers 的属性更改而更改【英文标题】:Xamarin, Label Text in xaml doesn't change on property changed WITH MVVM Helpers 【发布时间】:2022-01-11 22:30:19 【问题描述】:在我的 Xaml 中,值仅在我进入 xaml 并执行以下操作时更新:
绑定使用.currentlevel->绑定使用.currentleve->绑定使用.currentlevel
但当use
变量在启动和从数据库中获取数据时更新时,我不知道为什么。
附:我在 xaml 文件中设置了 bindingcontext。
AboutPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
x:Class="INWORK.Views.AboutPage"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:control="clr-namespace:ProgressRingControl.Forms.Plugin;assembly=ProgressRing.Forms.Plugin"
xmlns:vm="clr-namespace:INWORK.ViewModels"
Title="Binding Title"
BackgroundImage="MainBackground.png">
<ContentPage.BindingContext>
<vm:AboutViewModel />
</ContentPage.BindingContext>
<ContentPage.Resources>
<ResourceDictionary>
<Color x:Key="Accent">#96d1ff</Color>
<Color x:Key="Muscular">#E76F51</Color>
<Color x:Key="Cardio">#429EA6</Color>
</ResourceDictionary>
</ContentPage.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="1*" />
<RowDefinition Height="3*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1.15*" />
</Grid.RowDefinitions>
<Ellipse
Grid.Row="1"
Fill="Gray"
HeightRequest="160"
HorizontalOptions="Center"
Stroke="#FFFF9900"
VerticalOptions="Center"
WidthRequest="160" />
<control:ProgressRing
Grid.Row="1"
HeightRequest="100"
Progress="Binding use.muscularprogress"
RingProgressColor="StaticResource Muscular"
RingThickness="20"
Scale="1"
WidthRequest="100"
class="pro" />
<control:ProgressRing
Grid.Row="1"
HeightRequest="100"
Progress="Binding use.cardioprogress"
RingProgressColor="StaticResource Cardio"
RingThickness="20"
Scale="0.85"
class="pro" />
<StackLayout Grid.Row="1" VerticalOptions="Center">
<StackLayout Orientation="Horizontal" HorizontalOptions="Center">
<Label
x:Name="Level"
FontAttributes="Bold"
FontSize="20"
HorizontalOptions="CenterAndExpand"
Text="Level "
TextColor="Black" />
<Label
FontAttributes="Bold"
FontSize="20"
HorizontalOptions="CenterAndExpand"
Text="Binding use.currentlevel"
TextColor="Black" />
<Button Command="Binding GoInfoCommand"></Button>
</StackLayout>
<Label
x:Name="Totalprocent"
FontAttributes="Bold"
FontSize="20"
HorizontalOptions="CenterAndExpand"
Text="0%"
TextColor="Black" />
</StackLayout>
<Grid Grid.Row="4">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<StackLayout Grid.Column="0">
<Label
Padding="2"
FontAttributes="Bold"
FontSize="20"
HorizontalOptions="Center"
Text="Muscular"
TextColor="StaticResource Muscular" />
<StackLayout HorizontalOptions="Center" Orientation="Horizontal">
<Label
FontAttributes="Bold"
FontSize="20"
Text="Binding use.muscularprogress"
TextColor="Black" />
<Label
FontAttributes="Bold"
FontSize="20"
Text="%"
TextColor="Black" />
</StackLayout>
</StackLayout>
<StackLayout Grid.Column="2">
<Label
x:Name="easier"
FontAttributes="Bold"
FontSize="20"
HorizontalOptions="Center"
Text="Cardio"
TextColor="StaticResource Cardio" />
<StackLayout HorizontalOptions="Center" Orientation="Horizontal">
<Label
FontAttributes="Bold"
FontSize="20"
Text="Binding use.cardioprogress"
TextColor="Black" />
<Label
FontAttributes="Bold"
FontSize="20"
Text="%"
TextColor="Black" />
</StackLayout>
</StackLayout>
</Grid>
</Grid>
</ContentPage>
LevelProgress.cs 模型
using SQLite;
using System;
using System.Collections.Generic;
using System.Text;
namespace INWORK.Models
public class LevelProgress
[PrimaryKey, AutoIncrement]
public int Id get; set;
public int currentlevel get; set;
public bool pushups;
public bool squats;
public bool pullups;
public bool splitsquats;
public bool stepups;
public bool tricepdips;
public bool legraises;
//Cardio section
public bool running;
public bool intervals;
public double muscularprogress get; set;
public double cardioprogress get; set;
服务用于访问本地数据库
using INWORK.Models;
using SQLite;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Essentials;
namespace INWORK.Services
internal class DataStorage
private static SQLiteAsyncConnection db;
private static async Task Init()
if (db != null)
return;
var databasePath = Path.Combine(FileSystem.AppDataDirectory, "test2.db");
db = new SQLiteAsyncConnection(databasePath);
await db.CreateTableAsync<LevelProgress>();
await db.CreateTableAsync<Overview>();
public static async Task FirstCreation()
await Init();
LevelProgress LevelProgress = new LevelProgress()
currentlevel = 1,
cardioprogress = 0,
muscularprogress = 0,
pushups = false,
squats = false,
pullups = false,
splitsquats = false,
stepups = false,
tricepdips = false,
legraises = false
;
await db.InsertAsync(LevelProgress);
public static async Task EditProgress(LevelProgress usehere)
await Init();
await db.UpdateAsync(new LevelProgress()
Id = 1,
currentlevel = usehere.currentlevel,
muscularprogress = usehere.muscularprogress,
pushups = usehere.pushups,
squats = usehere.squats,
pullups = usehere.pullups,
splitsquats = usehere.splitsquats,
stepups = usehere.stepups,
tricepdips = usehere.tricepdips,
legraises = usehere.legraises,
cardioprogress = usehere.cardioprogress,
running = usehere.running,
intervals = usehere.intervals
);
public static async Task FinishWorkout()
public static async Task<LevelProgress> GetProgress()
await Init();
var levelProgress = await db.Table<LevelProgress>().FirstOrDefaultAsync();
//var levelProgress = await db.Table<LevelProgress>().ToListAsync();
return levelProgress;
public static async Task AddWorkout(string _Workout_type, int _Result, DateTime _Date)
await Init();
Overview Overview = new Overview()
Workout_type = _Workout_type,
Result = _Result,
Date = _Date
;
await db.InsertAsync(Overview);
public static async Task<IEnumerable<Overview>> GetOverview(string type)
await Init();
IEnumerable<Overview> overview;
if (type == "Running" || type == "Intervals")
overview = await db.Table<Overview>().Where(v => v.Workout_type == "Running" || v.Workout_type == "Intervals").ToListAsync();
else
overview = await db.Table<Overview>().Where(v => v.Workout_type != "Running" || v.Workout_type != "Intervals").ToListAsync();
return overview;
关于ViewModel
using INWORK.Models;
using INWORK.Services;
using MvvmHelpers;
using System;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Essentials;
using Xamarin.Forms;
namespace INWORK.ViewModels
public class AboutViewModel : ViewModelBase
public ICommand GoInfoCommand get; set;
public AboutViewModel()
Title = "About";
OpenWebCommand = new Command(async () => await Browser.OpenAsync("https://aka.ms/xamarin-quickstart"));
//Command = "Binding OpenWebCommand
Task.Run(async () => await Loadup());
//use.currentlevel = use.currentlevel;
private LevelProgress pp;
private LevelProgress _use;
public LevelProgress use
get => _use;
set
_use = value;
OnPropertyChanged();
public async Task Loadup()
_use = new LevelProgress();
var temps = await DataStorage.GetProgress();
use = temps;
//await ProgressTracker.AddWorkout("Ŗunning",2, DateTime.Today);
if (use.currentlevel == 0)
await DataStorage.FirstCreation();
Loadup();
public ICommand OpenWebCommand get;
【问题讨论】:
【参考方案1】:是的,如果我们想在对象use
中更改字段(muscularprogress
,cardioprogress
)后更新UI,我们需要使类LevelProgress
实现接口INotifyPropertyChanged
。
既然你有基类ViewModelBase
,我们可以这样做:
public class LevelProgress: ViewModelBase
[PrimaryKey, AutoIncrement]
public int Id get; set;
public int currentlevel get; set;
public bool pushups;
public bool squats;
public bool pullups;
public bool splitsquats;
public bool stepups;
public bool tricepdips;
public bool legraises;
//Cardio section
public bool running;
public bool intervals;
//public double muscularprogress get; set;
private double _muscularprogress;
public double muscularprogress
get => _muscularprogress;
set SetProperty(ref _muscularprogress, value);
//public double cardioprogress get; set;
private double _cardioprogress;
public double cardioprogress
get => _cardioprogress;
set SetProperty(ref _cardioprogress, value);
注意:
作为测试,我为它创建了一个具有特殊值的假对象,并在开始时将其值分配为use
,之后我们更改它的值,UI可以自动刷新。
private void test(object obj)
use.muscularprogress = 98.8;
use.cardioprogress = 12.9;
【讨论】:
嗨@Emils Legzdins,我已经好几天没有收到你的消息了。如果有什么我可以帮助的,请告诉我。以上是关于Xamarin,xaml 中的标签文本不会随着 MVVM Helpers 的属性更改而更改的主要内容,如果未能解决你的问题,请参考以下文章
Xamarin iOS - XAML IsVisible 绑定在 ItemsSource 更改时不会更新