首页 > 解决方案 > 在 itemtapped 上展开 listview 项目

问题描述

当我按下一个项目的名称时,我正在尝试制作一个可扩展的列表视图项目。问题是 IsVisiable 的值发生了变化,但没有反映在页面上并且它保持不变(只有项目的名称未显示所有隐藏的细节)。

首先,我在模型中添加了一个 IsVisiable 道具

public class Item
{
    public int Id { get; set; }

    public string UserId { get; set; }

    public string Name { get; set; }

    public string Category { get; set; }

    public string Quality { get; set; }

    public int Size { get; set; }

    public decimal Price { get; set; }

    public bool IsVisiable { get; set; }

}

这是内容页面

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         xmlns:viewModels="clr-namespace:XamarinApp.ViewModels;assembly=XamarinApp"
         x:Class="XamarinApp.ViewModels.Views.CustomerProfilePage">

<ContentPage.BindingContext>
    <viewModels:CustomerProfileViewModel/>
</ContentPage.BindingContext>

        <ListView ItemsSource="{Binding Items}" 
                  HasUnevenRows="True"
                  ItemTapped="ListView_OnItemTapped">


            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <StackLayout>
                            <Label Text="{Binding Name}" ></Label>
                            <StackLayout IsVisible="{Binding IsVisiable}">

                            <Label Text="{Binding Category}" ></Label>
                            <Label Text="{Binding Quality}" ></Label>
                            <Label Text="{Binding Size}" ></Label>
                            <Label Text="{Binding Price} "></Label>
                            </StackLayout>

                            <!--   <Label Text="المسافة بينك وبين العميل"></Label> -->


                        </StackLayout>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>

我创建了一个 onItemTapped 方法

    public partial class CustomerProfilePage : ContentPage
{
    public CustomerProfilePage (string userId)
    {

        InitializeComponent ();
        this.BindingContext = new CustomerProfileViewModel(userId); 

    }


    private void ListView_OnItemTapped(object sender, ItemTappedEventArgs e)
    {
        var vm = BindingContext as CustomerProfileViewModel;
        var Item = e.Item as Item;
        vm?.HideOrShowItem(Item);
    }
}

然后我在我的虚拟机中添加了 HideOrShow item 方法进行控制

public class CustomerProfileViewModel:INotifyPropertyChanged
{
    public CustomerProfileViewModel()
    {

    }

    public CustomerProfileViewModel(string cutomerId)
    {
        CustomerId = cutomerId;

        if (GetItems.CanExecute(null))
            GetItems.Execute(null);
    }

    public List<Item> Items
    {
        get => _items;
        set
        {

            if (Equals(value, _items)) return;
            _items = value;

            OnPropertyChanged();
        }
    }

    public string CustomerId { get;}

    private List<Item> _items;

    private Item _oldItem;

    ApiServices _apiServices = new ApiServices();




    public void HideOrShowItem(Item item)
    {

        if (_oldItem == item)
        {
            item.IsVisiable = !item.IsVisiable;
            UpdateItems(item);
        }
        else
        {
            if (_oldItem != null)
            {
                _oldItem.IsVisiable = false;
                UpdateItems(_oldItem);
            }

            item.IsVisiable = true;
            UpdateItems(item);
        }

        _oldItem = item;
    }

    private void UpdateItems(Item item)
    {
        var index = Items.IndexOf(item);
        Items.Remove(item);
        Items.Insert(index, item);


    }

    public ICommand GetItems
    {
        get
        {
            return new Command(async () =>
            {
                var accesstoken = Settings.AccessToken;
                Items = await _apiServices.GetItemsForSpecificUser(accesstoken, CustomerId);

            });
        }
    }


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


}

标签: xamllistviewxamarinxamarin.forms

解决方案


我能看到的问题:

  • 你的类Item必须实现INotifyPropertyChanged接口
  • 我还看到您可以更新您的列表Items。因此,要在您的 UI 中反映列表更改,Items必须是ObservableCollection<Item>

更新了 Item 类(应该看起来像这样):

    public class Item : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private int _id;
        private bool _isVisible;
        // . . .

        public int Id
        {
            get => _id;
            set
            {
                if (_id != value)
                {
                    _id = value;
                    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(this.Id)));
                }
            }
        }
        public bool IsVisible
        {
            get => _isVisible;
            set
            {
                if (_isVisible != value)
                {
                    _isVisible = value;
                    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(this.IsVisible)));
                }
            }
        }
    // . . . Other properties

在您的 ViewModel 中,声明项目列表:

private ObservableCollection<Item> _items;

public ObservableCollection<Item> Items{
    get => _items;
    private set{
        _items = value;
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(this.Items)));
    }
}

试试这个,告诉我们是否可以...


推荐阅读