#c# #xaml #xamarin #android-databinding
#c# #xaml #xamarin #android-привязка данных
Вопрос:
В моем Xaml значения обновляются только тогда, когда я захожу в xaml и делаю это, например:
{Использование привязки.текущий уровень}-gt;{Использование привязки.текущий уровень}-gt;gt;{Использование привязки.текущий уровень}
но не тогда, когда use
переменная обновляется при запуске и извлечении данных из базы данных, я не могу понять, почему.
P.S. я установил bindingcontext в файле xaml.
О странице.xaml
lt;?xml version="1.0" encoding="utf-8" ?gt; lt;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"gt; lt;ContentPage.BindingContextgt; lt;vm:AboutViewModel /gt; lt;/ContentPage.BindingContextgt; lt;ContentPage.Resourcesgt; lt;ResourceDictionarygt; lt;Color x:Key="Accent"gt;#96d1fflt;/Colorgt; lt;Color x:Key="Muscular"gt;#E76F51lt;/Colorgt; lt;Color x:Key="Cardio"gt;#429EA6lt;/Colorgt; lt;/ResourceDictionarygt; lt;/ContentPage.Resourcesgt; lt;Gridgt; lt;Grid.RowDefinitionsgt; lt;RowDefinition Height="1*" /gt; lt;RowDefinition Height="3*" /gt; lt;RowDefinition Height="1*" /gt; lt;RowDefinition Height="1*" /gt; lt;RowDefinition Height="1.15*" /gt; lt;/Grid.RowDefinitionsgt; lt;Ellipse Grid.Row="1" Fill="Gray" HeightRequest="160" HorizontalOptions="Center" Stroke="#FFFF9900" VerticalOptions="Center" WidthRequest="160" /gt; lt;control:ProgressRing Grid.Row="1" HeightRequest="100" Progress="{Binding use.muscularprogress}" RingProgressColor="{StaticResource Muscular}" RingThickness="20" Scale="1" WidthRequest="100" class="pro" /gt; lt;control:ProgressRing Grid.Row="1" HeightRequest="100" Progress="{Binding use.cardioprogress}" RingProgressColor="{StaticResource Cardio}" RingThickness="20" Scale="0.85" class="pro" /gt; lt;StackLayout Grid.Row="1" VerticalOptions="Center"gt; lt;StackLayout Orientation="Horizontal" HorizontalOptions="Center"gt; lt;Label x:Name="Level" FontAttributes="Bold" FontSize="20" HorizontalOptions="CenterAndExpand" Text="Level " TextColor="Black" /gt; lt;Label FontAttributes="Bold" FontSize="20" HorizontalOptions="CenterAndExpand" Text="{Binding use.currentlevel}" TextColor="Black" /gt; lt;Button Command="{Binding GoInfoCommand}"gt;lt;/Buttongt; lt;/StackLayoutgt; lt;Label x:Name="Totalprocent" FontAttributes="Bold" FontSize="20" HorizontalOptions="CenterAndExpand" Text="0%" TextColor="Black" /gt; lt;/StackLayoutgt; lt;Grid Grid.Row="4"gt; lt;Grid.ColumnDefinitionsgt; lt;ColumnDefinition Width="1*" /gt; lt;ColumnDefinition Width="1*" /gt; lt;ColumnDefinition Width="1*" /gt; lt;/Grid.ColumnDefinitionsgt; lt;StackLayout Grid.Column="0"gt; lt;Label Padding="2" FontAttributes="Bold" FontSize="20" HorizontalOptions="Center" Text="Muscular" TextColor="{StaticResource Muscular}" /gt; lt;StackLayout HorizontalOptions="Center" Orientation="Horizontal"gt; lt;Label FontAttributes="Bold" FontSize="20" Text="{Binding use.muscularprogress}" TextColor="Black" /gt; lt;Label FontAttributes="Bold" FontSize="20" Text="%" TextColor="Black" /gt; lt;/StackLayoutgt; lt;/StackLayoutgt; lt;StackLayout Grid.Column="2"gt; lt;Label x:Name="easier" FontAttributes="Bold" FontSize="20" HorizontalOptions="Center" Text="Cardio" TextColor="{StaticResource Cardio}" /gt; lt;StackLayout HorizontalOptions="Center" Orientation="Horizontal"gt; lt;Label FontAttributes="Bold" FontSize="20" Text="{Binding use.cardioprogress}" TextColor="Black" /gt; lt;Label FontAttributes="Bold" FontSize="20" Text="%" TextColor="Black" /gt; lt;/StackLayoutgt; lt;/StackLayoutgt; lt;/Gridgt; lt;/Gridgt; lt;/ContentPagegt;
Модель 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; } } }
Service for accsessing local database
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.CreateTableAsynclt;LevelProgressgt;(); await db.CreateTableAsynclt;Overviewgt;(); } 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 Tasklt;LevelProgressgt; GetProgress() { await Init(); var levelProgress = await db.Tablelt;LevelProgressgt;().FirstOrDefaultAsync(); //var levelProgress = await db.Tablelt;LevelProgressgt;().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 Tasklt;IEnumerablelt;Overviewgt;gt; GetOverview(string type) { await Init(); IEnumerablelt;Overviewgt; overview; if (type == "Running" || type == "Intervals") { overview = await db.Tablelt;Overviewgt;().Where(v =gt; v.Workout_type == "Running" || v.Workout_type == "Intervals").ToListAsync(); } else { overview = await db.Tablelt;Overviewgt;().Where(v =gt; v.Workout_type != "Running" || v.Workout_type != "Intervals").ToListAsync(); } return overview; } } }
AboutViewModel
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 () =gt; await Browser.OpenAsync("https://aka.ms/xamarin-quickstart")); //Command = "{Binding OpenWebCommand} Task.Run(async () =gt; await Loadup()); //use.currentlevel = use.currentlevel; } private LevelProgress pp; private LevelProgress _use; public LevelProgress use { get =gt; _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:
Да,если мы хотим обновить пользовательский интерфейс после изменения поля( muscularprogress
, cardioprogress
) в объекте use
, нам нужно создать 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 =gt; _muscularprogress; set { SetProperty(ref _muscularprogress, value); } } //public double cardioprogress { get; set; } private double _cardioprogress; public double cardioprogress { get =gt; _cardioprogress; set { SetProperty(ref _cardioprogress, value); } } }
Примечание:
В качестве теста я создал поддельный объект со специальным значением для него и назначил ему значение use
в начале , после этого мы изменили его значение,и пользовательский интерфейс мог обновляться автоматически.
private void test(object obj) { use.muscularprogress = 98.8; use.cardioprogress = 12.9; }
Комментарии:
1. Привет @Эмиль Легздинс , я не получал от тебя вестей уже пару дней. Пожалуйста, дайте мне знать, если я могу чем-то помочь здесь.