簡體   English   中英

如何從另一個視圖模型調用一個視圖模型的方法

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM