本文将接着上篇文章,介绍一下三点:(Universal App)
1.将添加Product集合,绑定到列表
2.给点击ListBox的添加选项改变时的事件(要附加依赖属性,和Button点击事件不同)
3.通过自定义类以JSON获取保存数据到存储空间
-------------------------------------------------
1.添加集合,绑定列表,支持可操作
在ProductViewModel中添加字段、属性:
private ObservableCollection<ProductModel> _products; public ObservableCollection<ProductModel> Product //产品集合{ get { return _products; } set { SetProperty(ref this._products, value); } }
并在构造函数中添加实例化语句
public ProductViewModel() { Products = new ObservableCollection<ProductModel>(); }
前台ListBox代码
<在View后台,this.DataContext = product; 也就是说ListBox.dataContext也是一样的>
<ListBox ItemsSource="{Binding Products}"> <ListBox.ItemTemplate> <DataTemplate> <StackPanel> <TextBlock Text="{Binding ProductId}"/> <TextBlock Text="{Binding ProductName}"/> <TextBlock Text="{Binding UnitPrice}"/> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox>
将保存数据的事件改写为
public void SaveProduct() { //await new MessageDialog("保存").ShowAsync(); Products.Add(CurrentProduct); //添加数据到集合中 }
每一次输入数字后,保存,ListBox数据将会增加。(你们可以自己试着实现删除。)
2.给ListBox添加事件(相当于SelectedChanged) 我们要使用依赖属性
新增一个SelectionChangedBehavior类
public static class SelectionChangedBehavior { public static readonly DependencyProperty SelectionChangedCommandProperty = DependencyProperty.RegisterAttached( "SelectionChangedCommand", typeof(ICommand), typeof(SelectionChangedBehavior), new PropertyMetadata(null, new PropertyChangedCallback(SeletionChangedPropertyChangedCallback))); public static ICommand GetSelectionChangedCommand(DependencyObject d) { return (ICommand)d.GetValue(SelectionChangedCommandProperty); } public static void SetSelectionChangedCommand(DependencyObject d, ICommand value) { d.SetValue(SelectionChangedCommandProperty, value); } public static void SeletionChangedPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) { ((ListBox)d).SelectionChanged += (ss, ee) => { ListBox lv = ss as ListBox; GetSelectionChangedCommand(lv).Execute(lv.SelectedItem); }; } }
在View.xaml中
添加引用 xmlns:behavior="using:SimpleMVVMExample.Common" 位置为上述类所在位置
给ListBox添加属性
<ListBox ItemsSource="{Binding Products}" behavior:SelectionChangedBehavior.SelectionChangedCommand="{Binding SelectionChangedCommand}" >
现在去ProductViewModel实现SelectionChangedCommand;
private ICommand _selectionChangedCommand; public ICommand SelectionChangedCommand { get { if (_selectionChangedCommand == null) _selectionChangedCommand = new RelayCommand(SelectionChanged); return _selectionChangedCommand; } } public void SelectionChanged(object parameter) { ProductModel productModel = parameter as ProductModel; //这已经获取到了 //具体要做些什么事情 自己处理 }
3.利用生命周期来向设置中保存、提取数据
A.自定义类转换为JSON
ProductViewModel.cs
public void SaveData() { var settings = ApplicationData.Current.LocalSettings; string json = this.Stringify(); settings.Values["ViewModel"] = json; } private string Stringify() { JsonObject jsonObject = new JsonObject(); JsonArray jsonArray = new JsonArray(); foreach (ProductModel item in Products) { jsonArray.Add(item.ToJsonObject()); } JsonObject products = new JsonObject(); products.SetNamedValue("ProductsKey", jsonArray); products.SetNamedValue("NewId", JsonValue.CreateNumberValue(_productId)); jsonObject.SetNamedValue("SaveKey", products); return jsonObject.Stringify(); }
ProductModel.cs
public JsonObject ToJsonObject() { JsonObject jsonObject = new JsonObject(); jsonObject.SetNamedValue("NameKey", JsonValue.CreateStringValue(ProductName)); jsonObject.SetNamedValue("IdKey", JsonValue.CreateNumberValue(ProductId)); jsonObject.SetNamedValue("PriceKey", JsonValue.CreateNumberValue((double)UnitPrice)); JsonObject product = new JsonObject(); product.SetNamedValue("ProductKey", jsonObject); return product; }
自己画的结构示意图。。。
B.JSON转换为自定义类
ProductViewModel.cs:
public void GetData() { string setting = ApplicationData.Current.LocalSettings.Values["ViewModel"].ToString(); ProductViewModel productViewModel = new ProductViewModel(setting); this._productId = productViewModel._productId; this._products = productViewModel.Products; } public ProductViewModel(string jsonString) { this.Products = new ObservableCollection<ProductModel>(); JsonObject jsonOject = JsonObject.Parse(jsonString); this.ProductId = (int)jsonOject.GetNamedObject("SaveKey").GetNamedNumber("NewId"); foreach (var item in jsonOject.GetNamedObject("SaveKey").GetNamedArray("ProductsKey", new JsonArray())) { if (item.ValueType == JsonValueType.Object) { this.Products.Add(new ProductModel(item.GetObject())); } } }
ProductModel.cs
public ProductModel(JsonObject jsonObject) { JsonObject productObject = jsonObject.GetNamedObject("ProductKey"); if (productObject != null) { this.ProductId = (int)productObject.GetNamedNumber("IdKey"); this.ProductName = (string)productObject.GetNamedString("NameKey"); this.UnitPrice = (decimal)productObject.GetNamedNumber("PriceKey"); } }
C.View生命周期
private void NavigationHelper_LoadState(object sender, LoadStateEventArgs e) { if (ApplicationData.Current.LocalSettings.Values.ContainsKey("ViewModel")) { product.GetData(); } } private void NavigationHelper_SaveState(object sender, SaveStateEventArgs e) { product.SaveData(); }
注: 上一篇文章里说了,MVVM下,在Model里不能包括任何方法,而此处转换JSON时,在Model里面的方法应该不规范。
可以在ProductViewModel里面实现。 这里只是给出进行转换的方法。写在ViewModel的保存、去除设置内容也是一样。
下面给出Demo: 为Universal App