簡體   English   中英

C#MVVM計算總計

[英]C# MVVM Calculating Total

我需要根據選定的價格和數量計算交易價值。 怎么能

以下是我的ViewModel:

class ViewModel : ViewModelBase
{
    public Trade Trade
    {
        get { return _trade; }
        set { SetField(ref _trade, value, () => Trade); }
    } private Trade _trade;

    public decimal TradeValue
    {
        get { return Trade.Amount * Trade.Price; }
    } 

}

ViewModelBase繼承INotifyPropertyChanged並包含SetField()

以下是貿易類:

public class Trade : INotifyPropertyChaged
{
    public virtual Decimal Amount
    {
        get { return _amount; }
        set { SetField(ref _amount, value, () => Amount); }
    } private Decimal _amount;
    public virtual Decimal Price
    {
        get { return _price; }
        set { SetField(ref _price, value, () => Price); }
    } private Decimal _price;
    ......
}

我知道由於設計我的TradeValue只計算一次(當它第一次請求時),並且當金額/價格變化時UI不會更新。 實現這一目標的最佳方法是什么?

任何幫助非常感謝。

更新: INotifyPropertyChanged實現:

    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
    protected virtual void OnPropertyChanged<T>(Expression<Func<T>> selectorExpression)
    {
        if (selectorExpression == null)
            throw new ArgumentNullException("selectorExpression");
        var body = selectorExpression.Body as MemberExpression;
        if (body == null)
            throw new ArgumentException("The body must be a member expression");
        OnPropertyChanged(body.Member.Name);
    }
    protected bool SetField<T>(ref T field, T value, Expression<Func<T>> selectorExpression)
    {
        if (EqualityComparer<T>.Default.Equals(field, value)) return false;
        field = value;
        OnPropertyChanged(selectorExpression);
        return true;
    }

這兩個答案都有效,現在我不知道選擇哪一個作為最佳答案。 Luke的答案似乎更好,因為似乎只有更少的代碼重復,盡管只是監聽OnPropertyChanged事件似乎更輕量級。

這就是我通常這樣做的方式:

private bool has_inited_tradevalue_linkage = false;
public decimal TradeValue
{
    get 
    { 
        if(!has_inited_tradevalue_linkage)
        {
            has_inited_tradevalue_linkage = true;
            this.PropertyChanged += (_, e) => 
            {
                if(e.PropertyName.Equals("Amount") || e.PropertyName.Equals("Price"))
                    OnPropertyChanged("TradeValue");
            };
        }
        return Trade.Amount * Trade.Price; }
}

這種方式鏈接是懶惰地構造的(所以你不發布沒有人感興趣的事件),並且所有的邏輯仍然包含在這個屬性中。 相反,您可以在PriceAmount的設置者中添加對OnPropertyChanged("TradeValue")調用,但這對於課堂上的其他人來說有點糟糕(至少在我看來)。 我已經非常成功地使用了這種模式,以創建類似的“依賴”屬性。

另一個選擇就是專門跟蹤依賴項:

在ViewModelBase中你可以添加這個:

私人詞典> DependencyMap = new Dictionary>(); protected void AddPropertyDependency(String prop,String dependantProp){if(DependencyMap.ContainsKey(prop)){DependencyMap [prop] .Add(dependantProp); } else {DependencyMap [prop] = new List {dependantProp}; }}

然后在你的OnPropertyChanged方法中:

protected void OnPropertyChanged(String prop)
{
    var eh = PropertyChanged;
    if(eh != null)
    {
        eh(this, new PropertyChangedEventArgs(prop);
        if(DependencyMap.ContainsKey(prop))
        {
            foreach(var p in DependencyMap[prop])
                OnPropertyChanged(p);//recursive call would allow for arbitrary dependencies
        }
    }
}

然后在您的類構造函數中,您只需定義屬性依賴項:

public ViewModel()
{
    AddPropertyDependency("Amount", "TradeValue");
    AddPropertyDependency("Price", "TradeValue");
}

這絕對是一個更通用的解決方案,大多數更改都在您的基類中。

private void UpdateValue()
        {
            this.Value = this.Acres * this.YieldPerAcre * this.UnitPrice;
        }      
       public double Acres
        {
            get { return _cropProductionRecord.Acres; }
            set
            {
                _cropProductionRecord.Acres = value;
                OnPropertyChanged("Acres");
                UpdateValue();
            }
        }
        public double YieldPerAcre
        {
            get { return _cropProductionRecord.YieldPerAcre; }
            set
            {
                _cropProductionRecord.YieldPerAcre = value;
                OnPropertyChanged("YieldPerAcre");
                UpdateValue();
            }
        }

        public double UnitPrice
        {
            get { return _cropProductionRecord.UnitPrice; }
            set
            {
                _cropProductionRecord.UnitPrice = value;
                OnPropertyChanged("UnitPrice");
                UpdateValue();
            }
        }
        public double Value
        {
            get { return _cropProductionRecord.Value; }
            set
            {
                _cropProductionRecord.Value = value;
                OnPropertyChanged("Value");
            }
        }

在VM類的Trade屬性的set方法中,在Trade類上訂閱PropertyChanged事件。 在該事件處理程序中,為屬性TradeValue發布propertychanged。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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