Xamarin 动态更新 CollectionView 中的特定 DataTemplate 项目属性具有唯一值

问题描述 投票:0回答:1
<CollectionView ItemsSource="{Binding ProductDb}">
    <CollectionView.ItemTemplate>
        <DataTemplate>
            <StackLayout>
                <Label Text="{Binding ItemStatus}" />
                <Label Text="{Binding ItemId}" />
                <Label Text="{Binding ItemDescription}" />
            </StackLayout>
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

collectionView 首先从数据库中加载并等待代码中发生的特定事件。所有项目数据属性的

ItemStatus
最初都有相同的消息“仍在进行中”。

然后当事件发生时,它必须更新

ItemStatus
中的特定项目数据
CollectionView
新消息“已完成!”

事件只是一个带有计时器的常规 C# 方法。 2 分钟后,它必须更新一个

ItemStatus
属性并将其消息更改为“已完成”。

我尝试从 INotifyPropertyChanged 的 OnPropertyChanged 更新

ItemStatus
,但它会使用相同的值更新每个项目数据的所有 ItemStatus。 我知道这是正常行为,因为 ItemStatus 属性名称在每个项目数据中找到自己。

我还尝试使用 x:Name 作为 ItemStatus 标签,但它不起作用;我在 Microsoft 网站上看到 DataTemplate 为其中的所有元素创建了一个新范围,

我也在考虑创建动态元素,但不确定是否可行。

顺便说一下,我只想动态更新特定 ItemId/Item Data 的 ItemStatus,

我记得在 HTML/CSS/Javascript 中有一种 CLASS 和 ID 元素,您可以在页面的任何位置从 javascript 方法访问它们。

请问有人知道如何实现吗?

private string itemStatus = "Still in progress";

public string ItemStatus
{
    get => itemStatus;
    set
    {
        if (value == itemStatus)
            return;

        itemStatus = value;     
        OnPropertyChanged(nameof(ItemStatus));
    }
}


private void UpdateUIItemStatusMessage(string uniqueMessage)
{
    ItemStatus = $"Completed !!!";
}

Jason 请求的代码

namespace WarehouseMobile
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class ProductPage : ContentPage
    {
        private string itemStatusMessage = "Still in progress";

        public string ItemStatus
        {
            get => itemStatusMessage;
            set
            {
                if (value == itemStatusMessage)
                    return;

                itemStatusMessage = value;
                OnPropertyChanged(nameof(ItemStatus));
            }
        }

        private ObservableCollection<ProductDb> _products;
        public ObservableCollection<ProductDb> Products
        {
            get { return _products; }
            set
            {
                _products = value;
                OnPropertyChanged(nameof(Products));
            }
        }

        public ProductPage()
        {
            InitializeComponent();

            BindingContext = this;

            Products = new ObservableCollection<ProductDb>();
        }

        protected override async void OnAppearing()
        {
            base.OnAppearing();

            Products = new ObservableCollection<ProductDb>(data);
            myCollection.ItemsSource = Products;
        }
        
        private void UpdateUIItemStatusMessage(string itemId)
        {
            var myItems = myCollection.ItemsSource as ObservableCollection<ProductDb>;

            var selectedItem = myItems.FirstOrDefault(o => o.Id == 4);

            selectedItem.ItemStatus = $"NEW MESSAGE !!! - Completed";
        }
    }
}

public class ProductDb
    {
        [PrimaryKey, AutoIncrement]
        public int ItemId { get; set; }
        public string ItemDescription { get; set; }
        public string ItemStatus { get; set; }
    }
xamarin xamarin.forms xamarin.android monodevelop
1个回答
0
投票

使用 LINQ

using System.Linq;

...

var item = MyItems.FirstOrDefault(x => x.ItemID == SelectedItemID);
item.ItemStatus = "some new status";

其次,如果您的 UI 绑定到类

P
的属性
C
,那么如果您希望 UI 在
P
的值更改时更新,
C
必须实现 INotifyPropertyChanged。在其他一些类上实现它对你没有帮助,它必须在相关属性所属的类上完成

实施

INotifyPropertyChanged

首先,将其添加到类声明中

public class C : INotifyPropertyChanged

然后,添加一个

PropertyChanged
事件

public event PropertyChangedEventHandler PropertyChanged; 

private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")  
    {  
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }  

最后,在要动态更新的任何属性的设置器中添加对

PropertyChanged
处理程序的调用

private string p;

public string P 
{
  get { return p; }
  set {
    p = value;
    NotifyPropertyChanged();  
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.