2009-05-28 12 views
11

मेरे विचार में, मेरे पास एक बटन है।मैं DelegateCommand के साथ व्यू टू व्यू मॉडेल से जानकारी कैसे पास करूं?

जब उपयोगकर्ता इस बटन पर क्लिक करता है, तो मैं ViewModel डेटाबेस में टेक्स्टब्लॉक के संदर्भ को सहेजना चाहता हूं।

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

लेकिन, मेरा ViewModel, "सहेजें()" में मेरे 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 का उपयोग करके आप एक CommandParameter के माध्यम से प्रतिनिधियों को जानकारी भेजने के कर सकते हैं:

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

अद्यतन

this article को देखते हुए, यह प्रतीत होता है, जिसमें एक पैरामीटर स्वीकार करता है DelegateCommand के जेनेरिक वर्जन है कि वहाँ एक समान तरीका आप अपने SaveCommand को DelegateCommand<MyObject> पर बदलने का प्रयास करना चाहेंगे और अपनी सेव और कैनसेव विधियों को बदल सकते हैं ताकि वे MyObject पैरामीटर ले सकें।

+2

मैंने वास्तव में टेक्स्टबॉक्स को एक व्यूमोडेल प्रॉपर्टी (INotifyPropertyChanged) पर बाध्य करके मेरी समस्या हल की है, निश्चित रूप से सेव() कमांड का उपयोग करने के लिए मूल्य है, लेकिन आपके सुझाव बहुत रोचक हैं, उन्हें जांच लेंगे। –

+0

एक विशिष्ट (और उचित रूप से आम) उपयोग केस है जहां मैट का समाधान निश्चित रूप से एक अलग बाध्य मान तक पहुंचने पर जीतता है: 'आइटम नियंत्रण' के भीतर से निष्पादित आदेश। यहां, एक बटन, कहें, 'ListView' में' 'DataContext' को पैरामीटर के रूप में उपयोग कर सकता है और जिस आइटम पर बटन क्लिक किया गया था उसे कमांड के साथ पास किया गया है। यह काम करना मुश्किल है कि किस बटन ने बटन को अन्यथा क्लिक किया था। –

+1

ध्यान दें कि सामान्य 'प्रतिनिधिमंडल ' का एक महत्वपूर्ण प्रतिबंध है (जिसे रन टाइम तक नहीं उठाया जाता है - संकलक शिकायत नहीं करेगा): आप पैरामीटर के रूप में मान प्रकार का उपयोग नहीं कर सकते हैं। आधिकारिक सलाह एक शून्य मूल्य प्रकार (जिसे अनुमति है) का उपयोग करना है और उपयोग से पहले जांचें कि इसमें एक मान है (https://msdn.microsoft.com/en-us/library/gg431410%28v=pandp.50%29 .aspx - "टिप्पणियां" अनुभाग देखें)। –

9

अपने वीएम में:

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

public ICommand SaveCmd{ get{ return _saveCmd } } 

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

में आप देखें, मैट उदाहरण की तरह CommandParameter का उपयोग करें।

+0

एक पूर्ण उत्तर नहीं है, लेकिन इसने मुझे कमांड पैरामीटर का उपयोग करने और DelegateCommand के लिए एक प्रकार निर्दिष्ट करने के लिए सही दिशा में इंगित किया। धन्यवाद – vdidxho

5

आप बटन कमांड के माध्यम से डेटा पास करने के बारे में पूछ रहे हैं।

<!-- 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

यह वही है जो मैं आम तौर पर करता हूं, क्योंकि टेक्स्टबॉक्स मान पहले से ही व्यूमोडेल में किसी संपत्ति से जुड़ा हुआ है। आदेश के पैरामीटर के रूप में इसे पास करने की कोई आवश्यकता नहीं है। –

+0

यदि आप केवल एक उद्देश्य के लिए टेक्स्ट का उपयोग करते हैं तो इसे पैरामीटर के रूप में पास करने के लिए यह अधिक समझ (कोड-पठनीयता) बनाता है। उदाहरण के लिए अपने वीएम में सक्रियण कुंजी गुजरना। –

12

यहाँ सुरुचिपूर्ण तरीका है:

क्या आप वास्तव में चाहते हैं, मुझे लगता है, बाँध अपने ViewModel में एक सार्वजनिक संपत्ति करने के लिए अपने पाठ बॉक्स का पाठ करने के लिए है।

अपने पाठ बॉक्स के लिए कोई नाम दें, तो बटन में CommandParameter बाध्य करने के लिए यह पाठ संपत्ति है:

<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)' का संदर्भ नहीं दे सकता है।

संबंधित मुद्दे