【问题标题】:Xamarin, Label Text in xaml doesn't change on property changed WITH MVVM HelpersXamarin,xaml 中的标签文本不会随着 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; }
    }
}

【问题讨论】:

    标签: c# xaml xamarin android-databinding


    【解决方案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,我已经好几天没有收到你的消息了。如果有什么我可以帮助的,请告诉我。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-01
    • 2017-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多