[英]How to call one viewmodel's method from another viewmodel
我正在開發Windows Universal應用程序。 我有一個GridView,其中有一個文本塊和一個按鈕。 gridview從服務獲取未購買對象的數據。 該按鈕用於購買特定對象。 因此,如果用戶單擊按鈕,則表示已購買對象,並且gridview會刷新以從其中刪除購買的項目。
我以簡化的方式說明了我的要求。 我嘗試了兩種方法,兩種方法均無效。 您能建議我有關此問題的解決方案嗎?
我使用的第一種方法是用ViewModel
類繼承Model
類,這樣我就可以訪問ViewModel
類的方法,但是它在ViewModelBase
中的SetProperty<T>
方法上引發了StackOverflowException
。
PS-我不想遷移到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));
}
}
}
好吧,在第一個示例中,您得到了StackOverflowException,因為ViewModel每次實例化9個Models-並且由於Model是ViewModel的擴展,因此每個實例都實例化9個Models,並且發生無限遞歸。 但是,這並不能回答您的主要問題:)
您的類名稱令我感到困惑,因為在MVVM中,“模型”只是表示數據和用於操縱它的方法的表示,而ViewModel則從Model請求此數據並通過從View檢索到的可公開訪問的屬性來呈現通過綁定。 View知道ViewModel,ViewModel知道Model,而Model僅僅知道數據。 無論如何,您都不應該直接從視圖綁定到模型!
您需要將RelayCommand放置在ViewModel中,以便您的View可以綁定到它,並取決於用戶購買項目時想要發生的事情(將其存儲在數據庫中,在另一個變量中進行跟蹤,只需將其從視圖而無需執行其他任何操作,等等),您可能需要也可能不需要為發生這種情況編寫其他邏輯。 通常,如果您的應用需要這樣做,您將希望ViewModel處理用戶輸入並更新表示對象,並通知Model進行了更改。 可以將其視為模型保存實際數據,而ViewModel僅保存用戶看到的內容。
不幸的是,在不知道自己要做什么的情況下,很難提供比這更具體的建議!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.