2009-05-28 71 views
11

在我的視圖中,我有一個按鈕。如何使用DelegateCommand將View中的信息傳遞給ViewModel?

當用戶點擊這個按鈕時,我想讓ViewModel將TextBlock的上下文保存在數據庫中。

<StackPanel HorizontalAlignment="Left" VerticalAlignment="Top"> 
    <TextBlock Text="{Binding FirstName}"/> 
    <TextBox Text="Save this text to the database."/> 
    <Button Content="Save" Command="{Binding SaveCommand}"/> 
</StackPanel> 

但是,我在我的視圖模型,「保存()」 DelegateCommand方法不傳遞任何參數,所以如何從在這一點上的看法得到的數據?

#region DelegateCommand: Save 
private DelegateCommand saveCommand; 

public ICommand SaveCommand 
{ 
    get 
    { 
     if (saveCommand == null) 
     { 
      saveCommand = new DelegateCommand(Save, CanSave); 
     } 
     return saveCommand; 
    } 
} 

private void Save() 
{ 
    TextBox textBox = ......how do I get the value of the view's textbox from here?.... 
} 

private bool CanSave() 
{ 
    return true; 
} 
#endregion 

回答

18

結賬this MSDN article by Josh Smith。在其中,他展示了DelegateCommand的一個變體,他稱之爲RelayCommand,並且RelayCommand上的Execute和CanExecute委託接受一個類型爲object的參數。

使用RelayCommand您可以通過CommandParameter信息傳遞給代表:

<Button Command="{Binding SaveCommand}" 
     CommandParameter="{Binding SelectedItem,Element=listBox1}" /> 

更新

this article來看,它似乎有DelegateCommand的一個通用版本,它接受一個參數類似的方式。您可能想嘗試將SaveCommand更改爲DelegateCommand<MyObject>,並更改Save和CanSave方法,以便它們取得MyObject參數。

+2

我實際上通過將TextBox綁定到ViewModel屬性(INotifyPropertyChanged)來解決我的問題,當然,Save()命令可以訪問哪個值,但是您的建議非常有趣,它將檢查它們。 – 2009-05-28 11:28:01

+0

Matt的解決方案肯定贏得了訪問單獨的綁定值的具體(合理常見)用例:在ItemsControl中執行的命令。在這裏,一個按鈕,比如'ListView'中的按鈕可以使用它的'DataContext'作爲參數,並且按鈕被點擊的項目和命令一起被傳遞。很難計算出許多項目中的哪一個按鈕被點擊。 – 2015-05-13 10:19:30

+1

請注意,通用的'DelegateCommand '有一個重要的限制(在運行時沒有被選中 - 編譯器不會抱怨):不能使用值類型作爲參數。官方建議是使用可以爲空的值類型(允許),並在使用之前檢查它是否包含值(https://msdn.microsoft.com/en-us/library/gg431410%28v=pandp.50%29 .aspx - 請參閱「備註」部分)。 – 2015-05-13 10:23:43

9

在你的虛擬機:

private DelegateCommand<string> _saveCmd = new DelegateCommand<string>(Save); 

public ICommand SaveCmd{ get{ return _saveCmd } } 

public void Save(string s) {...} 

在您查看,使用CommandParameter像馬特的例子。

+0

不是一個完整的答案,但是這指出我正確使用CommandParameter併爲DelegateCommand指定一個類型。謝謝 – vdidxho 2018-03-05 23:38:24

5

你在問關於通過按鈕Command傳遞數據。

你真正想要的是什麼,我想,是綁定您的文本框的文本在您的視圖模型一個公共財產

<!-- View: TextBox's text is bound to the FirstName property in your ViewModel --> 
<TextBox Text="{Binding Path=FirstName}" /> 
<Button Command="{Binding SaveCommand}"/> 

<!-- ViewModel: Expose a property for the TextBox to bind to --> 
public string FirstName{ get; set; } 
... 
private void Save() 
{ 
    //textBox's text is bound to --> this.FirstName; 
} 
+0

這是我通常做的事情,因爲TextBox的值已經綁定到viewmodel中的一個屬性。沒有必要將它作爲參數傳遞給命令。 – 2010-04-20 14:12:19

+0

如果僅將文本用於一個目的,則它更有意義(代碼可讀性)將其作爲參數傳遞。例如將激活密鑰傳遞給您的虛擬機。 – 2017-09-25 10:53:25

12

這裏是優雅的方式。

提供一個名稱的文本框,然後在按鈕綁定CommandParameter它的Text屬性:

<StackPanel HorizontalAlignment="Left" VerticalAlignment="Top"> 
    <TextBlock Text="{Binding FirstName}"/> 
    <TextBox x:Name="ParameterText" Text="Save this text to the database."/> 
    <Button Content="Save" Command="{Binding SaveCommand}" 
      CommandParameter="{Binding Text, ElementName=ParameterText}"/> 
</StackPanel> 
1

我不能作出評論,我猜。我正在迴應卡洛斯的建議,因爲我試了一下。雖然這是一個好主意,但DelegateCommand需要以某種方式進行修改,否則會出現此錯誤: 字段初始值設定項無法引用非靜態字段,方法或屬性'MyViewModel.Save(string)'。

相關問題