问题描述
使用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.Horizontal;
s.Children.Add(BTN);
s.Children.Add(数据);
this.View =秒;
}
} 公众的MainPage()
{
视图模型=新视图模型();
viewModel.ViewModelList.Add(新模型(0));
viewModel.ViewModelList.Add(新模型(0));
的InitializeComponent();
} 公共无效的InitializeComponent()
{
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适当的结合和更新?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!