WPF बाइंडिंग का उपयोग करके दो कमांड पैरामीटर पास करना


155

मेरे पास एक कमांड है जिसे मैं अपने XAML फ़ाइल से निम्न मानक सिंटैक्स का उपयोग करके निष्पादित कर रहा हूं:

<Button Content="Zoom" Command="{Binding MyViewModel.ZoomCommand}"/>

यह तब तक ठीक काम करता है जब तक मुझे एहसास नहीं हो जाता है कि मुझे इस ऑपरेशन को उपयोगकर्ताओं द्वारा अपेक्षित तरीके से पूरा करने के लिए (कैनवास की चौड़ाई और ऊंचाई विशेष रूप से) देखने के लिए सूचना के दो टुकड़ों की आवश्यकता है।

ऐसा लगता है कि मेरे आदेश के लिए एक तर्क के रूप में एक सरणी पास करना संभव है, लेकिन मुझे कमांडपैरमीटर में अपने दो कैनवास गुणों के लिए बाध्यकारी निर्दिष्ट करने का एक तरीका नहीं है:

<Button Content="Zoom" 
        Command="{Binding MyViewModel.ZoomCommand" 
        CommandParameter="{Binding ElementName=MyCanvas, Path=Width}"/>

मैं अपने आदेश में चौड़ाई और ऊँचाई दोनों कैसे पास करूँ? ऐसा नहीं लगता है कि XAML से कमांड का उपयोग करना संभव है और मुझे अपने जूम विधि को पास करने के लिए इस जानकारी को प्राप्त करने के लिए अपने कोडबेहैंड में एक क्लिक हैंडलर को वायर करने की आवश्यकता है।


[ stackoverflow.com/questions/58114752/… उपरोक्त समाधान। मेरे पास एक ही मुद्दा था।)
user1482689

जवाबों:


240

सबसे पहले, यदि आप MVVM कर रहे हैं, तो आपके पास आम तौर पर दृश्य से बंधे हुए अलग-अलग गुणों के माध्यम से यह जानकारी आपके वीएम के पास उपलब्ध होगी। यह आपको अपने कमांड में किसी भी पैरामीटर को पास करने से बचाता है।

हालाँकि, आप मापदंडों को बनाने के लिए एक बहु-बाँध और एक कनवर्टर का उपयोग कर सकते हैं:

<Button Content="Zoom" Command="{Binding MyViewModel.ZoomCommand">
    <Button.CommandParameter>
        <MultiBinding Converter="{StaticResource YourConverter}">
             <Binding Path="Width" ElementName="MyCanvas"/>
             <Binding Path="Height" ElementName="MyCanvas"/>
        </MultiBinding>
    </Button.CommandParameter>
</Button>

आपके कनवर्टर में:

public class YourConverter : IMultiValueConverter
{
    public object Convert(object[] values, ...)
    {
        return values.Clone();
    }

    ...
}

फिर, आपके कमांड निष्पादन तर्क में:

public void OnExecute(object parameter)
{
    var values = (object[])parameter;
    var width = (double)values[0];
    var height = (double)values[1];
}

1
धन्यवाद केंट - वह वही था जिसकी मुझे तलाश थी। मैं आपके पहले दृष्टिकोण को बेहतर तरीके से पसंद करता हूं ताकि वीएम को एक बंधन के माध्यम से दृश्य की "स्थिति" पता चले, मेरे बिना सभी मापदंडों को पारित करने के लिए, लेकिन मैं अभी भी इसका परीक्षण कर सकता हूं। मुझे यकीन नहीं है कि यहां मेरे लिए काम करने जा रहा है, क्योंकि मुझे कैनवास को जितना संभव हो उतना बड़ा बनाने और इस मान को वीएम को पास करने की आवश्यकता है। अगर मैं इसे बांधता हूं, तो क्या मुझे वीएम में चौड़ाई निर्धारित नहीं करनी होगी? किस मामले में, VM देखने के लिए बाध्य है?

@ जेसन: आप इसे किसी भी तरह से कर सकते हैं। अर्थात्, दृश्य मॉडल में दृश्य पुश परिवर्तन वापस आ गए हैं, या दृश्य मॉडल पुश दृश्य में परिवर्तन हैं। एक TwoWay बाइंडिंग आपके लिए उपलब्ध विकल्प के रूप में होगा।
केंट बूगार्ट

मेरे कार्यक्रम में OnExecute पद्धति पैरामीटर शून्य मानों के साथ एक सरणी है लेकिन, कनवर्टर में मान अपेक्षित हैं
एलेक्स डेविड

2
मुझे लगता है कि पैरामीटर OnExecute विधि में अशक्त है, भी YourConverter.Convert () बटन क्लिक करने के बाद नहीं बुलाया गया था। क्यों?
सबमरीनएक्स

