如何在Xamarin中使用MVVM不断更新字符串。

huangapple go评论63阅读模式
英文:

How would I constantly update a string in xamarin Using MVVM

问题

Here is the translation of the content you provided:

制作一个倒计时到一个人死亡的时钟

我有一个线程检查时间,然后计算剩下多少周,然后显示它们。

我认为我可以通过使用 ViewModel.TimeLeftString = TimeLeft.ToString() 来实现这个目标。

视图

<Label Grid.Column="0" Grid.Row="1" VerticalOptions="CenterAndExpand" FontSize="Title" Text="{Binding TimeLeft}" BackgroundColor="Purple"/>

视图模型

string timeLeft;

public string TimeLeft
{
    get => timeLeft;
    set
    {
        timeLeft = value;

        var args = new PropertyChangedEventArgs(nameof(TimeLeft));

        PropertyChanged?.Invoke(this, args);
    }
}

模型(这在一个线程中运行)

DateTime LastRecordedTime = DateTime.MinValue;
while (true)
{
    // 读取当前时间
    DateTime CurrentTime = DateTime.Now;

    if (CurrentTime >= LastRecordedTime)
    {
        LastRecordedTime = addInterval(CurrentTime, Interval, DurationOfInterval);
        Console.WriteLine($"时间已过 {LastRecordedTime.ToString("dd/MM/yyyy | HH:mm:ss")}");

        // 运行程序
        ViewModel.TimeSpent = CurrentTime.ToString();
        Console.WriteLine(CurrentTime.ToString());
    }
}

然而,这似乎不起作用,没有显示任何内容。如有需要,请告诉我您需要的进一步帮助。

英文:

Making a clock that counts down to a persons death

i have thread that checks the time and then figures out how many weeks are left then displays them.

i thought id do this by using ViewModel.TimeLeftString = TimeLeft.ToString()

View

<Label Grid.Column="0" Grid.Row="1" VerticalOptions="CenterAndExpand" FontSize="Title" Text="{Binding TimeLeft}" BackgroundColor="Purple"/>

View Model

string timeLeft;

public string TimeLeft
{
    get => timeLeft;
    set
    {
        timeLeft = value;

        var args = new PropertyChangedEventArgs(nameof(TimeLeft));

        PropertyChanged?.Invoke(this, args);
    }
}

Model (this is being ran in a thread)

DateTime LastRecordedTime = DateTime.MinValue;
            while (true)
            {
                //read current time,
                DateTime CurrentTime = DateTime.Now;


                if (CurrentTime >= LastRecordedTime)
                {
                    LastRecordedTime = addInterval(CurrentTime, Interval, DurationOfInterval);
                    Console.WriteLine($"time has passed {LastRecordedTime.ToString("dd/MM/yyyy |                 HH:mm:ss")}");

                    //run the funkin program thing
                    ViewModel.TimeSpent = CurrentTime.ToString();
                    Console.WriteLine(CurrentTime.ToString());




                }
            }

This doesn't work though and displays nothing. any help is greatly appreciated

答案1

得分: 0

Based on the description you posted, here's the translated code portion:

  1. 创建一个ViewModel (MyViewModel.cs) 并实现 INotifyPropertyChanged 接口。
public class MyViewModel : INotifyPropertyChanged
{
    string timeLeft;
    public string TimeLeft
    {
        set { SetProperty(ref timeLeft, value); }
        get { return timeLeft; }
    }

    public MyViewModel()
    {
        TimeLeft = "2023.5.18";

        Device.StartTimer(TimeSpan.FromSeconds(3), () =>
        {
            DateTime LastRecordedTime = DateTime.MinValue;
            DateTime CurrentTime = DateTime.Now;

            if (CurrentTime >= LastRecordedTime)
            {
                Console.WriteLine($"time has passed {LastRecordedTime.ToString("dd/MM/yyyy | HH:mm:ss")}");
                TimeLeft = CurrentTime.ToString();
            }

            return true;
        });
    }

    bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
    {
        if (Object.Equals(storage, value))
            return false;
        storage = value;
        OnPropertyChanged(propertyName);
        return true;
    }
    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
    public event PropertyChangedEventHandler PropertyChanged;
}
  1. MainPage.xaml

在页面中设置 BindingContext,并将 TimeLeft 绑定到一个标签(Label)。

<?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:mvvmapp518="clr-namespace:MVVMApp518"
             x:Class="MVVMApp518.MainPage">

    <ContentPage.BindingContext>
        <mvvmapp518:MyViewModel></mvvmapp518:MyViewModel>
    </ContentPage.BindingContext>

    <StackLayout>
        <Label VerticalOptions="CenterAndExpand" FontSize="Title" Text="{Binding TimeLeft}" />
    </StackLayout>
</ContentPage>

注意:

ViewModel.TimeSpent = CurrentTime.ToString();

从您分享的代码中,我找不到您更改 TimeLeft 值的代码。另外,我们还需要确保修改的是页面的 BindingContext,这是 MyViewModel 类的实例。

英文:

Based on the description you posted,I created a simple demo and achieved a similar function.

You can refer to the following code:

1.create a viewmodel (MyViewModel.cs) and implement interface INotifyPropertyChanged.

I also added Device.StartTimer to the constructor of the viewmodel to change the value of TimeLeft.Once changing the value of TimeLeft, the UI will update automatically.

public class MyViewModel: INotifyPropertyChanged 
    {

        string timeLeft;
        public string TimeLeft
        {
            set { SetProperty(ref timeLeft, value); }
            get { return timeLeft; }
        }
  
        public MyViewModel()
        {

            TimeLeft = &quot;2023.5.18&quot;;


            Device.StartTimer(TimeSpan.FromSeconds(3), () =&gt; {

                DateTime LastRecordedTime = DateTime.MinValue;

                DateTime CurrentTime = DateTime.Now;

                if (CurrentTime &gt;= LastRecordedTime)
                {
                    //LastRecordedTime = addInterval(CurrentTime, Interval, DurationOfInterval);
                    Console.WriteLine($&quot;time has passed {LastRecordedTime.ToString(&quot;dd/MM/yyyy |HH:mm:ss&quot;)}&quot;);

                    //run the funkin program thing
                    TimeLeft = CurrentTime.ToString();
                }

                return true;

            });
        }

        bool SetProperty&lt;T&gt;(ref T storage, T value, [CallerMemberName] string propertyName = null)
        {
            if (Object.Equals(storage, value))
                return false;
            storage = value;
            OnPropertyChanged(propertyName);
            return true;
        }
        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        public event PropertyChangedEventHandler PropertyChanged;
    }

2.MainPage.xaml

Here set the BindingContext for the page and bind TimeLeft to a Label.

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt; 
&lt;ContentPage xmlns=&quot;http://xamarin.com/schemas/2014/forms&quot;
             xmlns:x=&quot;http://schemas.microsoft.com/winfx/2009/xaml&quot; 
             xmlns:mvvmapp518=&quot;clr-namespace:MVVMApp518&quot;
             x:Class=&quot;MVVMApp518.MainPage&quot;&gt;

    &lt;ContentPage.BindingContext&gt;
        &lt;mvvmapp518:MyViewModel&gt;&lt;/mvvmapp518:MyViewModel&gt;
    &lt;/ContentPage.BindingContext&gt;

    &lt;StackLayout&gt;
        &lt;Label  VerticalOptions=&quot;CenterAndExpand&quot; FontSize=&quot;Title&quot; Text=&quot;{Binding TimeLeft}&quot; /&gt;

        
    &lt;/StackLayout&gt;
&lt;/ContentPage&gt;

Note:

> ViewModel.TimeSpent = CurrentTime.ToString();

From the code you shared, I couldn't find the code that you changed the value of TimeLeft.

Besides,we also need to make sure to modify the same instance of class MyViewModel which is the BindingContext of your page.

huangapple
  • 本文由 发表于 2023年5月18日 03:48:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/76275715.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定