我正在开发Windows Universal app。我有一个GridView,它有一个文本块和一个按钮。 gridview从服务获取未购买对象的数据。该按钮用于购买特定对象。因此,如果用户点击按钮,则购买该对象& gridview会刷新以从中删除购买的商品。
我以简化的方式说明了我的要求。我尝试了两种方法,两种都不起作用。能否请你就此提出解决方案。
我使用的第一种方法是使用Model
类继承ViewModel
类,以便我可以访问ViewModel
类的方法,但它会在StackOverflowException
中抛出ViewModelBase
在SetProperty<T>
方法。
P.S。 - 我不想迁移到MVVMLight等任何框架。
ViewModel.cs
public class ViewModel : ViewModelBase
{
public ViewModel()
{
DataCollection = new ObservableCollection<Model>();
for (int i = 1; i < 10; i++)
{
DataCollection.Add(new Model { Number = i });
}
}
private ObservableCollection<Model> _DataCollection;
public ObservableCollection<Model> DataCollection
{
get { return _DataCollection; }
set { this.SetProperty(ref this._DataCollection, value); }
}
}
Model.cs
public class Model : ViewModel
{
public RelayCommand<int> DeleteCommand { get; set; }
public Model()
{
DeleteCommand = new RelayCommand<int>((x) => DeleteNumber(x));
}
private void DeleteNumber(int x)
{
var obj = DataCollection.Where(varNum => varNum.Number == x).FirstOrDefault();
if (obj != null)
{
DataCollection.Remove(obj);
}
}
private int _Number;
public int Number
{
get { return _Number; }
set { this.SetProperty(ref this._Number, value); }
}
}
第二种方式我保持隔离,所以我无法访问这些方法。
ViewModel.cs与上面相同
Model.cs
public class Model : ViewModelBase
{
public RelayCommand<int> DeleteCommand { get; set; }
public Model()
{
DeleteCommand = new RelayCommand<int>((x) => DeleteNumber(x));
}
private void DeleteNumber(int x)
{
// How to access ViewModel's DataCollection property or
// a method which sets un-purchased objects in DataCollection property
}
private int _Number;
public int Number
{
get { return _Number; }
set { this.SetProperty(ref this._Number, value); }
}
}
ViewModelBase.cs
public class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] String propertyName = null)
{
if (object.Equals(storage, value)) return false;
storage = value;
this.OnPropertyChanged(propertyName);
return true;
}
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var eventHandler = this.PropertyChanged;
if (eventHandler != null)
{
eventHandler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
答案 0 :(得分:0)
好吧,在第一个例子中,你得到了一个StackOverflowException,因为你的ViewModel每次都会实例化9个模型 - 而且由于你的Model是ViewModel的扩展,每个实例都会实例化9个模型并发生无限递归。但是,这并没有回答你的主要问题:)
你的班级名字让我感到困惑,因为在MVVM中有一个&#34;模型&#34;它只是表示操作它的数据和方法,而ViewModel从模型中请求这些数据,并通过可通过绑定从View中检索的公共可访问属性来呈现它。 View了解ViewModel,ViewModel知道Model,而Model只知道数据。在任何情况下,您都不应该直接从视图绑定到模型!
您希望在ViewModel中存放RelayCommand,以便您的View可以绑定到它,并根据您在用户购买项目时要发生的事情(将其存储在数据库中,在另一个变量中跟踪) ,只需从视图中删除而不做任何其他事情,等等。)当发生这种情况时,您可能需要或可能不需要编写额外的逻辑。通常,您希望ViewModel处理用户输入并更新演示文稿对象,并通知模型进行了更改,如果这是您的应用程序所需要的。想想它,因为Model保存实际数据,而ViewModel只保存用户看到的内容。
不幸的是,如果不知道自己要做的更多细节,那么很难给出比这更具体的建议!