2017-01-08 92 views
0

我正在使用Galasoft MVVM Light。我有一個DataGrid,它有四列,總金額,增值稅率,增值稅金額和淨金額。當用戶更改其中一個值時,我需要重新計算其他三個值。我有一箇中繼命令附加到DataGrid的CellEditEnding事件來激活執行計算的ViewModel中的代碼。但是我需要知道爲了正確進行計算而改變了哪個值。如何在XAML中指定哪個列/單元觸發了該事件,即如何將命令參數綁定到觸發列/單元的名稱?XAML將命令參數綁定到DataGrid列名

<DataGrid 
    ....> 
<i:Interaction.Triggers> 
    <i:EventTrigger EventName="CellEditEnding"> 
     <mvvm:EventToCommand Command="{Binding CalculateAusgabe_Command, 
        Mode=OneWay, 
        UpdateSourceTrigger=PropertyChanged, 
        diag:PresentationTraceSources.TraceLevel=High}" 
       CommandParameter="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGridTextColumn}}, Path=Name}" /> 
    </i:EventTrigger> 
</i:Interaction.Triggers> 
</DataGrid> 

在視圖模型的代碼是:

public RelayCommand<string> CalculateAusgabe_Command { get; set; } 
... 
CalculateAusgabe_Command = new RelayCommand<string>(CalculateAusgabe); 

最後,做計算的過程:

void CalculateAusgabe(string colName) 
{ 
    if (currBetrag.USt == null) return; 
    switch (colName) 
    { 
     case "colBetBtto": 
     case "colBetUStS": 
      if (currBetrag.BttoBetrag != 0M) 
      { 
       currBetrag.UStBetrag = Math.Round((currBetrag.BttoBetrag/(100M + currBetrag.USt.UStProz)) * currBetrag.USt.UStProz, 2); 
       currBetrag.NttoBetrag = currBetrag.BttoBetrag - currBetrag.UStBetrag; 
      } 
      break; 
     case "colBetUStB": 
     ... 

數據網格的當前行被綁定到currBetrag對象。一切正常,CalculateAusgabe在事件被觸發時被激活,但不管我做了什麼,參數colName總是爲空。對此問題的任何幫助表示讚賞。

+0

爲什麼不簡單地在currBetrag類的setter中執行計算?只要值被改變,就會調用列中顯示的屬性的setter,然後可以將CalculateAusgabe方法移動到currBetrag類並在所有這些setter中調用它。這是使用MVVM模式解決此問題的方法。您將無法使用指定DataGridTextColumn作爲RelativeSource,因爲DataGridColumn不是視覺元素,而是添加到可視化樹中。 – mm8

+0

謝謝你mm8,聽起來很合理。我已經使用了多年的WinForms應用程序,現在正在努力作爲wpf/xaml的新手,所以請你更詳細些?你能舉一個這樣的「制定者」的簡短例子嗎? –

+0

請參考我的回答。 – mm8

回答

1

你可以在currBetrag類的setter方法進行計算,例如:被認爲是一種不好的做法,無論您的母語是什麼不能用英語成員名稱

public class currBetrag : INotifyPropertyChanged 
{ 
    private decimal _bttoBetrag; 
    public decimal BttoBetrag 
    { 
     get { return _bttoBetrag; } 
     set 
     { 
      _bttoBetrag = value; 
      OnPropertyChanged(); 

      CalculateAusgabe("BttoBetrag"); 
     } 
    } 

    private decimal _uStBetrag; 
    public decimal UStBetrag 
    { 
     get { return _uStBetrag; } 
     set 
     { 
      _uStBetrag = value; 
      OnPropertyChanged(); 

      CalculateAusgabe("UStBetrag"); 
     } 
    } 

    private void CalculateAusgabe(string colName) 
    { 
     if (USt == null) return; 
     switch (colName) 
     { 
      //set the value of all fields... 
      _uStBetrag = ?; 
     } 

     //and raise the PropertyChanged event for all involved properties 
     OnPropertyChanged("UStBetrag"); 
     OnPropertyChanged("NttoBetrag"); 
     //... 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
    private void OnPropertyChanged([CallerMemberName] String propertyName = "") 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 

注意。

+0

謝謝你mm8,現在我明白你的意思是「setter」:對象屬性的set部分。當你提到「......被認爲是一種不好的做法...」,我希望你能告訴我們誰是誰。有人告訴我,軟件行業的最大成本是維護的一部分,因此維護團隊儘可能瞭解這一點非常重要,因此除了編程語言之外,應該使用本地語言。說實話,我明白這個說法。 –

+0

這只是一個一般的建議,幾乎所有的主流庫和框架(例如.NET和Java)都遵循這個建議。這不是一個法律:)無論如何,如果你的原始問題已經解決,請記住接受答案並投票。 – mm8

+0

那麼從英語國家有一個建議說英語的時候,我並不會感到驚訝。除了那個重要的問題,你的建議是將業務規則/計算放到模型層。正如我理解MVVM這些東西屬於ViewModel層,對吧? –