你是怎么做到的ListView Xamarin.Forms适当的结合和更新? [英] How do you do proper binding and updating of Xamarin.Forms ListView?

查看:921
本文介绍了你是怎么做到的ListView Xamarin.Forms适当的结合和更新?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用MVVM模式,我有一个模型,视图模型和视图,其中包含一个ListView。 ListView控件绑定到视图模型中的一员,它是Model类的一个ObservableCollection。我可以得到初始显示工作的结合并在作用于视图可以更新Model类为适当的行属性,但我无法获取视图刷新,在从的ObservableCollection Model类获取数据。 ListView控件类不包含方法无效或强制刷新,这就解决了我的问题。我如何在ListView在模型更新数据后刷新?

下面是什么,我试图做一个简单的例子:每行包含一个按钮和标签。当点击一个按钮,我可以更新的标签,这将在屏幕上反映出来。我需要做的就是更新模型,这反过来会迫使该视图的更新。但是,我不能得到这个工作。在实际应用中,模型的更新将在业务逻辑层,而不是在视图中,在这之后我需要强制的ListView的刷新。

举例code:

 使用系统;
使用System.Collections.ObjectModel;
使用Xamarin.Forms;命名空间ListViewTest
{
    公共类模型
    {
        公共静态INT的id = 0;
        公共模型(串计数)
        {
            ID = +1;
            计数=计数;
        }
        公众诠释标识{搞定;组; }
        公共字符串计数{搞定;组; }
    }    公共类ModelList:与的ObservableCollection LT;型号:GT;
    {
    }    公共类视图模型
    {
        ModelList名单=新ModelList();
        公共ModelList ViewModelList
        {
            {返回列表; }
            组
            {
                列表=值;
            }
        }
    }    公共部分类的MainPage:ContentPage
    {
        公共视图模型视图模型;        公共类DATACELL:ViewCell
        {
            公共DATACELL()
            {
                VAR BTN =新按钮();
                Btn.Text =点击
                VAR数据=新的Label();
                Data.SetBinding(Label.TextProperty,伯爵);
                Btn.Clicked + =(对象发件人,EventArgs的E)=>
                {
                    模型模型=(型号)(((按钮)发送方).Parent.BindingContext);
                    诠释计数= Convert.ToInt32(model.Count);
                    算上++;
                    model.Count = count.ToString();                    //需要从数据源刷新的ListView这里...如何?
                };                StackLayout S =新StackLayout();
                s.Orientation = StackOrientation.Horizo​​ntal;
                s.Children.Add(BTN);
                s.Children.Add(数据);
                this.View =秒;
            }
        }        公众的MainPage()
        {
            视图模型=新视图模型();
            viewModel.ViewModelList.Add(新模型(0));
            viewModel.ViewModelList.Add(新模型(0));
            的InitializeComponent();
        }        公共无效的Ini​​tializeComponent()
        {
            ListView控件的ListView =新的ListView
            {
                的ItemsSource = viewModel.ViewModelList,
                ItemTemplate中=新的DataTemplate(()=>
                    {
                        返回新DATACELL();
                    })
            };
            内容=的ListView;
        }
    }
}


解决方案

我觉得你的模型需要实现INotifyPropertyChanged。因此,UI知道,在模型的值的更改

是这样的:

 公共类产品型号:INotifyPropertyChanged的
{
    //锅炉板
    公共事件PropertyChangedEventHandler的PropertyChanged;
    受保护的虚拟无效OnPropertyChanged(字符串propertyName的)
    {
        PropertyChangedEventHandler处理器=的PropertyChanged;
        如果(!=处理空值)处理器(这一点,新PropertyChangedEventArgs(propertyName的));
    }
    保护布尔SetField< T>(REF T字段,T值,字符串propertyName的)
    {
        如果(EqualityComparer< T> .Default.Equals(场,值))返回false;
        字段=值;
        OnPropertyChanged(propertyName的);
        返回true;
    }    // 道具
    私人字符串_count;
    公共字符串计数
    {
        {返回_count; }
        集合{SetField(REF _count,价值,伯爵); }
    }
}

Using the MVVM pattern, I have a Model, ViewModel and View, which contains a ListView. The ListView is bound to a member of the ViewModel that is an ObservableCollection of the Model class. I can get the binding for the initial display to work and can update properties on the Model class for the appropriate row upon acting on the view, but I cannot get the view to refresh, pulling data from the Model class in the ObservableCollection. The ListView class does not contain method to invalidate or force a refresh, which would address my issue. How do I get the ListView to refresh after updating data on the Model?

Here is a simple example of what I am trying to do: Each row contains a Button and Label. Upon clicking a button, I can update the label, which will be reflected on screen. What I need to do is update the Model, which in turn should force an update of the view. However, I cannot get this to work. In an actual application, updating of the Model will be in a business logic layer, not in the view, after which I need to force refresh of the ListView.

Example Code:

using System;
using System.Collections.ObjectModel;
using Xamarin.Forms;

namespace ListViewTest
{   
    public class Model
    {
        public static int ids = 0;
        public Model(string count) 
        {
            Id = +1;
            Count = count;
        }
        public int Id { get; set; }
        public string Count { get; set; }
    }

    public class ModelList : ObservableCollection<Model>
    {
    }

    public class ViewModel
    {
        ModelList list = new ModelList();
        public ModelList ViewModelList
        {
            get { return list; }
            set 
            { 
                list = value; 
            }
        }
    }

    public partial class MainPage : ContentPage
    {   
        public ViewModel viewModel;

        public class DataCell : ViewCell
        {
            public DataCell()
            {
                var Btn = new Button();
                Btn.Text = "Click";
                var Data = new Label();
                Data.SetBinding(Label.TextProperty,"Count");
                Btn.Clicked += (object sender, EventArgs e) => 
                {
                    Model model = (Model)(((Button)sender).Parent.BindingContext);
                    int count = Convert.ToInt32(model.Count);
                    count++;
                    model.Count = count.ToString();

                    // Need to refresh ListView from data source here... How???
                };

                StackLayout s = new StackLayout();
                s.Orientation = StackOrientation.Horizontal;
                s.Children.Add(Btn);
                s.Children.Add(Data);
                this.View = s;
            }
        }

        public MainPage ()
        {
            viewModel = new ViewModel();
            viewModel.ViewModelList.Add(new Model("0"));
            viewModel.ViewModelList.Add(new Model("0"));
            InitializeComponent();
        }

        public void InitializeComponent()
        {
            ListView listView = new ListView
            {
                ItemsSource = viewModel.ViewModelList,
                ItemTemplate = new DataTemplate(() =>
                    {
                        return new DataCell();
                    })
            };
            Content = listView;
        }
    }
}

解决方案

i think your model needs to implement INotifyPropertyChanged. So the UI knows that a value in model has changed

something like this :

public class Model : INotifyPropertyChanged
{
    // boiler-plate
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
    protected bool SetField<T>(ref T field, T value, string propertyName)
    {
        if (EqualityComparer<T>.Default.Equals(field, value)) return false;
        field = value;
        OnPropertyChanged(propertyName);
        return true;
    }

    // props
    private string _count;
    public string Count 
    {
        get { return _count; }
        set { SetField(ref _count, value, "Count"); }
    }
}

这篇关于你是怎么做到的ListView Xamarin.Forms适当的结合和更新?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