3
यह काम नहीं करता है, जब एक बटन दबाया जाता है, पैरामीटर अशक्त होते हैं
adminSoftDK

38

चुने हुए समाधान के कनवर्टर में, आपको मान जोड़ना चाहिए। क्लिक करें () अन्यथा कमांड अंत में पैरामीटर शून्य हैं

public class YourConverter : IMultiValueConverter
{
    public object Convert(object[] values, ...)
    {
        return values.Clone();
    }

    ...
}

6
नमस्ते, क्लोन () के साथ यह अतिरिक्त काम करता है :) क्या आप कृपया समझा सकते हैं, इससे क्या फर्क पड़ता है। मुझे समझ में नहीं आता कि यह काम करने के लिए क्लोन () की आवश्यकता क्यों है? धन्यवाद।
adminSoftDK

मैं गलत हो सकता हूं, लेकिन यह (रेखा 1267) ऐसा लगता है कि यह मेरे लिए कारण हो सकता है: संदर्भ
स्रोत ।microsoft.com

14

कनवर्टर में Tuple का प्रयोग करें, और OnExecute में, पैरामीटर ऑब्जेक्ट को Tuple में वापस डालें।

public class YourConverter : IMultiValueConverter 
{      
    public object Convert(object[] values, ...)     
    {   
        Tuple<string, string> tuple = new Tuple<string, string>(
            (string)values[0], (string)values[1]);
        return (object)tuple;
    }      
} 

// ...

public void OnExecute(object parameter) 
{
    var param = (Tuple<string, string>) parameter;
}

5

यदि आपके मूल्य स्थिर हैं, तो आप उपयोग कर सकते हैं x:Array:

<Button Command="{Binding MyCommand}">10
  <Button.CommandParameter>
    <x:Array Type="system:Object">
       <system:String>Y</system:String>
       <system:Double>10</system:Double>
    </x:Array>
  </Button.CommandParameter>
</Button>

" यदि आपके मूल्य स्थिर हैं ": एक स्थिर संसाधन क्या है? उदाहरण के लिए प्रश्न में कैनवस चौड़ाई और ऊँचाई का उल्लेख है। ये मूल्य स्थिर नहीं हैं, लेकिन क्या वे स्थिर हैं? इस मामले में XAML क्या होगा?
मिनट

2
मुझे "स्थिर" के बजाय "स्थिर" लिखना चाहिए था। एक स्थिर संसाधन एक ऐसा संसाधन है जो निष्पादन के दौरान नहीं बदलता है। यदि आप SystemColorsउदाहरण के लिए उपयोग करते हैं, तो आपको DynamicResourceइसके बजाय उपयोग करना चाहिए StaticResourceक्योंकि उपयोगकर्ता निष्पादन के दौरान नियंत्रण कक्ष के माध्यम से सिस्टम रंग बदल सकता है। कैनवस Widthऔर Heightसंसाधन नहीं हैं और स्थिर नहीं हैं। वहाँ उदाहरण गुण से विरासत में मिला है FrameworkElement
मैक्सेंस

2

कनवर्टर में टपल के उपयोग के बारे में, 'स्ट्रिंग' के बजाय 'ऑब्जेक्ट' का उपयोग करना बेहतर होगा, ताकि यह 'स्ट्रिंग' ऑब्जेक्ट की सीमा के बिना सभी प्रकार की वस्तुओं के लिए काम करे।

public class YourConverter : IMultiValueConverter 
{      
    public object Convert(object[] values, ...)     
    {   
        Tuple<object, object> tuple = new Tuple<object, object>(values[0], values[1]);
        return tuple;
    }      
} 

तब कमांड में निष्पादन तर्क इस तरह हो सकता है

public void OnExecute(object parameter) 
{
    var param = (Tuple<object, object>) parameter;

    // e.g. for two TextBox object
    var txtZip = (System.Windows.Controls.TextBox)param.Item1;
    var txtCity = (System.Windows.Controls.TextBox)param.Item2;
}

और पैरामीटर के साथ मल्टी-बाइंड पैरामीटर बनाने के लिए (दो टेक्स्टबॉक्स ऑब्जेक्ट्स के साथ)

<Button Content="Zip/City paste" Command="{Binding PasteClick}" >
    <Button.CommandParameter>
        <MultiBinding Converter="{StaticResource YourConvert}">
            <Binding ElementName="txtZip"/>
            <Binding ElementName="txtCity"/>
        </MultiBinding>
    </Button.CommandParameter>
</Button>

मुझे यह पसंद है क्योंकि यह अधिक स्पष्ट है कि कनवर्टर कितने मापदंडों का समर्थन करता है। सिर्फ दो मापदंडों के लिए अच्छा है! (इसके अलावा आपने एक्सएएमएल और कमांड को फुल कवरेज के लिए कमांड निष्पादित किया)
कालेब डब्ल्यू।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.