【问题标题】:How Do I Force My UI Page To Update Automatically?如何强制我的 UI 页面自动更新?
【发布时间】:2021-06-21 14:34:51
【问题描述】:

我正在尝试学习应用程序开发,并且一直在阅读文档和遵循教程来熟悉。

我创建了一个包含 CollectionView 的 XAML 文件。

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Organized_Chaos.Views.NotesPage"
             Title="NotesPage">
    <ContentPage.Content>
        <StackLayout>
            <CollectionView ItemsSource ="{Binding Monkii}"
                            SelectionMode="Single"
                            SelectionChanged="OnSelectionChanged">
                <CollectionView.ItemTemplate>
                    <DataTemplate>
                        <Grid Padding="10"
                              RowDefinitions="Auto, *"
                              ColumnDefinitions="Auto, *">

                            <Image Grid.RowSpan="2"
                                   Source="{Binding ImageUrl}"
                                   Aspect="AspectFill"
                                   HeightRequest="60"
                                   WidthRequest="60"/>

                            <Label Grid.Column="1"
                                   Text="{Binding Name}"
                                   FontAttributes="Bold"/>

                            <Label Grid.Row="1"
                                   Grid.Column="1"
                                   Text="{Binding Location}"
                                   VerticalOptions="End"/>

                        </Grid>
                    </DataTemplate>
                </CollectionView.ItemTemplate>
            </CollectionView>
            
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

我已经制作了相应的 C# 文件,用数据填充 CollectionView:

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace Organized_Chaos.Views
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class NotesPage : ContentPage
    {

        public IList<Monke> Monkii { get; private set; }

        public NotesPage()
        {
            InitializeComponent();

            Monkii = new List<Monke>();
            Monkii.Add(new Monke
            {
                Name = "Baboon",
                Location = "Africa & Asia",
                ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/f/fc/Papio_anubis_%28Serengeti%2C_2009%29.jpg/200px-Papio_anubis_%28Serengeti%2C_2009%29.jpg"
            });
            Monkii.Add(new Monke
            {
                Name = "Test",
                Location = "Test",
                ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/f/fc/Papio_anubis_%28Serengeti%2C_2009%29.jpg/200px-Papio_anubis_%28Serengeti%2C_2009%29.jpg"
            });

            BindingContext = this;

            //This would run asynchronously to continuously update the CollectionView....
            Task.Run(() =>
            {
                int counter = 0;
                    counter += 1;
                    Thread.Sleep(1000);
                    Device.BeginInvokeOnMainThread(() =>
                    {
                        Monkii[0].Name = counter.ToString();
                        Monkii.Add(new Monke
                        {
                            Name = "Test",
                            Location = "Test",
                            ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/f/fc/Papio_anubis_%28Serengeti%2C_2009%29.jpg/200px-Papio_anubis_%28Serengeti%2C_2009%29.jpg"
                        });
                    });

            });
            
        }

        void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            Monke selectedItem = e.CurrentSelection as Monke;
        }
    }
}

目前,当我运行程序时,它会创建两条测试数据,如果我想显示第三条,我必须以某种方式单击页面外并单击返回以刷新它。

但是,我希望 CollectionView 以 60 秒的间隔无限期更新(即,当新的股票数据进入时,您会希望看到它而不刷新),但这似乎比最初想象的要复杂得多。

为什么不使用 BeginInvokeOnMainThread 更新 UI?我以为这个功能是专门为这样的场景设计的。

【问题讨论】:

  • 我刚刚尝试了你的建议,不幸的是效果是一样的。
  • 您的 Monkii 集合不可观察,因此 UI 不知道集合已更改。您应该明确通知 UI 有关此类更改或将 IList 替换为 ObservableCollection 之类的内容,它将自动发布更改通知。
  • 这两个链接讨论了 wpf 中的集合视图更改,但在 xamarin 中可能具有相同的实现:stackoverflow.com/questions/35317427/…stackoverflow.com/questions/7713190/…

标签: c# xaml xamarin.forms


【解决方案1】:

您可以使用计时器以 60 秒的间隔无限期更新。我以 10 秒为例。

型号:

 public class Monke : INotifyPropertyChanged
{
    private string _name;
    public string Name
    {
        get
        {
            return _name;
        }
        set
        {
            _name = value;
            OnPropertyChanged("Name");
        }
    }
    private string _location;
    public string Location
    {
        get
        {
            return _location;
        }
        set
        {
            _location = value;
            OnPropertyChanged("Location");
        }
    }
    private string _imageUrl;
    public string ImageUrl
    {
        get
        {
            return _imageUrl;
        }
        set
        {
            _imageUrl = value;
            OnPropertyChanged("ImageUrl");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

视图模型:

public class MonkeViewModel
{
    public ObservableCollection<Monke> Monkii { get; private set; }
    public MonkeViewModel()
    {
        CreateCollection();
    }

    public void CreateCollection()
    {
        Monkii = new ObservableCollection<Monke>();
        Monkii.Add(new Monke
        {
            Name = "Baboon",
            Location = "Africa & Asia",
            ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/f/fc/Papio_anubis_%28Serengeti%2C_2009%29.jpg/200px-Papio_anubis_%28Serengeti%2C_2009%29.jpg"
        });
        Monkii.Add(new Monke
        {
            Name = "Test",
            Location = "Test",
            ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/f/fc/Papio_anubis_%28Serengeti%2C_2009%29.jpg/200px-Papio_anubis_%28Serengeti%2C_2009%29.jpg"
        });
    }

}

后面的代码:

  public readonly string Name;
    public System.Timers.Timer timer;
    public MonkeViewModel monkeViewModel { get; set; }
    public Page21()
    {
        InitializeComponent();
        monkeViewModel = new MonkeViewModel();
        this.BindingContext = monkeViewModel;
       
    }
    protected override void OnAppearing()
    {
        base.OnAppearing();

        timer = new System.Timers.Timer(10000);
        timer.Elapsed += Timer_Elapsed; ;

        timer.Start();
    }

    private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {         
        monkeViewModel.Monkii.Add(new Monke
        {
            Name = "Test2",
            Location = "TestUpdate",
            ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/f/fc/Papio_anubis_%28Serengeti%2C_2009%29.jpg/200px-Papio_anubis_%28Serengeti%2C_2009%29.jpg"
        });

    }

    private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        Monke selectedItem = e.CurrentSelection as Monke;
    }  

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-13
    • 1970-01-01
    • 2016-02-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多